Python使用注释绘制3D点

时间:2012-10-14 07:43:41

标签: python matplotlib

我有一张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()

1 个答案:

答案 0 :(得分:1)

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

    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'))