Skip to main content
 首页 » 编程设计

Python 绘制带注释的 3D 点

2025年05月04日7mate10pro

我有一个 3D 图形,我想用坐标对其进行注释。但是,注释会重叠。我希望它们不要重叠。

我的问题是-

  • 注释重叠
  • 在传说中,我不明白为什么会有三角形和圆形这两个符号。不应该只有一个吗?

仅供引用,我的数据集仅限于以下几点。因此,即使任何其他参数是硬编码的,我也无所谓。

这是我的代码。

from mpl_toolkits.mplot3d import Axes3D 
from mpl_toolkits.mplot3d import proj3d 
import matplotlib.pyplot as plt 
import pylab     
 
xData1=[ 24500.,   2980.,   2980.,  13740.] 
xData2=[  8360.,   8360.,  24500.,   5670.,   2980.,   2980.,  11050.,  13740.] 
yData1=[ 179.,  244.,  242.,  181.] 
yData2=[ 132.,  149.,  116.,  163.,  247.,  228.,  116.,  116.] 
zData1=[  1.,  44.,  86.,  44.] 
zData2=[ 86.,  22.,   1.,  86.,  43.,  86.,  86.,  22.] 
 
fig = plt.figure() 
ax = fig.gca(projection='3d') 
 
ax.plot(xData1, yData1, zData1, '^', c='r', label='cfg1') 
ax.plot(xData2, yData2, zData2, 'o', c='b', label='cfg2') 
 
 
for i in range(len(xData1)): 
    text='['+str(int(xData1[i]))+','+str(int(yData1[i]))+','+str(int(zData1[i]))+']'     
    x2, y2, _ = proj3d.proj_transform(xData1[i],yData1[i],zData1[i], ax.get_proj())     
    label = pylab.annotate(text, 
    xycoords='data',  
    xy = (x2, y2), xytext = (60, 20), 
    textcoords = 'offset points', ha = 'right', va = 'bottom', 
    bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5), 
    arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 
 
 
for i in range(len(xData2)): 
    text='['+str(int(xData2[i]))+','+str(int(yData2[i]))+','+str(int(zData2[i]))+']'     
    x2, y2, _ = proj3d.proj_transform(xData2[i],yData2[i],zData2[i], ax.get_proj())     
    label = pylab.annotate(text, 
    xycoords='data',  
    xy = (x2, y2), xytext = (20, 20), 
    textcoords = 'offset points', ha = 'right', va = 'bottom', 
    bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5), 
    arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 
 
ax.set_xlabel('X-Data') 
ax.set_ylabel('Y-Data') 
ax.set_zlabel('Z-Data') 
 
ax.legend(ncol=3) 
plt.show() 

请您参考如下方法:

这两个问题都是相对简单的答案。我先从第二个开始:图例中有两个符号,因为您在定义图例时没有指定数字,默认值为两个。要更正,只需更改:

    ax.legend(ncol=3, numpoints=1) 

其中 numpoints 更改图例中的点数 - 现在设置为 1。

第一个问题的答案涉及操纵文本注释的位置,更具体地说是 xytext,它给出了文本的坐标。用下面的替换你的第二个 for 循环应该摆脱你的重叠文本,并给你一个很好的例子,说明如何为任何其他难看的位置问题更改注释框的位置:

    for i in range(len(xData2)): 
    text='['+str(int(xData2[i]))+','+str(int(yData2[i]))+','+str(int(zData2[i]))+']' 
    x2, y2, _ = proj3d.proj_transform(xData2[i],yData2[i],zData2[i], ax.get_proj()) 
    if i==4: 
        label = pylab.annotate(text, 
                       xycoords='data', 
                       xy = (x2, y2), xytext = (0, -50), 
                       textcoords = 'offset points', ha = 'right', va = 'bottom', 
                       bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5), 
                       arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 
    elif i==6: 
        label = pylab.annotate(text, 
                           xycoords='data', 
                           xy = (x2, y2), xytext = (-40, 0), 
                           textcoords = 'offset points', ha = 'right', va = 'bottom', 
                           bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5), 
                           arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0')) 
    else: 
        label = pylab.annotate(text, 
                           xycoords='data', 
                           xy = (x2, y2), xytext = (-20, 10), 
                           textcoords = 'offset points', ha = 'right', va = 'bottom', 
                           bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5), 
                           arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))