简体   繁体   English

Matplotlib:从多个子图中抓取单个子图

[英]Matplotlib: Grab Single Subplot from Multiple Subplots

I have an application where I have one figure with nine line plot sub-plots (3x3) and I want to let the user select one of the charts and have a small wx Python application open up to allow editing and zooming on the specified sub-plot.我有一个应用程序,我有一个带有九个线图子图(3x3)的图形,我想让用户选择其中一个图表并打开一个小的 wx Python 应用程序以允许编辑和缩放指定的子图阴谋。

Is it possible to grab all the information from the selected sub-plot, ie axis labels, axis formatting, lines, tick sizes, tick labels, etc and plot it quickly on the canvas of the wx application?是否可以从选定的子图中获取所有信息,即轴标签、轴格式、线条、刻度大小、刻度标签等,并在 wx 应用程序的画布上快速绘制?

My current solution is too long and bulky, as I just re-do the plot that the user selects.我当前的解决方案太长太笨重,因为我只是重新绘制用户选择的图。 I was thinking something like this, but it doesn't work quite right.我在想这样的事情,但它并不完全正确。

#ax is a dictionary containing each instance of the axis sub-plot
selected_ax = ax[6]
wx_fig = plt.figure(**kwargs)
ax = wx_fig.add_subplots(111)
ax = selected_ax
plt.show()

Is there a way to save the properties from getp(ax) to a variable and use selected properties of that variable with setp(ax) to construct a new chart?有没有办法将 getp(ax) 中的属性保存到变量,并使用 setp(ax) 使用该变量的选定属性来构建新图表? I feel this data must be accessible somehow, given how quickly it prints when you call getp(ax), but I can't even get the following code to work on an axis with two y-axes:考虑到调用 getp(ax) 时它的打印速度,我觉得必须以某种方式访问​​这些数据,但我什至无法让以下代码在具有两个 y 轴的轴上工作:

label = ax1.yaxis.get_label()
ax2.yaxis.set_label(label)

I have a feeling this isn't possible, but I thought I would ask anyways.我有一种感觉这是不可能的,但我想我还是会问。

Unfortunately, cloning an axis or sharing artists between multiple axes is difficult in matplotlib.不幸的是,在 matplotlib 中克隆一个轴或在多个轴之间共享艺术家很困难。 (Not completely impossible, but re-doing the plot will be simpler.) (并非完全不可能,但重新绘制情节会更简单。)

However, what about something like the following?但是,像下面这样的东西呢?

When you left-click on a subplot, it will occupy the entire figure, and when you right-click, you'll "zoom out" to show the rest of the subplots...当您左键单击一个子图时,它将占据整个图形,而当您右键单击时,您将“缩小”以显示其余的子图...

import matplotlib.pyplot as plt

def main():
    fig, axes = plt.subplots(nrows=2, ncols=2)
    for ax, color in zip(axes.flat, ['r', 'g', 'b', 'c']):
        ax.plot(range(10), color=color)
    fig.canvas.mpl_connect('button_press_event', on_click)
    plt.show()

def on_click(event):
    """Enlarge or restore the selected axis."""
    ax = event.inaxes
    if ax is None:
        # Occurs when a region not in an axis is clicked...
        return
    if event.button is 1:
        # On left click, zoom the selected axes
        ax._orig_position = ax.get_position()
        ax.set_position([0.1, 0.1, 0.85, 0.85])
        for axis in event.canvas.figure.axes:
            # Hide all the other axes...
            if axis is not ax:
                axis.set_visible(False)
    elif event.button is 3:
        # On right click, restore the axes
        try:
            ax.set_position(ax._orig_position)
            for axis in event.canvas.figure.axes:
                axis.set_visible(True)
        except AttributeError:
            # If we haven't zoomed, ignore...
            pass
    else:
        # No need to re-draw the canvas if it's not a left or right click
        return
    event.canvas.draw()

main()

Here's a working example that uses a class to store the subplot (axis) selected by the user (the zoomed axis).这是一个使用类来存储用户选择的子图(轴)(缩放轴)的工作示例。 From the stored axis, you can get all of the information you need.从存储的轴中,您可以获得所需的所有信息。 This demo, for example, shows how to zoom and restore the subplot (axis).例如,此演示展示了如何缩放和恢复子图(轴)。 You can then write other methods in the class that have access to the selected axis to fit your needs.然后,您可以在类中编写其他方法来访问所选轴以满足您的需要。

import matplotlib.pyplot as plt

class Demo(object):
    """ Demo class for interacting with matplotlib subplots """
    def __init__(self):
        """ Constructor for Demo """
        self.zoomed_axis = None
        self.orig_axis_pos = None

    def on_click(self, event):
        """ Zoom or restore the selected subplot (axis) """
        # Note: event_axis is the event in the *un-zoomed* figure
        event_axis = event.inaxes
        if event_axis is None: # Clicked outside of any subplot
            return
        if event.button == 1:  # Left mouse click in a subplot
            if not self.zoomed_axis:
                self.zoomed_axis = event_axis
                self.orig_axis_pos = event_axis.get_position()
                event_axis.set_position([0.1, 0.1, 0.85, 0.85])
                # Hide all other axes
                for axis in event.canvas.figure.axes:
                    if axis is not event_axis:
                        axis.set_visible(False)
            else:
                self.zoomed_axis.set_position(self.orig_axis_pos)
                # Restore all axes
                for axis in event.canvas.figure.axes:
                    axis.set_visible(True)
                self.zoomed_axis = None
                self.orig_axis_pos = None
        else:  # any other event in a subplot
            return
        event.canvas.draw()

    def run(self):
        """ Run the demo """
        fig, axes = plt.subplots(nrows=2, ncols=2)
        for axis, color in zip(axes.flat, ['r', 'g', 'b', 'c']):
            axis.plot(range(10), color=color)
        fig.canvas.mpl_connect('button_press_event', self.on_click)
        plt.show()

def main():
    """ Main driver """
    demo = Demo()
    demo.run()

if __name__ == "__main__":
    main()

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

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