Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

matplotlib - pyplot - copy an axes content and show it in a new figure

let say I have this code:

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()

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

I tried doing something like this

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)

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

edit:

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

edit #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()

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

thanks

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Copying the axes

The inital answer here does not work, we keep it for future reference and also to see why a more sophisticated approach is needed.

#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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...