Python/Matplotlib 1.0.1 does not open new figure when clicked - python

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

Related

How to setup matplotlib in order to show all figures in one single window?

I want to plot over 100 charts, hence subplots does not work for it. I want to be able to navigate the charts using the arrows in the top side of the Figure window
I am not sure that matplotlib provides such a function that you can choose a specific plot from the plot list, I could not find it in documentation. However, by following link, you can check the plots by clicking. Good luck!
import scipy
import matplotlib.pyplot as plt
DataRange = range(0, 360)
DataRange = list(map(scipy.deg2rad, DataRange))
Data1 = list(map(scipy.sin, DataRange))
Data2 = list(map(scipy.cos, DataRange))
toggle = True
def onclick(event):
global toggle
toggle = not toggle
event.canvas.figure.clear()
if toggle:
event.canvas.figure.gca().plot(Data1)
else:
event.canvas.figure.gca().plot(Data2)
event.canvas.draw()
fig = plt.figure()
fig.canvas.mpl_connect('button_press_event', onclick)
plt.plot(Data1)
plt.show()

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

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

Matplotlib: Saved files in a loop aren't the same as in show()

My program shows the correct graph in the plt.show() pop up but not in the fig.savefig one. I'm quite new to python so apologies if it is something simple.
I'm using python 2.7.10, windows (10).
import numpy as np
import matplotlib.pyplot as plt
data = np.genfromtxt('strike_details.txt') #, skip_header= 0
header= 3
information=10000
width = 5
files = 16
types = 4
length = information + header
frames = data[header:length,0]
fig= plt.figure()
plt.grid(True)
for i in range(0,int(files)):
density=data[(header+i*length):(length+i*length),4]
plt.plot(frames,density, label=data[i*length+1][2])
for j in range (0,files/types):
if i==(types*(j+1)-1):
plt.legend(loc='best')
plt.xlabel('$Frames$', fontsize=22)
plt.ylabel('$Density$', fontsize=22)
fig.savefig(str(data[j*length+1][0])+'_'+str(data[j*length+1][1])+'_'+str(data[j*length+1][2])+'.png',format='png', dpi=fig.dpi)
plt.show()
plt.clf()
The program produces four files with different file names but they're all of the first group you see in the plt.show pop up.
If I missed out anything important let me know.
Thanks,
Lio
I think this is due to mixing the API-style and interactive-styles of matplotlib. When you call plt.show() the link between the active figure and fig is broken, and so you continue to output the first figure you created. I can reproduce this problem with this minimal example:
import matplotlib.pyplot as plt
fig = plt.figure()
for n in range(0,10):
plt.plot(list(range(0,n)))
fig.savefig('test%d.png' % n)
plt.show()
plt.clf()
If you remove the show() the issue goes away.
The correct way to do this is to access the current interactive figure via plt.gcf():
plt.gcf().savefig(...)
Alternatively, you can workaround it by recreating the figure object on each loop:
for i in range(0,int(files)):
fig= plt.figure()
plt.grid(True)
...

"Reset original view" does not show the whole plot

I'm plotting a line and updating it in a loop. When I pan the plot at some point during the execution and then click "Reset original view" in the interactive matplotlib window, I am taken back to the plot state from the moment when I started zooming/panning it. Is there a way to see the full extents of the plot instead? Even better, is there a way to tell matplotlib to keep updating the view after this operation?
python 3.4.3, matplotlib 1.4.3
import matplotlib
matplotlib.use('Qt4Agg')
import matplotlib.pyplot as plt
import numpy as np
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
values_v = []
values_i = []
ln1, = ax1.plot(values_i, values_v, color='green')
plt.ion()
plt.show()
for i in range(40):
scopevals = [i, i+2+np.random.rand()]
values_v.append(scopevals[0])
values_i.append(scopevals[1])
ln1.set_data([values_i, values_v])
ax1.relim()
ax1.autoscale_view(True,True,True)
plt.pause(1)
I encountered the problem when I displayed different images in the same figure.
Clearing the old figure helped me:
plt.figure(1) #the figure you re working with
plt.clf() #clear figure
plt.imshow(self.sample_image) # show new picture
And the Original view should work again.
Cheers
Andy

how do I redraw an image using python's matplotlib?

What I am trying to do seems to be fairly straightforward, but I'm having a heck of a time trying to get it to work. I am simply trying to draw an image using imshow and then re-draw it periodically as new data arrives.
I've started out with this:
fig = figure()
ax = plt.axes(xlim=(0,200),ylim=(0,200))
myimg = ax.imshow(zeros((200,200),float))
Then I'm assuming I can call set_data like this to update the image:
myimg.set_data(newdata)
I've tried many other things, for example I've called ax.imshow(newdata) instead or I've tried using figure.show() after set_data().
You can simply call figure.canvas.draw() each time you append something new to the figure. This will refresh the plot.
from matplotlib import pyplot as plt
from builtins import input
fig = plt.figure()
ax = fig.gca()
fig.show()
block = False
for i in range(10):
ax.plot(i, i, 'ko')
fig.canvas.draw()
if block:
input('pause : press any key ...')
else:
plt.pause(0.1)
plt.close(fig)

Categories

Resources