We do not have good built in support for this kind of thing (though we
should add it). One approach is to write a custom artist, as in this
example. I'm using GTK only for the idle handling callback, but you
can use whatever approach works for you. The important part is the
example showing how to write a custom artist for dynamic data:
import gtk
import numpy as np
import matplotlib
matplotlib.use('GTKAgg')
import matplotlib.pyplot as plt
import matplotlib.artist as artist
import matplotlib.colors as colors
import matplotlib.agg as agg
class DynamicMarkers(artist.Artist):
def __init__(self, buffersize=30):
artist.Artist.__init__(self)
self.buffersize = buffersize
self.x = []
self.y = []
self.count = 0
self.path = None
self.markersize = 10.
self.facecolor = colors.colorConverter.to_rgb('blue')
self.edgecolor = colors.colorConverter.to_rgb('black')
def add(self, x, y):
self.count+=1
self.x.append(x)
self.y.append(y)
if self.count>self.buffersize:
del self.x[0]
del self.y[0]
def draw(self, renderer):
if self.axes is None:
raise RuntimeError('you must first add me to the axes')
if self.path is None:
# use square markers
side = renderer.points_to_pixels(self.markersize)
offset = side*0.5
path = agg.path_storage()
path.move_to(-offset, -offset)
path.line_to(-offset, offset)
path.line_to(offset, offset)
path.line_to(offset, -offset)
path.end_poly()
self.path = path
gc = renderer.new_gc()
self._set_gc_clip(gc) # Artist method
gc.set_foreground(self.edgecolor)
renderer.draw_markers(gc, self.path, self.facecolor, self.x,
self.y, self.get_transform())
fig = plt.figure()
ax = fig.add_subplot(111)
myline = DynamicMarkers(30)
ax.add_artist(myline)
ax.set_xlim(-20, 1)
ax.set_ylim(0,1)
def animate(*args):
i = animate.i
print 'animate', i
myline.add(i, np.random.rand())
ax.set_xlim(i-30, i+1)
fig.canvas.draw()
animate.i += 1
if animate.i<200: return True
else: return False
gtk.idle_add(animate)
animate.i = 0
plt.show()
···
On Fri, Mar 28, 2008 at 8:20 AM, Matthias Michler <MatthiasMichler@...361...> wrote:
On Friday 28 March 2008 13:57, Chris Withers wrote:
> Matthias Michler wrote:
> > I'm not sure it is the easiest way, but it works for me:
> >
> > for label in ax.xaxis.get_majorticklabels():
> > label.set_rotation(+90)
>
> Yes, that's what I was using, just wondered if there was a better way...
At least I don't know a better way, but I'm not an expert.
> >> Also, how would I get this kind of updating with bar charts or
> >> errorbars?
> >
> > In the case of bar charts and errorbars it is quite difficult to reset
> > the data.
>
> Oh, I also meant to ask about scatter, can the data be easilly reset there?
Scatter returns a line collection and I don't know if there is a method to
reset their x/ydata.