I'm trying to create an animated histogram for work, using matplotlib.animation, but animation.FuncAnimation is not functioning properly : when using this code, that i found on the official documentation,
"""
A simple example of an animated plot
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))
def animate(i):
print(i)
line.set_ydata(np.sin(x + i/10.0)) # update the data
return line,
# Init only required for blitting to give a clean slate.
def init():
line.set_ydata(np.ma.array(x, mask=True))
return line,
ani = animation.FuncAnimation(fig, animate, np.arange(1, 200),init_func=init,interval=25, blit=True)
plt.show()
I get as final result the graph created by init() function (an empty graph also), but no animate iterations. Furthermore, I tested other codes, which practically gave me the same result : i get the initialization, or the first frame, but not more. matplotlib and matplotlib.animation are installed, everything seems to be ok, except it doesn't work. Have someone an idea how to fix it ? (Thank you in advance :) !)
I had the same issue working with Jupyter notebook and I solved it by inserting the line
%matplotlib notebook
in the code.
It may be that IPython inside your Spyder is configured to automatically use the inline backend. This would show your plots inside the console as png images. Of course png images cannot be animated.
I would suggest not to use IPython but execute the script in a dedicated Python console. In Spyder, go to Run/Configure.. and set the option to new dedicated Python console.
I'm working with matplotlib plotting and use ioff() to switch interactive mode off to suppress the automatic opening of the plotting window on figrue creation. I want to have full control over the figure and only see it when explicitely using the show() command.
Now apparently the built-in commands to clear figures and axes do not work properly anymore.
Example:
import numpy as np
import matplotlib.pyplot as mpp
class PlotTest:
def __init__(self,nx=1,ny=1):
# Switch off interactive mode:
mpp.ioff()
# Create Figure and Axes:
self.createFigure(nx, ny)
def createFigure(self,nx=1,ny=1):
self.fig, self.axes = mpp.subplots(nx,ny)
if nx*ny == 1:
self.axes = np.array([self.axes])
def linePlot(self):
X = np.linspace(0,20,21)
Y = np.random.rand(21)
self.axes[0].plot(X,Y)
P = PlotTest()
P.linePlot()
P.fig.show()
Now I was thinking I could use P.fig.clear() any time to simply clear P.fig, but apparently that's not the case.
Writing P.fig.clear() directly into the script and execute it together it works and all I see is an empty figure. However that's rather pointless as I never get to see the actual plot like that.
Doing P.fig.clear() manually in the console does not do anything, regardless if the plot window is open or not, all other possible commands fail as well:
P.fig.clf()
P.axes[0].clear()
P.axes[0].cla()
mpp.clf()
mpp.cla()
mpp.close(P.fig)
Wrapping the command into a class method doesn't work either:
def clearFig(self):
self.fig.clear()
EDIT ================
After a clear() fig.axes is empty, yet show() still shows the old plot with the axes still being plotted.
/EDIT ================
Is it because I switched off interactive mode?
If you add a call to plt.draw() after P.fig.clear() it clears the figure. From the docs,
This is used in interactive mode to update a figure that has been altered, but not automatically re-drawn. This should be only rarely needed, but there may be ways to modify the state of a figure with out marking it as stale. Please report these cases as bugs.
I guess this is not a bug as you have switched off interactive mode so it is now your responsibility to explicitly redraw when you want to.
You can also use P.fig.canvas.draw_idle() which could be wrapper in the class as clearFigure method.
I am trying to plot in Jupyter notebook (Python 2.7), then prompt user for input, save it and then change the plot (this is a crucial point: I don't want to create a new plot, I need to modify the old one after user input). This completely fails to work. Instead of showing the figure and then prompting for input, it opens the figure window, but freezes (doesn't display anything) until I respond to the raw_input() prompt. Only then it plots.
Simple version of the code to show the error:
import matplotlib.pyplot as plt
%matplotlib qt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3],[1,2,3])
plt.show(block=False)
my_input = raw_input()
This bug only appears when I use %matplotlib qt, but I have to use it, because with %matplotlib inline I am unable to modify the plot after it was displayed (at least as far as I am aware).
In fact, I noticed that it freezes until the end of the cell execution, even if it is just time.sleep().
Am I missing something? Some settings of how matplotlib displays figures?
Since I am using Python3 I had to change raw_input() to input() and removed the block=False because IPython told me that this is an unknown attribute.
This should work nice:
import matplotlib.pyplot as plt
%matplotlib inline
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3], [1,2,3])
plt.show()
my_input = input()
Fur sure, you need to adapt this back to Python2 to fit your needs.
I'm currently trying to display dynamically the result of a genetic fitting I'm running (so that I can decide when to stop). The code is pretty much the following:
#vars stands for a bunch of variables required for the simulation and the fit
import matplotlib.pyplot as plt
class plotSim:
def __init__(self, vars, line)
self.vars = vars
self.line = line
def animate(self,i):
simulation_fit_result = perform_simulation_fit(self.vars)
self.line.set_ydata(simulation_fit_result)
fig, ax = plt.subplots(figsize=(20,8))
ax.semilogy(x_experimental,y_experimental)
line, = ax.semilogy(x_simulation,y_simulation) #initializing the line with the simulation performed with the initial values to fit
plotfit = plotSim(vars,line)
ani = animation.FuncAnimation(fig, plotfit.animate,interval=1000)
plt.show()
I can't see the difference with other example I found googling. In my case the simulation is successfully performed (as I can see some stuff printed I placed for check) but no figures are showing (not even a static one). I also had the same problem using plt.ion() combined with plt.draw(). I'm using Spyder 2.1.9 IDE under Ubuntu 12.04, can this have any influence?
Thanks for the help to anyone answering.
Say that I have two figures in matplotlib, with one plot per figure:
import matplotlib.pyplot as plt
f1 = plt.figure()
plt.plot(range(0,10))
f2 = plt.figure()
plt.plot(range(10,20))
Then I show both in one shot
plt.show()
Is there a way to show them separately, i.e. to show just f1?
Or better: how can I manage the figures separately like in the following 'wishful' code (that doesn't work):
f1 = plt.figure()
f1.plot(range(0,10))
f1.show()
Sure. Add an Axes using add_subplot. (Edited import.) (Edited show.)
import matplotlib.pyplot as plt
f1 = plt.figure()
f2 = plt.figure()
ax1 = f1.add_subplot(111)
ax1.plot(range(0,10))
ax2 = f2.add_subplot(111)
ax2.plot(range(10,20))
plt.show()
Alternatively, use add_axes.
ax1 = f1.add_axes([0.1,0.1,0.8,0.8])
ax1.plot(range(0,10))
ax2 = f2.add_axes([0.1,0.1,0.8,0.8])
ax2.plot(range(10,20))
With Matplotlib prior to version 1.0.1, show() should only be called once per program, even if it seems to work within certain environments (some backends, on some platforms, etc.).
The relevant drawing function is actually draw():
import matplotlib.pyplot as plt
plt.plot(range(10)) # Creates the plot. No need to save the current figure.
plt.draw() # Draws, but does not block
raw_input() # This shows the first figure "separately" (by waiting for "enter").
plt.figure() # New window, if needed. No need to save it, as pyplot uses the concept of current figure
plt.plot(range(10, 20))
plt.draw()
# raw_input() # If you need to wait here too...
# (...)
# Only at the end of your program:
plt.show() # blocks
It is important to recognize that show() is an infinite loop, designed to handle events in the various figures (resize, etc.). Note that in principle, the calls to draw() are optional if you call matplotlib.ion() at the beginning of your script (I have seen this fail on some platforms and backends, though).
I don't think that Matplotlib offers a mechanism for creating a figure and optionally displaying it; this means that all figures created with figure() will be displayed. If you only need to sequentially display separate figures (either in the same window or not), you can do like in the above code.
Now, the above solution might be sufficient in simple cases, and for some Matplotlib backends. Some backends are nice enough to let you interact with the first figure even though you have not called show(). But, as far as I understand, they do not have to be nice. The most robust approach would be to launch each figure drawing in a separate thread, with a final show() in each thread. I believe that this is essentially what IPython does.
The above code should be sufficient most of the time.
PS: now, with Matplotlib version 1.0.1+, show() can be called multiple times (with most backends).
I think I am a bit late to the party but...
In my opinion, what you need is the object oriented API of matplotlib. In matplotlib 1.4.2 and using IPython 2.4.1 with Qt4Agg backend, I can do the following:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1) # Creates figure fig and add an axes, ax.
fig2, ax2 = plt.subplots(1) # Another figure
ax.plot(range(20)) #Add a straight line to the axes of the first figure.
ax2.plot(range(100)) #Add a straight line to the axes of the first figure.
fig.show() #Only shows figure 1 and removes it from the "current" stack.
fig2.show() #Only shows figure 2 and removes it from the "current" stack.
plt.show() #Does not show anything, because there is nothing in the "current" stack.
fig.show() # Shows figure 1 again. You can show it as many times as you want.
In this case plt.show() shows anything in the "current" stack. You can specify figure.show() ONLY if you are using a GUI backend (e.g. Qt4Agg). Otherwise, I think you will need to really dig down into the guts of matplotlib to monkeypatch a solution.
Remember that most (all?) plt.* functions are just shortcuts and aliases for figure and axes methods. They are very useful for sequential programing, but you will find blocking walls very soon if you plan to use them in a more complex way.
Perhaps you need to read about interactive usage of Matplotlib. However, if you are going to build an app, you should be using the API and embedding the figures in the windows of your chosen GUI toolkit (see examples/embedding_in_tk.py, etc).
None of the above solutions seems to work in my case, with matplotlib 3.1.0 and Python 3.7.3. Either both the figures show up on calling show() or none show up in different answers posted above.
Building upon #Ivan's answer, and taking hint from here, the following seemed to work well for me:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1) # Creates figure fig and add an axes, ax.
fig2, ax2 = plt.subplots(1) # Another figure
ax.plot(range(20)) #Add a straight line to the axes of the first figure.
ax2.plot(range(100)) #Add a straight line to the axes of the first figure.
# plt.close(fig) # For not showing fig
plt.close(fig2) # For not showing fig2
plt.show()
As #arpanmangal, the solutions above do not work for me (matplotlib 3.0.3, python 3.5.2).
It seems that using .show() in a figure, e.g., figure.show(), is not recommended, because this method does not manage a GUI event loop and therefore the figure is just shown briefly. (See figure.show() documentation). However, I do not find any another way to show only a figure.
In my solution I get to prevent the figure for instantly closing by using click events. We do not have to close the figure — closing the figure deletes it.
I present two options:
- waitforbuttonpress(timeout=-1) will close the figure window when clicking on the figure, so we cannot use some window functions like zooming.
- ginput(n=-1,show_clicks=False) will wait until we close the window, but it releases an error :-.
Example:
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots(1) # Creates figure fig1 and add an axes, ax1
fig2, ax2 = plt.subplots(1) # Another figure fig2 and add an axes, ax2
ax1.plot(range(20),c='red') #Add a red straight line to the axes of fig1.
ax2.plot(range(100),c='blue') #Add a blue straight line to the axes of fig2.
#Option1: This command will hold the window of fig2 open until you click on the figure
fig2.waitforbuttonpress(timeout=-1) #Alternatively, use fig1
#Option2: This command will hold the window open until you close the window, but
#it releases an error.
#fig2.ginput(n=-1,show_clicks=False) #Alternatively, use fig1
#We show only fig2
fig2.show() #Alternatively, use fig1
As of November 2020, in order to show one figure at a time, the following works:
import matplotlib.pyplot as plt
f1, ax1 = plt.subplots()
ax1.plot(range(0,10))
f1.show()
input("Close the figure and press a key to continue")
f2, ax2 = plt.subplots()
ax2.plot(range(10,20))
f2.show()
input("Close the figure and press a key to continue")
The call to input() prevents the figure from opening and closing immediately.