2

私は 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) 関数を使用していましたが、見栄えがよくありません。

ありがとう !

4

1 に答える 1

3

私は最近、同じ問題を抱えており、ソリューションのインスピレーションは次のソリューションから得られました。

  1. Matplotlib: 3D 散布図に注釈を付ける
  2. matplotlib の 1 つのテキストで複数の点に注釈を付ける

解決策は、「ラベル」の配列の作成に基づいており、各「ラベル」の位置は 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()
于 2013-10-10T10:32:27.287 に答える