plt.figure.Figure.show() does nothing when not executing interactively - python

So I have a following simple code saved in a .py file, and executing in shell:
import matplotlib.pyplot as plt
myfig = plt.figure(figsize=(5, 5))
ax1 = myfig.add_subplot(1, 1, 1)
myfig.show()
However it does nothing upon execution, no errors nothing.
Then when I start Ipython in shell, and type exact same code, it does pop up an empty window. Why is that?
of course I can use plt.show() and everything is fine. But lets say I have two figures, fig1 and fig2, and there is stuff in both figs, and I want to only display one of them, how can I do that? plt.show() plots both of them.
Sorry if this is stupid I'm just curious why when working interactively in ipython, window pops up upon calling fig1.show() but nothing happens when I execute same script in shell but doing: python myfile.py
Thank you!

plt.show starts an event loop, creates interactive windows and shows all current figures in them. If you have more figures than you actually want to show in your current pyplot state, you may close all unneeded figures prior to calling plt.show().
fig1 = plt.figure()
ax1 = fig1.add_subplot(1, 1, 1)
ax1.plot([1,3,4])
fig2 = plt.figure()
ax2 = fig2.add_subplot(1, 1, 1)
ax2.plot([1,2,5])
# close first figure
plt.close(fig1)
# show all active figures (which is now only fig2)
plt.show()
In contrast fig.show() will not start an event loop. It will hence only make sense in case an event loop already has been started, e.g. after plt.show() has been called. In non-interactive mode that may happen upon events in the event loop. To give an example, the following would show fig2 once a key on the keyboard is pressed when fig1 is active.
import matplotlib.pyplot as plt
fig1 = plt.figure()
ax1 = fig1.add_subplot(1, 1, 1)
ax1.plot([1,3,4])
def show_new_figure(evt=None):
fig2 = plt.figure()
ax2 = fig2.add_subplot(1, 1, 1)
ax2.plot([1,2,5])
fig2.show()
# Upon pressing any key in fig1, show fig2.
fig1.canvas.mpl_connect("key_press_event", show_new_figure)
plt.show()

You need to modify your code like this:
import matplotlib.pyplot as plt
myfig = plt.figure(figsize=(5, 5))
ax1 = myfig.add_subplot(1, 1, 1)
plt.plot((1, 2, 3)) # <- plot something
plt.show() # <- show the plot
more info in matplotlib docs here.

you need add an extra line
%matplotlib inline
To get the plot in jupyter notebook.
for more you can refer http://ipython.readthedocs.io/en/stable/interactive/tutorial.html#magics-explained

Related

Activate a figure in matplotlib

It seems easy but I could not find any solution for opening multiple figures and save them by their name. I look for something like this:
fig1, ax1 = pl.subplots(1)
fig2, ax2 = pl.subplots(1)
...
pl.savefig('f1.png', fig1)
pl.savefig('f2.png', fig2)
usually pl.savefig acts on the last active figure. So how one can activate a figure and save it, then repeat the process for the rest of the figures?
You can save an image using the figure object itself:
fig1.savefig(...)
Alternatively, you can change the current figure by calling plt.figure(1) to select the first figure that was create and then use plt.savefig(). Or, you can use plt.figure(fig1.number) to switch focus to fig1
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots(1)
fig2, ax2 = plt.subplots(1)
# Can choose one of the below to change the current figure
plt.figure(1)
# plt.figure(fig1.number)
plt.savefig(...) # will save fig1

Re-call matplotlib graphs after inital call

I have a Tkinter GUI which creates a budget calculator and stores transactions. One of the buttons on the GUI is a call to a script that creates charts from the transaction data.
The first time I click the button, the graphs open up fine. If I attempt to click the button again, a blank figure comes up. I believe this comes from my initial,
plt.show()
call where I draw the graphs. Has anyone ran into a problem like this before?
GUI code:
ViewCharts = Button(win,text = 'View Spending Charts')
ViewCharts.grid(row = 21,column = 1)
def view_charts():
Graphs.plot_charts()
ViewCharts.configure(command = view_charts)
Charts code:
global fig
fig = plt.figure(figsize=(12, 9))
fig.subplots_adjust(hspace=.5)
global ax1
ax1 = fig.add_subplot(1,2,1)
global ax2
ax2 = fig.add_subplot(1,2,2)
def plot_charts():
category_bar_chart()
category_pie_chart()
fig = plt.show()
Where category_bar_chart() and category_pie_chart() are just functions to add plots into ax1 and ax2.
Any help or advice is greatly appreciated! I am working on Python3 on a Mac/PC depending on the time of day. Thanks!
The problem is you are redefining fig when you do fig = plt.show() so after the first call, you no longer have the plots stored anywhere. Simply do plt.show() instead.

Plotting second figure with matplotlib while first is still open

K here's a more precise example of what I am trying to do. I am using WXBuilder for Python as my user interface with multiple plotting functionality i.e. the user must be able to plot a graph based on their chosen parameters. After a graph is plotted I want the user to be able to plot a second without closing the first figure. This is for comparison purposes. Below is an oversimplified example of what I am looking to do.
import matplotlib as plt
def OnPlotClick1(self, event):
plt.plot(self.DateArray1, self.kVAArray2)
plt.show()
def OnPlotClick2(self, event):
plt.plot(self.DateArray1, self.kVAArray2)
plt.show()
Now I am assuming my problem is arising due plotting and showing() the graph, and therefore the program somehow is blocked from functionality until the first figure or plot window is closed.
I hope this explains my problem better.
You should not block show. Use:
import matplotlib.pylab as plt
plt.plot([1,2,3]) # first plot
plt.show(block=False) # do not block
plt.plot([11,21,31]) # second plot
Each window is in matplotlib parlance, a new figure. You can call plt.subplots twice to create two figures:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 1000)
y1 = np.sin(x)*np.exp(-x/5.0)
y2 = np.sin(x**2)*x
fig1, ax1 = plt.subplots()
ax1.plot(x, y1)
fig2, ax2 = plt.subplots()
ax2.plot(x, y2)
plt.show()
Note that plt.show() starts a GUI event loop and so generally it should only be called once per script.
You can also draw 2 or more than 2 plotters in the same figure
import matplotlib.pyplot as plt
def my_plotter(ax, data1, data2, param_dict):
out = ax.plot(data1, data2, **param_dict)
return out
fig, (ax1, ax2) = plt.subplots(1, 2)
#here you put your data
data1=[0,1,2,3,8]
data2=[0,1,2,3,8]
data3=[0,1,2,3,8]
data4=[0,1,2,3,8]
my_plotter(ax1, data1, data2, {'marker':'x'})
my_plotter(ax2, data3, data4, {'marker':'o'})
plt.show()
You can either follow #(Corrupted MyStack) suggestion or with interactive graphic devide. Run
plt.ion()
once, anytime before you start the plots. To turn it off
plt.ioff()

Python/Matplotlib 1.0.1 does not open new figure when clicked

I have a problem with Matplotlib 1.0.1
I create a figure, and the I use an onclick event to do stuff when I click into the figure. One thing is, that it has to create a new figure with new data in it. This perfectly works in Matplotlib 0.99.3, where I developed the script, but now a collegue tried it on his machine, which has matplotlib 1.0.1 (and python 2.6 instead of 2.7), and the figure is not shown.
However, I think the figure is created, but not shown, because if I close the first figure, the script is not ended, it is still running.
Here is a simple example code:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
a = [1,2,3]
b = [4,2,9]
line = ax.plot(a,b)
def onclick(event):
print "clicked"
a = [7,8,9]
b = [1,9,20]
fig2 = plt.figure()
ax_single = fig2.add_subplot(111)
line2 = ax_single.plot(a,b)
cid = fig.canvas.mpl_connect('button_press_event',onclick)
plt.show()
Is this a (known) bug in matplotlib 1.0.1? Is there any way around it?
Thx.
Adding a simple fig2.show() did the trick to me. Read the How-to to get more information!
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
a = [1,2,3]
b = [4,2,9]
line = ax.plot(a,b)
def onclick(event):
print "clicked"
a = [7,8,9]
b = [1,9,20]
fig2 = plt.figure()
ax_single = fig2.add_subplot(111)
line2 = ax_single.plot(a,b)
fig2.show()
cid = fig.canvas.mpl_connect('button_press_event',onclick)
plt.show()
The was indeed a change in 1.0.0 in the way matplotlib handles figures after the mainloop has been started.
You can put Pyplot in interactive mode at the beginning:
plt.ion()
and then end your program with something like
raw_input('Press enter when done...')
(instead of show()).
The semantics of show() and of the interactive mode were updated with Matplotlib 1.0. You can get more information on this on StackOverflow: Exact semantics of Matplotlib's "interactive mode" (ion(), ioff())?. I understand that using the interactive mode (ion) is generally more convenient. Another important point is that in interactive mode, only pyplot.* functions automatically draw/redraw plots (and not <object>.*() methods).

Choosing which figures to show on-screen and which to save to a file using Python's matplotlib

I'd like to create different figures in Python using matplotlib.pyplot. I'd then like to save some of them to a file, while others should be shown on-screen using the show() command.
However, show() displays all created figures. I can avoid this by calling close() after creating the plots which I don't want to show on-screen, like in the following code:
import matplotlib.pyplot as plt
y1 = [4, 2, 7, 3]
y2 = [-7, 0, -1, -3]
plt.figure()
plt.plot(y1)
plt.savefig('figure1.png')
plt.close()
plt.figure()
plt.plot(y2)
plt.show()
plt.close('all')
This saves the first figure and shows the second one. However, I get an error message:
can't invoke "event" command: application has been destroyed while executing
Is it possible to select in a more elegant way which figures to show?
Also, is the first figure() command superfluous? It doesn't seem to make a different whether I give it or not.
Many thanks in advance.
The better way is to use plt.clf() instead of plt.close().
Moreover plt.figure() creates a new graph while you can just clear previous one with plt.clf():
import matplotlib.pyplot as plt
y1 = [4, 2, 7, 3]
y2 = [-7, 0, -1, -3]
plt.figure()
plt.plot(y1)
plt.savefig('figure1.png')
plt.clf()
plt.plot(y2)
plt.show()
plt.clf()
This code will not generate errors or warnings such can't invoke "event" command...
Generally speaking, you can just close the figure. As a quick example:
import matplotlib.pyplot as plt
fig1 = plt.figure()
plt.plot(range(10), 'ro-')
plt.title('This figure will be saved but not shown')
fig1.savefig('fig1.png')
plt.close(fig1)
fig2 = plt.figure()
plt.plot(range(10), 'bo')
plt.title('This figure will be shown')
plt.show()
As far as whether or not the first plt.figure() call is superflous, it depends on what you're doing. Usually, you want to hang on to the figure object it returns and work with that instead of using matplotlib's matlab-ish state machine interface.
When you're making more complex plots, it often becomes worth the extra line of code to do something like this:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(range(10))
The advantage is that you don't have to worry about which figure or axis is "active", you just refer to a specific axis or figure object.

Categories

Resources