我正在尝试创建一个包含 4 个子图的交互式图。理想情况下,点击其中一个子图会导致其余的相同(镜像点击)。

到目前为止,我只能单独单击它们并使用 mpldatacursor 获取特定数据。

在此图中,单击事件将导致所有 4 个图形显示 x、y、z 的相应数据:

import matplotlib.pyplot as plt
import numpy as np
from mpldatacursor import datacursor
fig, ((ax1,ax2),(ax3,ax4)) = plt.subplots(nrows=2,
ncols=2,sharex=True, sharey=True, figsize=(60, 20))
plt.subplots_adjust(wspace=0.08, hspace=0.08)
ax1.imshow(np.random.random((10,10)))
ax2.imshow(np.random.random((10,10)))
ax3.imshow(np.random.random((10,10)))
ax4.imshow(np.random.random((10,10)))
datacursor(display='multiple',formatter='x:{x:.0f}\n  y:{y:.0f}\n z:
{z}'.format,draggable=True,fontsize=10)
plt.show()

最佳答案

您使用的 mpldatacursor 包无法一次注释多个图像。但是您可以编写自己的“数据光标”,用于注释图像。

这可能如下所示。

import matplotlib.pyplot as plt
import numpy as np

fig, ((ax1,ax2),(ax3,ax4)) = plt.subplots(nrows=2,
                                          ncols=2,sharex=True, sharey=True)
plt.subplots_adjust(wspace=0.08, hspace=0.08)
ax1.imshow(np.random.random((10,10)))
ax2.imshow(np.random.random((10,10)))
ax3.imshow(np.random.random((10,10)))
ax4.imshow(np.random.random((10,10)))

class ImageCursor():
    def __init__(self, axes, fmt='x:{x}\ny:{y}\nz:{z:.3f}'):
        self.fmt = fmt
        self.axes = axes
        self.fig = self.axes[0].figure
        self.ims = []
        self.annot = []
        for ax in self.axes:
            ax.images[0].set_picker(True)
            self.ims.append(ax.images[0])
            annot = ax.annotate("",xy=(0,0), xytext=(-30,30),
                                textcoords="offset points",
                                arrowprops=dict(arrowstyle="->",color="w",
                                                connectionstyle="arc3"),
                                va="bottom", ha="left", fontsize=10,
                                bbox=dict(boxstyle="round", fc="w"),)
            annot.set_visible(False)
            self.annot.append(annot)
        self.cid = self.fig.canvas.mpl_connect("pick_event", self.pick)

    def pick(self,event):
        e = event.mouseevent
        if e.inaxes:
            x,y = int(np.round(e.xdata)), int(np.round(e.ydata))
            self.annotate((x,y))
    def annotate(self,X):
        for annot, im in zip(self.annot, self.ims):
            z = im.get_array()[X[1],X[0]]
            annot.set_visible(True)
            annot.set_text(self.fmt.format(x=X[0],y=X[1],z=z))
            annot.xy = X
        self.fig.canvas.draw_idle()

ic = ImageCursor([ax1,ax2,ax3,ax4])

plt.show()

python - 在多个子图上反射(reflect)事件处理-LMLPHP

关于python - 在多个子图上反射(reflect)事件处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48423236/

10-12 20:19