the following code snippet is from a simple wxpython/matplotlib app
# Data object class
class PlotData(object):
# Constructor (dummy arrays)
def __init__(self):
self.np = 100
self.xa = numpy.arange(100.0)
self.ya = 2.0 * self.xa
self.ys = 4.0 * self.xa
# Plot window class
class PlotWin(object):
def __init__(self, data):
self.data = data # Store reference to data object
self.figure = Figure() # Initialise figure
# Create an Axes object to plot on
self.ax1 = self.figure.gca()
self.ax1.yaxis.tick_left()
self.ax1.xaxis.tick_bottom()
# Plot the data
self.lines=[]
self.lines.append(self.ax1.plot(self.data.xa, self.data.ya, 'g'))
self.lines.append(self.ax1.plot(self.data.xa, self.data.ys, '-r'))
# Update plot with new data
def RefreshPlot(self, data):
self.lines[0].set_data((self.data.xa,self.data.ya))
self.lines[1].set_data((self.data.xa,self.data.ys))
self.canvas.draw()
# Main program
if __name__ == "__main__":
data = PlotData()
pwin = PlotWin(data)
pwin.RefreshPlot(data)
The plot data changes during the application and I just want to replace the existing data with the new data (which may have a different number of points compared to the old data). I get the Python error "'list' object has no attribute 'set_data'" when the code executes RefreshPlot(). AFAIK lines[0] and lines[1] are 'Line2D' objects (at least that's what Python says they are when I ask to have them printed) , which do have a 'set_data' method. I'm sure there's something really easy that I need to do but just can't see it - all suggestions gratefully received!
Thanks in advance
Alun Griffiths
the following code snippet is from a simple wxpython/matplotlib app
# Data object class
class PlotData(object):
# Constructor (dummy arrays)
def __init__(self):
self.np = 100
self.xa = numpy.arange(100.0)
self.ya = 2.0 * self.xa
self.ys = 4.0 * self.xa
# Plot window class
class PlotWin(object):
def __init__(self, data):
self.data = data # Store reference to data object
self.figure = Figure() # Initialise figure
# Create an Axes object to plot on
self.ax1 = self.figure.gca()
self.ax1.yaxis.tick_left()
self.ax1.xaxis.tick_bottom()
# Plot the data
self.lines=
self.lines.append(self.ax1.plot(self.data.xa, self.data.ya, 'g'))
self.lines.append(self.ax1.plot(self.data.xa, self.data.ys, '-r'))
# Update plot with new data
def RefreshPlot(self, data):
self.lines[0].set_data((self.data.xa,self.data.ya))
self.lines[1].set_data((self.data.xa,self.data.ys))
self.canvas.draw()
# Main program
if __name__ == "__main__":
data = PlotData()
pwin = PlotWin(data)
pwin.RefreshPlot(data)
The plot data changes during the application and I just want to
replace the existing data with the new data (which may have a
different number of points compared to the old data). I get the
Python error "'list' object has no attribute 'set_data'" when the
code executes RefreshPlot(). AFAIK lines[0] and lines[1] are
'Line2D' objects (at least that's what Python says they are when I
ask to have them printed) , which do have a 'set_data' method. I'm
sure there's something really easy that I need to do but just can't
see it - all suggestions gratefully received!
I think the problem is:
self.lines.append(self.ax1.plot(self.data.xa, self.data.ya, 'g'))
plot() returns a list of lines. You are appending that list to self.lines, so
when you index self.lines[0] later, you are getting the list returned by
plot. You should either use extend() instead of append, or you need to index
deeper: self.lines[0][0] and self.lines[0][1].
Darren
On Wednesday 25 June 2008 07:09:52 am eShopping wrote:
Hi Darren
thanks for the quick reply. I tried
self.lines[0][0].set_data((self.data.xa,self.data.ya))
self.lines[0][1].set_data((self.data.xa,self.data.ys))
but got the error 'list index out of range' after the second statement. I also tried
self.lines[0][0].set_data((self.data.xa,self.data.ya))
self.lines[1][0].set_data((self.data.xa,self.data.ys))
There were no errors in this case but the data does not plot correctly. Finally, I tried
self.lines[0][0].set_xdata(self.data.xa)
self.lines[0][0].set_ydata(self.data.ya)
self.lines[1][0].set_xdata(self.data.xa)
self.lines[1][0].set_ydata(self.data.ys)
but matplotlib complained that 'xdata and ydata must be the same length' after executing the first of these statements (presumably because the new xa array has a different number of elements than the old ya array)
At 13:05 25/06/2008, you wrote:
Hi Alun,
On Wednesday 25 June 2008 07:09:52 am eShopping wrote:
> the following code snippet is from a simple wxpython/matplotlib app
> # Data object class
> class PlotData(object):
> # Constructor (dummy arrays)
> def __init__(self):
> self.np = 100
> self.xa = numpy.arange(100.0)
> self.ya = 2.0 * self.xa
> self.ys = 4.0 * self.xa
> # Plot window class
> class PlotWin(object):
> def __init__(self, data):
> self.data = data # Store reference to data object
> self.figure = Figure() # Initialise figure
> # Create an Axes object to plot on
> self.ax1 = self.figure.gca()
> self.ax1.yaxis.tick_left()
> self.ax1.xaxis.tick_bottom()
> # Plot the data
> self.lines=
> self.lines.append(self.ax1.plot(self.data.xa, self.data.ya, 'g'))
> self.lines.append(self.ax1.plot(self.data.xa, self.data.ys, '-r'))
> # Update plot with new data
> def RefreshPlot(self, data):
> self.lines[0].set_data((self.data.xa,self.data.ya))
> self.lines[1].set_data((self.data.xa,self.data.ys))
> self.canvas.draw()
> # Main program
> if __name__ == "__main__":
> data = PlotData()
> pwin = PlotWin(data)
> pwin.RefreshPlot(data)
> The plot data changes during the application and I just want to
> replace the existing data with the new data (which may have a
> different number of points compared to the old data). I get the
> Python error "'list' object has no attribute 'set_data'" when the
> code executes RefreshPlot(). AFAIK lines[0] and lines[1] are
> 'Line2D' objects (at least that's what Python says they are when I
> ask to have them printed) , which do have a 'set_data' method. I'm
> sure there's something really easy that I need to do but just can't
> see it - all suggestions gratefully received!
I think the problem is:
self.lines.append(self.ax1.plot(self.data.xa, self.data.ya, 'g'))
plot() returns a list of lines. You are appending that list to self.lines, so
when you index self.lines[0] later, you are getting the list returned by
plot. You should either use extend() instead of append, or you need to index
deeper: self.lines[0][0] and self.lines[0][1].
Darren
The self.lines[0][1] idiom is really ugly. Avoid it with Darren't
first suggestions::
self.lines.extend(ax.plot(something))
If the xdata or ydata change in size, you will need to set them both
simultaneously:
line.set_data(xdata, ydata)
On Wed, Jun 25, 2008 at 7:31 AM, eShopping <[email protected]...> wrote:
Hi Darren
thanks for the quick reply. I tried
self.lines[0][0].set_data((self.data.xa,self.data.ya))
self.lines[0][1].set_data((self.data.xa,self.data.ys))
but got the error 'list index out of range' after the second
statement. I also tried
self.lines[0][0].set_data((self.data.xa,self.data.ya))
self.lines[1][0].set_data((self.data.xa,self.data.ys))
There were no errors in this case but the data does not plot
correctly. Finally, I tried
self.lines[0][0].set_xdata(self.data.xa)
self.lines[0][0].set_ydata(self.data.ya)
self.lines[1][0].set_xdata(self.data.xa)
self.lines[1][0].set_ydata(self.data.ys)
but matplotlib complained that 'xdata and ydata must be the same
length' after executing the first of these statements (presumably
because the new xa array has a different number of elements than the
old ya array)