将相同的 Patch 实例添加到 matplotlib 中的多个子图中

问题描述:

我正在尝试将修补程序的相同实例添加到matplotlib中的多个轴.这是最小的例子:

I am trying to add the same instance of a patch to multiple axes in matplotlib. Here is minimal example:

import matplotlib.pyplot as mpl_plt
import matplotlib.patches as mpl_patches

fig, (axes_1, axes_2) = mpl_plt.subplots(2,1)
axes_1.axis([-5, 5, -5, 5])
axes_2.axis([-5, 5, -5, 5])

# Create ellipse and add it to the axes
ellipse = mpl_patches.Ellipse((1,1), 0.5, 0.8)
axes_1.add_patch(ellipse)
axes_2.add_patch(ellipse)

# Change the position of the ellipse
ellipse.center = (2,2)

# Show the plot
mpl_plt.show()

在这个例子中,椭圆没有出现在两个子图中.如果我将行 axes_2.add_patch(ellipse)注释掉,则椭圆出现在第一个子图中其移动位置(2,2).是否可以让椭圆出现在多个轴上并在两个轴上都反映它的变化?

In this example, the ellipse does not appear in either subplot. If I comment out the line axes_2.add_patch(ellipse), the ellipse appears in the first subplot at its moved location (2,2). Is it possible to have the ellipse appear in multiple axes and have changes to it reflected in both?

我的最终目标是能够将艺术家添加到不同的子图中,并对艺术家的变化进行全方位的反映.更好的方法是使用 mpl_toolkits 中的 zoomed_inset_axes 来显示插图的特写,其中补丁的更改将同时显示在主菜单中.情节和插图.

My end goal is being able to add artists to different subplots and have changes to the artists reflected in all axes. Even better would be to use zoomed_inset_axes from mpl_toolkits to have an inset plot that shows a close-up of a patch, where changes to the patch would be shown in both the main plot and the inset.

一种方法是使用类为艺术家设置所有自定义设置.我已经创建了一个示例类,每个属性都有一个默认值.如果你只是引用这个类的 art 函数,你每次都会得到一个新实例,但参数完全相同.请注意,我是如何将Ellipse1更改为xy =(2,2)的,并且这两个图都显示了这一点.我只是想增加一点技巧,所以您可以使用getattr调用多个修补程序类型.假设存在针对不同补丁的共享参数,或者?您可以像我想的那样使它变得复杂或简单.

One way to do this is using a class to set all your custom settings for the artist. I've made an example class that has a default value for each property. If you then just make a reference to the art function of this class you get a new instance every time but with the exact same parameters. Notice how I changed Ellipse1 to have xy=(2,2) and that showed up on both plots. Just for an added flair, I made it so you could potentially call more than one patch type using getattr. This is assuming there are shared arguments for different patches or? You can make this as complicated or simple as you like I suppose.

import matplotlib.pyplot as mpl_plt
import matplotlib.patches as mpl_patches

class artist_instance:
    def __init__(self,
                 xy=None,
                 width=None,
                 height=None,
                 type=None,
                 ):
        self.xy=xy if xy is not None else (1,1)
        self.width=width if width is not None else 0.5
        self.height=height if height is not None else 0.8
        self.type=type if type is not None else 'Ellipse'

    def art(self):
        return getattr(mpl_patches,self.type)(xy=self.xy,width=self.width,height=self.height)

Ellipse1=artist_instance(xy=(2,2))

fig, (axes_1, axes_2) = mpl_plt.subplots(2,1)
axes_1.axis([-5, 5, -5, 5])
axes_2.axis([-5, 5, -5, 5])

axes_1.add_patch(Ellipse1.art())
axes_2.add_patch(Ellipse1.art())
mpl_plt.show()

绘图结果