2012-10-14 66 views
2

我有一個3D圖形,我想用座標對它們進行註釋。但是,註釋會重疊。我希望他們不要重疊。Python繪製帶有註釋的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

這兩個問題都是比較簡單的答案。我將從第二個開始:圖例中有兩個符號,因爲在定義圖例時沒有指定數字,默認值爲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')) 
+0

這是偉大的! :) – Raj