Matplotlib:以图像作为注释的三维散点图

2024-05-02 20:13:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为tSNE嵌入的图像生成一个三维散点图,该数据集包含从0到9的数字。我还想用数据集中的图像注释这些点。在

在查阅了与此问题相关的现有资源后,我发现使用matplotlib.offsetbox如前所述here。在

{但也有一个注解}与一个3D}有关。有人知道如何用图像而不是文字来注释吗?在

谢谢!在


Tags: 数据图像herematplotlib数字资源文字tsne
1条回答
网友
1楼 · 发布于 2024-05-02 20:13:49

在matplotlib.offsetbox二维轴和三维坐标轴中的一个不对应于三维坐标轴的工作位置。在

要计算这些位置的坐标,可以参考How to transform 3d data units to display units with matplotlib?。然后可以使用这些显示坐标的反变换来获得叠加轴中的新坐标。在

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import proj3d
import matplotlib.pyplot as plt
from matplotlib import offsetbox
import numpy as np

xs = [1,1.5,2,2]
ys = [1,2,3,1]
zs = [0,1,2,0]

c = ["b","r","g","gold"]

fig = plt.figure()
ax = fig.add_subplot(111, projection=Axes3D.name)

ax.scatter(xs, ys, zs, c=c, marker="o")

# Create a dummy axes to place annotations to
ax2 = fig.add_subplot(111,frame_on=False) 
ax2.axis("off")
ax2.axis([0,1,0,1])


def proj(X, ax1, ax2):
    """ From a 3D point in axes ax1, 
        calculate position in 2D in ax2 """
    x,y,z = X
    x2, y2, _ = proj3d.proj_transform(x,y,z, ax1.get_proj())
    return ax2.transData.inverted().transform(ax1.transData.transform((x2, y2)))

def image(ax,arr,xy):
    """ Place an image (arr) as annotation at position xy """
    im = offsetbox.OffsetImage(arr, zoom=2)
    im.image.axes = ax
    ab = offsetbox.AnnotationBbox(im, xy, xybox=(-30., 30.),
                        xycoords='data', boxcoords="offset points",
                        pad=0.3, arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)


for s in zip(xs,ys,zs):
    x,y = proj(s, ax, ax2)
    image(ax2,np.random.rand(10,10),[x,y])

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()

enter image description here

上述解决方案是静态的。这意味着如果旋转或缩放绘图,注释将不再指向正确的位置。为了同步注释,可以连接到draw事件并检查限制或视角是否已更改,并相应地更新注释坐标。(2019年编辑:更新版本还要求将事件从顶部2D轴传递到底部3D轴;代码更新)

^{pr2}$

enter image description here

相关问题 更多 >