我对python和matplotlib很新,这个网站给了我很多帮助。但我找不到关于这个主题的完整答案。
我想使用matplotlib来注释3d图的点,所以经过一些研究后我发现了这个代码的和平: Matplotlib: Annotating a 3D scatter plot
import pylab
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import proj3d
fig = pylab.figure()
ax = fig.add_subplot(111, projection = '3d')
x = y = z = [1, 2, 3]
sc = ax.scatter(x,y,z)
# now try to get the display coordinates of the first point
x2, y2, _ = proj3d.proj_transform(1,1,1, ax.get_proj())
label = pylab.annotate(
"this",
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'))
def update_position(e):
x2, y2, _ = proj3d.proj_transform(1,1,1, ax.get_proj())
label.xy = x2,y2
label.update_positions(fig.canvas.renderer)
fig.canvas.draw()
fig.canvas.mpl_connect('button_release_event', update_position)
pylab.show()
但问题是,我设法只用这段代码更新最后一个标签,我试着在update_position(e)函数中做一些循环。但我肯定错过了一些东西。 到目前为止,我使用了Axes3D.text(x,y,z,s,zdir)函数,但它看起来并不是很好。
谢谢!
答案 0 :(得分:3)
我最近遇到了同样的问题,我的解决方案的灵感来自以下解决方案:
解决方案基于创建“标签”数组,然后在update_position()函数中更新每个“标签”的位置。
import numpy
from mpl_toolkits.mplot3d import proj3d
import matplotlib.pyplot as plt
import pylab
def update_position(e):
print "From update position"
#Transform co-ordinates to get new 2D projection
tX, tY, _ = proj3d.proj_transform(dataX, dataY, dataZ, ax.get_proj())
for i in range(len(dataX)):
label = labels[i]
label.xy = tX[i],tY[i]
label.update_positions(fig.canvas.renderer)
fig.canvas.draw()
return
#Input 3D Data
data = numpy.array([[3,6,2],[4,6,2],[2,9,2],[3,6,10],[6,1,5]])
#Separate into X, Y, Z for greater clarity
dataX = data[:,0]
dataY = data[:,1]
dataZ = data[:,2]
plt.close()
fig = plt.figure()
ax = fig.gca(projection='3d')
#3D scatter plot
ax.scatter(dataX, dataY, dataZ, marker = 'o', c='b')
#Transform co-ordinates to get initial 2D projection
tX, tY, _ = proj3d.proj_transform(dataX, dataY, dataZ, ax.get_proj())
#Array of labels
labels = []
#Loop through data points to initially annotate scatter plot
#and populate labels array
for i in range(len(dataX)):
text='['+str(int(dataX[i]))+','+str(int(dataY[i]))+','+str(int(dataZ[i]))+']'
label = ax.annotate(text,
xycoords='data',
xy = (tX[i], tY[i]), xytext = (-20, 20),
textcoords = 'offset points', ha = 'right', va = 'top', fontsize=6,
bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5),
arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))
labels.append(label)
#Positions are updated when mouse button is released after rotation.
fig.canvas.mpl_connect('button_release_event', update_position)
fig.show()