Description
Problem
Often, I will create figures using matplotlib using the Figure
class explicitly, because either I want to make a figure and repeatedly tweak it to see how it looks, or I am creating a lot of figures and don't need / want to deal with the pyplot interface. However, as far as I can tell, there is no native matplotlib way to show those figures since they weren't created with the pyplot interface.
An example of what I would like to do:
fig =. Figure()
ax = fig.subplots()
ax.plot([1, 2, 3, 4])
fig.show() # This gives an error (below)
Error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jordan.e/opt/miniconda3/lib/python3.7/site-packages/matplotlib/figure.py", line 408, in show
"Figure.show works only for figures managed by pyplot, "
AttributeError: Figure.show works only for figures managed by pyplot, normally created by pyplot.figure()
The reason I don't want to use plt.subplots()
followed by plt.show()
, is, as mentioned above, because I often want to close and re-show the same figure. It seems really odd to me that matplotlib has a way of creating figures via a pure-OOP interface, but no easy way to display them. This is very frustrating and basically leads me to either repeatedly re-create the same plot with the pyplot interface instead of just tweaking the one I already have. I wrote a very hacky method for showing created figures based on a StackOverflow answer to this question which is below, and does not work reliably (the figure doubles in size every time I show it):
def show_figure(fig):
"""
create a dummy figure and use its manager to display "fig"
"""
dummy = plt.figure()
new_manager = dummy.canvas.manager
new_manager.canvas.figure = fig
fig.set_canvas(new_manager.canvas)
plt.show()
Proposed Solution
Either support fig.show()
directly for figures created using the OOP-interface, or provide a method like pyplot.show_figure()
which takes as an argument an existing figure and prints it to the screen (doing the exact same thing that a plt.plot()
followed by plt.show()
would do)