Plot subplot axes in separate figure in matplotlib [duplicate]

匿名 (未验证) 提交于 2019-12-03 02:33:02

问题:

This question already has an answer here:

Suppose I have the following code (modified version of matplotlib gridspec tutorial)

import matplotlib.pyplot as plt  def make_ticklabels_invisible(fig):     for i, ax in enumerate(fig.axes):         ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")         for tl in ax.get_xticklabels() + ax.get_yticklabels():             tl.set_visible(False)   plt.figure(0) ax1 = plt.subplot2grid((3,3), (0,0), colspan=3) ax2 = plt.subplot2grid((3,3), (1,0), colspan=2) ax3 = plt.subplot2grid((3,3), (1, 2), rowspan=2) ax4 = plt.subplot2grid((3,3), (2, 0)) plt.subplot2grid((3,3), (2, 1))  # OOPS! Forgot to store axes object  plt.suptitle("subplot2grid") make_ticklabels_invisible(plt.gcf()) plt.show() 

which results in

How can I 'extract' ax5 and plot it 'full screen' in a separate figure without having to recreate the plot?

回答1:

I can't find anything in official documentation to back up what I'm saying, but my understanding is that it is impossible to "clone" an existing axes onto a new figure. In fact, no artist (line, text, legend) defined in one axes may be added to another axes. This discussion on Github may explain it to some degree.

For example, attempting to add a line from an axes defined on fig1 to an axes on a different figure fig2 raises an error:

import matplotlib.pyplot as plt fig1 = plt.figure() ax1 = fig1.add_subplot(111) line, = ax1.plot([0,1]) fig2 = plt.figure() ax2 = fig2.add_subplot(111) ax2.add_line(line) >>>RuntimeError: Can not put single artist in more than one figure` 

And attempting to add a line that was drawn in ax1 to a second axes ax2 on the same figure raises an error:

fig1 = plt.figure() ax1 = fig1.add_subplot(121) line, = ax1.plot([0,1]) ax12 = fig1.add_subplot(122) ax12.add_line(line) >>>ValueError: Can not reset the axes.  You are probably trying to re-use an artist in more than one Axes which is not supported 

The best recommendation I can make is extract the data from the axes you want to copy, and manually plot that into a new axes object that is sized to your liking. Something like below demonstrates this. Note that this works for Line2D objects plotted via ax.plot. If the data was plotted using ax.scatter, then you need to change things just a little bit and I refer you here for instructions on how to extract data from a scatter.

import matplotlib.pyplot as plt import numpy as np  def rd(n=5):     # Make random data     return np.sort(np.random.rand(n))  fig1 = plt.figure() ax1 = fig1.add_subplot(111) # Plot three lines on one axes ax1.plot(rd(), rd(), rd(), rd(), rd(), rd())  xdata = [] ydata = [] # Iterate thru lines and extract x and y data for line in ax1.get_lines():     xdata.append( line.get_xdata() )     ydata.append( line.get_ydata() )  # New figure and plot the extracted data fig2 = plt.figure() ax2 = fig2.add_subplot(111) for X,Y in zip(xdata,ydata):     ax2.plot(X,Y) 

Hope it helps.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!