pyplot-复制轴内容并将其显示在新图中 [英] pyplot - copy an axes content and show it in a new figure

查看:129
本文介绍了pyplot-复制轴内容并将其显示在新图中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我说我有这段代码:

num_rows = 10
num_cols = 1
fig, axs = plt.subplots(num_rows, num_cols, sharex=True)
for i in xrange(num_rows):
     ax = axs[i]
     ax.plot(np.arange(10), np.arange(10)**i)
plt.show()

结果图形中的信息太多,现在我要选择1个轴并将其单独绘制在新图形中

the result figure has too much info and now I want to pick 1 of the axes and draw it alone in a new figure

我试图做这样的事情

def on_click(event):
    axes = event.inaxes.get_axes()
    fig2 = plt.figure(15)
    fig2.axes.append(axes)
    fig2.show()

fig.canvas.mpl_connect('button_press_event', on_click)

但是效果不佳.正确的方法是什么?搜索文档并抛出SE几乎没有任何有用的结果

but it didn't quite work. what would be the correct way to do it? searching through the docs and throw SE gave hardly any useful result

我不介意重新绘制选定的轴,但是我不确定如何知道选择了哪个轴,因此如果可以某种方式获得该信息,那对我来说是一个有效的解决方案

I don't mind redrawing the chosen axes, but I'm not sure how can I tell which of the axes was chosen so if that information is available somehow then it is a valid solution for me

编辑#2:

所以我设法做到了这样:

so I've managed to do something like this:

def on_click(event):
    fig2 = plt.figure(15)
    fig2.clf()
    for line in event.inaxes.axes.get_lines():
         xydata = line.get_xydata()
         plt.plot(xydata[:, 0], xydata[:, 1])
    fig2.show()

似乎正在运行"(所有其他信息都丢失了-标签,线条颜色,线条样式,线条宽度,xlim,ylim等) 但我觉得必须有更好的方法

which seems to be "working" (all the other information is lost - labels, lines colors, lines style, lines width, xlim, ylim, etc...) but I feel like there must be a nicer way to do it

谢谢

推荐答案

复制轴

此处的初始答案无效,我们将其保留以备将来参考,并了解为什么需要更复杂的方法.

#There are some pitfalls on the way with the initial approach. 
#Adding an `axes` to a figure can be done via `fig.add_axes(axes)`. However, at this point, 
#the axes' figure needs to be the figure the axes should be added to. 
#This may sound a bit like running in circles but we can actually set the axes' 
#figure as `axes.figure = fig2` and hence break out of this.

#One might then also position the axes in the new figure to take the usual dimensions. 
#For this a dummy axes can be added first, the axes can change its position to the position 
#of the dummy axes and then the dummy axes is removed again. In total, this would look as follows.

import matplotlib.pyplot as plt
import numpy as np

num_rows = 10
num_cols = 1
fig, axs = plt.subplots(num_rows, num_cols, sharex=True)
for i in xrange(num_rows):
     ax = axs[i]
     ax.plot(np.arange(10), np.arange(10)**i)
     
     
def on_click(event):
    axes = event.inaxes
    if not axes: return   
    fig2 = plt.figure()
    axes.figure=fig2
    fig2.axes.append(axes)
    fig2.add_axes(axes)
    
    dummy = fig2.add_subplot(111)
    axes.set_position(dummy.get_position())
    dummy.remove()
    fig2.show()

fig.canvas.mpl_connect('button_press_event', on_click)


plt.show()

#So far so good, however, be aware that now after a click the axes is somehow 
#residing in both figures, which can cause all sorts of problems, e.g. if you
# want to resize or save the initial figure.

相反,以下方法将起作用:

问题是无法复制轴(即使deepcopy也会失败).因此,要获取轴的真实副本,您可能需要使用pickle.以下将起作用.它会腌制完整的图形,并删除要显示的一个轴以外的所有轴.

The problem is that axes cannot be copied (even deepcopy will fail). Hence to obtain a true copy of an axes, you may need to use pickle. The following will work. It pickles the complete figure and removes all but the one axes to show.

import matplotlib.pyplot as plt
import numpy as np
import pickle
import io

num_rows = 10
num_cols = 1
fig, axs = plt.subplots(num_rows, num_cols, sharex=True)
for i in range(num_rows):
     ax = axs[i]
     ax.plot(np.arange(10), np.arange(10)**i)

def on_click(event):

    if not event.inaxes: return
    inx = list(fig.axes).index(event.inaxes)
    buf = io.BytesIO()
    pickle.dump(fig, buf)
    buf.seek(0)
    fig2 = pickle.load(buf) 

    for i, ax in enumerate(fig2.axes):
        if i != inx:
            fig2.delaxes(ax)
        else:
            axes=ax

    axes.change_geometry(1,1,1)
    fig2.show()

fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

重新创建图

上述替代方法当然是每次单击轴时都在新图形中重新创建图.为此,可以使用一种函数,该函数在指定的轴上以指定的索引作为输入来创建绘图.在图形创建期间以及以后在另一个图形中复制图形时使用此功能,可以确保在所有情况下都具有相同的图形.

Recreate plots

The alternative to the above is of course to recreate the plot in a new figure each time the axes is clicked. To this end one may use a function that creates a plot on a specified axes and with a specified index as input. Using this function during figure creation as well as later for replicating the plot in another figure ensures to have the same plot in all cases.

import matplotlib.pyplot as plt
import numpy as np

num_rows = 10
num_cols = 1
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
labels = ["Label {}".format(i+1) for i in range(num_rows)]

def myplot(i, ax):
    ax.plot(np.arange(10), np.arange(10)**i, color=colors[i])
    ax.set_ylabel(labels[i])


fig, axs = plt.subplots(num_rows, num_cols, sharex=True)
for i in xrange(num_rows):
     myplot(i, axs[i])


def on_click(event):
    axes = event.inaxes
    if not axes: return
    inx = list(fig.axes).index(axes)
    fig2 = plt.figure()
    ax = fig2.add_subplot(111)
    myplot(inx, ax)
    fig2.show()

fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

这篇关于pyplot-复制轴内容并将其显示在新图中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆