简体   繁体   English

单击时放大子图(带有 inset_axes 图)

[英]Zoom in on subplot (with inset_axes plot) on click

So I have followed the approach from this thread:所以我遵循了这个线程的方法:

How can I plot the same figure standalone and in a subplot in Matplotlib? 我怎样才能在 plot 中独立和在 Matplotlib 的子图中使用相同的图?

And it actually works quite well, as seen in his example.正如他的示例所示,它实际上工作得很好。 However, one issue is that I have inset_axes plots in my plots.但是,一个问题是我的图中有inset_axes图。 So when it zooms, all the inset plots remains, and actually overlaps the enlarged plot.因此,当它放大时,所有插图都保留下来,实际上与放大的 plot 重叠。

I am however not sure how to remove them, and maybe even also zoom in on the inset plot that are together with the subplot being clicked.但是,我不确定如何删除它们,甚至可能还放大与单击的子图一起的插图 plot。

So from the thread I have just used this class for the zoom approach:所以从线程我刚刚使用这个 class 进行缩放方法:

class ZoomingSubplots(object):
    def __init__(self, *args, **kwargs):
        """All parameters passed on to 'subplots`."""
        self.fig, self.axes = plt.subplots(*args, **kwargs)
        self._zoomed = False
        self.fig.canvas.mpl_connect('button_press_event', self.on_click)
        self.fig.subplots_adjust(hspace=0.3)

    def zoom(self, selected_ax):
        for ax in self.axes.flat:
            ax.set_visible(False)
        self._original_size = selected_ax.get_position()
        selected_ax.set_position([0.125, 0.1, 0.775, 0.8])
        selected_ax.set_visible(True)
        self._zoomed = True

    def unzoom(self, selected_ax):
        selected_ax.set_position(self._original_size)
        for ax in self.axes.flat:
            ax.set_visible(True)
        self._zoomed = False

    def on_click(self, event):
        if event.inaxes is None:
            return
        if self._zoomed:
            self.unzoom(event.inaxes)
        else:
            self.zoom(event.inaxes)
        self.fig.canvas.draw()

And then when I plot I use this:然后当我 plot 我使用这个:

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

__name__ = '__main__':
    subplots = ZoomingSubplots(2, 2)

    for ax in subplots.axes.flat:
        ax.plot(x, y)
        axins = inset_axes(ax, width=1.3, height=0.9, loc=2)
        axins.plot(x2, y2)

    plt.show()

But as stated, with this the inset plot for all subplots will remain in their position and overlap with the enlarged plot.但如上所述,所有子图的插图 plot 将保留在其 position 中,并与放大的 plot 重叠。 How can I change this, so that they don't intervene, and maybe even the inset_plot for the subplot remains and is also enlarged?我怎样才能改变它,这样他们就不会干预,甚至可能子图的 inset_plot 仍然存在并且也被放大了?

I couldn't find a way to change the position of the inset_axes , probably because their position and size are locked-in to their parent axes.我找不到更改 inset_axes 的inset_axes的方法,可能是因为它们的 position 和大小被锁定到它们的父轴。

In the meantime, here is a new class that creates the inset_axes automatically, and hides/shows the relevant inset_axes when clicking on one of the base axes.同时,这是一个新的 class,它会自动创建 inset_axes,并在单击其中一个基轴时隐藏/显示相关的 inset_axes。

class ZoomingSubplotsWithInset(ZoomingSubplots):
    def __init__(self, *args, inset_width=1.3, inset_height=0.9, inset_loc=2, **kwargs):
        super(ZoomingSubplotsWithInset, self).__init__(*args, **kwargs)
        self.inset_axes = []
        for ax in self.axes.flat:
            axins = inset_axes(ax, width=inset_width, height=inset_height, loc=inset_loc)
            self.inset_axes.append(axins)
        self.inset_axes = np.array(self.inset_axes)

    def on_click(self, event):
        if event.inaxes in self.axes.flat:
            super(ZoomingSubplotsWithInset, self).on_click(event)

    def zoom(self, selected_ax):
        for ax in self.inset_axes.flat:
            ax.set_visible(False)
        super(ZoomingSubplotsWithInset, self).zoom(selected_ax)
        # restore visibility of the inset_axes corresponding to the zoomed axes
        _, _, i = selected_ax.get_geometry()
        self.inset_axes[i-1].set_visible(True)

    def unzoom(self, selected_ax):
        for ax in self.inset_axes.flat:
            ax.set_visible(True)
        super(ZoomingSubplotsWithInset, self).unzoom(selected_ax)


if __name__ == '__main__':
    N = 10

    subplots = ZoomingSubplotsWithInset(2, 2)

    for ax, axins in zip(subplots.axes.flat, subplots.inset_axes.flat):
        x, y = np.random.random(size=(2, N))
        x2, y2 = np.random.random(size=(2, N))
        ax.plot(x, y)
        axins.plot(x2, y2)

    plt.show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM