matplotlib update data in thread - python

I'm new in matplotlib.
I want to update a data in an endless while loop in a different thread
in addition to updating the plot in the pyplot.show method.
I tried using the threading import but it isn't working
well together with pyplot.show method.
I know I can use pyplot.ion and it works fine with the threads.
The problem with pyplot.ion is that it is not efficient.
Is there any way that i could use pyplot.show instead?
To make myself clear, I don't want the solution:
pyplot.ion()
....
while True:
....
pyplot.show()

I'm not sure if this solves your problem, but you could try to use pyplot.draw()instead of pyplot.show(). If you already have used show() once, will it update the plot? draw() should update the plot though.
I do not know how you plot the data, but assuming that the data-set you're plotting is of the same size every time one trick to speed things up is to use set_data(), if you the first time you plot store the line-artist as
x, y = generate_data_function()
line, = pyplot.plot(x, y)
pyplot.show()
while True:
x, y = generate_data_function()
line.set_data(x, y)
pyplot.draw()
Hope it helps! As I said, I'm not completely sure if it really solves your problem but it could be worth trying at least.

I have found gobject.idle_add() and gobject.threads_init() to be very useful. It was almost exactly what I needed.
I also found these resources useful:
Can you plot live data in matplotlib?
http://wiki.scipy.org/Cookbook/Matplotlib/Animations

Related

How do plt.plot(x,y) and plt.show() work the way they do?

I wanted to know the basic backbone process going on between plt.plot(x,y) and plt.show() commands of matplotlib.pyplot.
To elaborate it a bit, the piece of code:
plt.plot(x , y)
plt.show()
show the desired graph (no problem with that).
Also, the code:
plt.plot(x , y)
plt.plot(p , q)
plt.show()
works fine as well. It shows the two plots created by the lists x & y and p & q.
Now here is something that I found very interesting when coding dynamically in ipython.
In [73]: plt.plot(x , y)
#normal plotting function.
In [78]: plt.show()
#shows a graph as intended.
In [79]: plt.show()
#shows nothing.
Now, no matter how many times I call plt.show() (after I've called it once) it doesn't display the graph at all. Why is so?.
PS: To my understanding maybe there is an object being created and deleted withing this process. But neither I'm sure nor convinced.
Thanks in advance.
Pyplot uses or is a so called "statemachine". It stores a number of figures and references to the current axes and figure. Once show is called, all figures are shown and once show returns, they are removed from the statemachine.
On a subsequent call to show there are no figures to show anymore, hence not output is shown.
Therefore there is some (maybe unwritten or implicit) assumption that show is called exactly once in a script.
It may be worth noting that although figures are removed from the statemachine they remain in memory until they are closed. So they may be reused under certain circumstances and depending on the desired workflow.

Having issues with matplolib for loop getting slower

I want to loop over a series of images to see how they change over time. Thus, I want them plotted on the same figure. The following code works but seems to slow down after a few iterations. Does anyone know why this is happening, how to overcome it, or an alternative way to visualize these images over time?
fig, ax=pyplot.subplots(figsize=(8,6))
for i in range(n):
ax.imshow(imageArray[i])
fig.canvas.draw()
time.sleep(0.2)
The animation is getting slower because the old image isn't deleted. More and more images will be redrawn each time you call fig.canvas.draw(). Therefore add ax.cla() before the imshow call. The tutorial that Jake suggested doesn't need the cla because it sets the image directly, and will therefore be slightly faster.

dynamically plot the optimization result in Matplotlib

I'm doing a numerical optimization, and I want to visualize the loss of the objective function at each iteration, which means I need to add one point when each iteration is done into the plot.
I thought this might be a matplotlib.animation job, but it seems that animation just updates the plot by interval period of time, this is not what I want.
After searching SO, I indeed find a tricky solution, but is there a better way?
To set the data of a scatter in-place, you need to do the following:
pc = ax.scatter( x, y, ...)
and modify:
px.set_offsets( xnew, ynew )
before invoking wither draw (slower) or the blit method you linked.

Embed matplotlib figure in larger figure

I am writing a bunch of scripts and functions for processing astronomical data. I have a set of galaxies, for which I want to plot some different properties in a 3-panel plot. I have an example of the layout here:
Now, this is not a problem. But sometimes, I want to create this plot just for a single galaxy. In other cases, I want to make a larger plot consisting of subplots that each are made up of the three+pane structure, like this mockup:
For the sake of modularity and reusability of my code, I would like to do something to the effect of just letting my function return a matplotlib.figure.Figure object and then let the caller - function or interactive session - decide whether to show() or savefig the object or embed it in a larger figure. But I cannot seem to find any hints of this in the documentation or elsewhere, it doesn't seem to be something people do that often.
Any suggestions as to what would be the best road to take? I have speculated whether using axes_grid would be the solution, but it doesn't seem quite clean and caller-agnostic to me. Any suggestions?
The best solution is to separate the figure layout logic from the plotting logic. Write your plotting code something like this:
def three_panel_plot(data, ploting_args, ax1, ax2, ax3):
# what you do to plot
So now the code that turns data -> images takes as arguments the data and where it should plot that data too.
If you want to do just one, it's easy, if you want to do a 3x3 grid, you just need to generate the layout and then loop over the axes sets + data.
The way you are suggesting (returning an object out of your plotting routine) would be very hard in matplotlib, the internals are too connected.

Most lightweight way to plot streaming data in python

To give you a sense of what I'm looking for, it looks like this:
Up until now I have used matplotlib for all my plotting, and timing hasn't been critical (it's been done in postprocessing).
I'm wondering if there is a lighter weight way to plot other than shifting my data to the left and redrawing the entire plot.
Have a look at the Matplotlib Animations Examples. The main trick is to not completely redraw the graph but rather use the OO interface of matplotlib and set the x/ydata of the plot-line you created. If you've integrated your plot with some GUI, e.g., GTK, then definitely do it like proposed in the respective section of the plot, otherwise you might interfere with the event-loop of your GUI toolkit.
For reference, if the link ever dies:
from pylab import *
import time
ion()
tstart = time.time() # for profiling
x = arange(0,2*pi,0.01) # x-array
line, = plot(x,sin(x))
for i in arange(1,200):
line.set_ydata(sin(x+i/10.0)) # update the data
draw() # redraw the canvas
print 'FPS:' , 200/(time.time()-tstart)
You could try streamlit lib.
Should be the lightest one.
In the python wiki there is a list of suggestions with short descriptions: link.

Categories

Resources