Append _one point_ to a plot?

Hi list,

I'm trying to get a dynamic plot running.
I'm stuck at feeding the data to the lines.

basically I've a callback that receives a (y,x1,x2) tuple and I would
like to add the 2 points to the two matplotlib.lines of the figure.

should I handle a copy of xdata/ydata and gives the updated set to
set_x/ydata() for one point?
I tried to get_data() and append to it, but It's a MaskedArray and I
guess it means its a really bad idea to try this way.

probably a new class inheriting figure and overriding
get_data()//set_data() could do the trick?

any advice on a _clean_ design I could use?

thanks.

···

----
This message contains confidential information and may contain information that is legally privileged. If you have received this message by mistake, please immediately notify us and delete the original message. Thank you.

Ce message contient des informations confidentielles. S'il vous est parvenu par erreur, merci de bien vouloir nous en aviser par retour, de n'en faire aucun usage et de n'en garder aucune copie.
----

You can add a value to an array using np.concatenate:

x,y = line.get_data()
x = np.concatenate((x, [x0]))
y = np.concatenate((y, [y0]))

line.set_data([x,y])

This is rather inefficient however if you’re adding lots of points or if there are just a lot of point in x any in general. If you know how many points you’re going to end up with, you could create mostly empty MaskedArrays and keep the extra points masked until you get the data.

Ryan

···

On Fri, Jul 3, 2009 at 8:32 AM, guillaume ranquet <granquet@…2572…> wrote:

Hi list,

I’m trying to get a dynamic plot running.

I’m stuck at feeding the data to the lines.

basically I’ve a callback that receives a (y,x1,x2) tuple and I would

like to add the 2 points to the two matplotlib.lines of the figure.

should I handle a copy of xdata/ydata and gives the updated set to

set_x/ydata() for one point?

I tried to get_data() and append to it, but It’s a MaskedArray and I

guess it means its a really bad idea to try this way.

probably a new class inheriting figure and overriding

get_data()//set_data() could do the trick?

any advice on a clean design I could use?


Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Ryan May wrote:

    Hi list,

    I'm trying to get a dynamic plot running.
    I'm stuck at feeding the data to the lines.

    basically I've a callback that receives a (y,x1,x2) tuple and I would
    like to add the 2 points to the two matplotlib.lines of the figure.

    should I handle a copy of xdata/ydata and gives the updated set to
    set_x/ydata() for one point?
    I tried to get_data() and append to it, but It's a MaskedArray and I
    guess it means its a really bad idea to try this way.

    probably a new class inheriting figure and overriding
    get_data()//set_data() could do the trick?

    any advice on a _clean_ design I could use?

You can add a value to an array using np.concatenate:

x,y = line.get_data()
x = np.concatenate((x, [x0]))
y = np.concatenate((y, [y0]))
line.set_data([x,y])

This is rather inefficient however if you're adding lots of points or if
there are just a lot of point in x any in general. If you know how many
points you're going to end up with, you could create mostly empty
MaskedArrays and keep the extra points masked until you get the data.

Ryan

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

thanks Ryan,
It does work and I'll use that for now.
the idea is to have a gkrellm-like UI in which you can monitor system
usage 'live'
I guess I could have a 'window of event', just keeping the last 1000
points and move the xlim as a window:
ax.set_xlim(xmin=currentmin+time,xmax=currentmax+time)
but something sounds plain wrong, It sounds like there's too much
useless calculations and data copied.

would it be a good idea to have an array of 1000 points and shift it
left every round to add the new point at the end?

···

On Fri, Jul 3, 2009 at 8:32 AM, guillaume ranquet <granquet@…2572… > <mailto:granquet@…2572…>> wrote:

----
This message contains confidential information and may contain information that is legally privileged. If you have received this message by mistake, please immediately notify us and delete the original message. Thank you.

Ce message contient des informations confidentielles. S'il vous est parvenu par erreur, merci de bien vouloir nous en aviser par retour, de n'en faire aucun usage et de n'en garder aucune copie.
----

I think your best bet in this case is to just keep a python list of your 1000 points around:

#Remove old point and add new one
x_list.pop(0)

x_list.append(x0)
y_list.pop(0)
y_list.append(y0)

line.set_xdata(np.array(x_list))
line.set_ydata(np.array(y_list))

Ryan

···

On Fri, Jul 3, 2009 at 12:05 PM, guillaume ranquet <granquet@…878…2572…> wrote:

Ryan May wrote:

On Fri, Jul 3, 2009 at 8:32 AM, guillaume ranquet <granquet@…2572… > > mailto:granquet@...2572...> wrote:

Hi list,
I'm trying to get a dynamic plot running.
I'm stuck at feeding the data to the lines.
basically I've a callback that receives a (y,x1,x2) tuple and I would
like to add the 2 points to the two matplotlib.lines of the figure.
should I handle a copy of xdata/ydata and gives the updated set to
set_x/ydata() for one point?
I tried to get_data() and append to it, but It's a MaskedArray and I
guess it means its a really bad idea to try this way.
probably a new class inheriting figure and overriding
get_data()//set_data() could do the trick?
any advice on a _clean_ design I could use?

You can add a value to an array using np.concatenate:

x,y = line.get_data()

x = np.concatenate((x, [x0]))

y = np.concatenate((y, [y0]))

line.set_data([x,y])

This is rather inefficient however if you’re adding lots of points or if

there are just a lot of point in x any in general. If you know how many

points you’re going to end up with, you could create mostly empty

MaskedArrays and keep the extra points masked until you get the data.

Ryan

Ryan May

Graduate Research Assistant

School of Meteorology

University of Oklahoma

thanks Ryan,

It does work and I’ll use that for now.

the idea is to have a gkrellm-like UI in which you can monitor system

usage ‘live’

I guess I could have a ‘window of event’, just keeping the last 1000

points and move the xlim as a window:

ax.set_xlim(xmin=currentmin+time,xmax=currentmax+time)

but something sounds plain wrong, It sounds like there’s too much

useless calculations and data copied.

would it be a good idea to have an array of 1000 points and shift it

left every round to add the new point at the end?


Ryan May
Graduate Research Assistant
School of Meteorology

University of Oklahoma

but something sounds plain wrong, It sounds like there's too much
useless calculations and data copied.

Well, if you think something is wrong, I guess you may have chosen a
wrong tool.
MPL is mainly for 2d plotting, and not very strong for animation
although it supports some.

would it be a good idea to have an array of 1000 points and shift it
left every round to add the new point at the end?

Shifting array should be done by numpy, not by matplotlib (I'm not
sure if numpy can do this in place). Anyhow, what actually matter is
that even if you shift the array, matplotlib will draw all the points
in the array every time.

One possible option in your case is to save your plot as an image in
each round. And at the next round, you plot the newly available data
upon the shifted image.

http://matplotlib.sourceforge.net/examples/animation/animation_blit_gtk2.html

Note that the above example requires svn version of matplotlib.

Regards,

-JJ

···

On Fri, Jul 3, 2009 at 1:05 PM, guillaume ranquet<granquet@...2572...> wrote:

Jae-Joon Lee wrote:

Well, if you think something is wrong, I guess you may have chosen a
wrong tool.
MPL is mainly for 2d plotting, and not very strong for animation
although it supports some.

I just think that I have a nice hammer, a nice nail ... and not a clue
on how to use a hammer (I'm a python noob, and high level language noob
in general, the highest level language I used before starting python was
C ... for embedded devices)
I just though that I was thinking in the wrong way.

One possible option in your case is to save your plot as an image in
each round. And at the next round, you plot the newly available data
upon the shifted image.

http://matplotlib.sourceforge.net/examples/animation/animation_blit_gtk2.html

thanks, this looks great :slight_smile:

···

----
This message contains confidential information and may contain information that is legally privileged. If you have received this message by mistake, please immediately notify us and delete the original message. Thank you.

Ce message contient des informations confidentielles. S'il vous est parvenu par erreur, merci de bien vouloir nous en aviser par retour, de n'en faire aucun usage et de n'en garder aucune copie.
----