Update values of errorbars

Dear mpl users,
I have the following problem to solve. Imagine to have the simple example reported on website plotting the errorbars of some x,y data:

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt

# example data
x = np.arange(0.1, 4, 0.5)
y = np.exp(-x)

# example variable error bar values
yerr = 0.1 + 0.2*np.sqrt(x)
xerr = 0.1 + yerr

# First illustrate basic pyplot interface, using defaults where possible.
plt.figure()
plt.errorbar(x, y, xerr=0.2, yerr=0.4)

···

================================================
Now I change the last line into:

p = plt.errorbar(x, y, xerr=0.2, yerr=0.4)

and if I change, for instance, y:

y = y/2.

I can easily replace the x,y with:

p[0].set_data(x,y)

but I do not know how to do the same for the errorbars.

I need to do this as I am implementing a code with a GUI written in PyQt4, and I need to quickly replot some data.

Can anyone help me?

Many thanks in advance

Gianfranco Durin

From: Gianfranco Durin [mailto:g.durin@…3344…]
Sent: Wednesday, November 10, 2010 11:32

Dear mpl users,
I have the following problem to solve. Imagine to have the
simple example reported on website plotting the errorbars of
some x,y data:

...

and if I change, for instance, y:

y = y/2.

I can easily replace the x,y with:

p[0].set_data(x,y)

but I do not know how to do the same for the errorbars.

I believe I see how you could do it. The errorbar call returns the tuple p =
(plotline, caplines, barlinecols) [1], and to update the errorbars, you must
modify the objects in the caplines and barlinecols lists. Each element of the
caplines list is a Line2D artist [2] for the left, right, top, or bottom caps;
you can use its methods set_data, set_xdata, or set_ydata to modify its
coordinates, as you did for the main line. Each element of the barlinecols
list is a LineCollection [3] artist responsible for all of the x or y
errorbars; you can use the set_segments method to provide new coordinates.

[1]
http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.Axes.error
bar
[2]
http://matplotlib.sourceforge.net/api/artist_api.html#matplotlib.lines.Line2D
[3]
http://matplotlib.sourceforge.net/api/collections_api.html#matplotlib.collecti
ons.LineCollection

Thanks Stan,
with your suggestion I was able to solve the problem, even if it is not immediate (but not too long). This is what I did:

plotline, caplines, barlinecols = plt.errorbar(x, y, yerr, xerr)

# Now move the line
y = y/2.

# Replot the data first
plotline.set_data(x,y)

# Find the ending points of the errorbars
error_positions = (x-xerr,y), (x+xerr,y), (x,y-yerr), (x,y+yerr)

# Update the caplines
for i,pos in enumerate(error_positions):
     caplines[i].set_data(pos)

# Update the error bars
barlinecols[0].set_segments(zip(zip(x-xerr,y), zip(x+xerr,y)))
barlinecols[1].set_segments(zip(zip(x,y-yerr), zip(x,y+yerr)))

The last lines are a little clumsy, but I could not find a better way. Anyway, it could be nice to have a method like set_errorbar(x, y, yerr, xerr) to do the job.

Many thanks again

Gianfranco

···

On 11/16/2010 07:41 PM, Stan West wrote:

I believe I see how you could do it. The errorbar call returns the tuple p =
(plotline, caplines, barlinecols) [1], and to update the errorbars, you must
modify the objects in the caplines and barlinecols lists. Each element of the
caplines list is a Line2D artist [2] for the left, right, top, or bottom caps;
you can use its methods set_data, set_xdata, or set_ydata to modify its
coordinates, as you did for the main line. Each element of the barlinecols
list is a LineCollection [3] artist responsible for all of the x or y
errorbars; you can use the set_segments method to provide new coordinates.

[1]
http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.Axes.errorbar
[2]
http://matplotlib.sourceforge.net/api/artist_api.html#matplotlib.lines.Line2D
[3]
http://matplotlib.sourceforge.net/api/collections_api.html#matplotlib.collections.LineCollection
   

--

Istituto Nazionale di Ricerca Metrologica (I.N.Ri.M)
(former Istituto Elettrotecnico Nazionale Galileo Ferraris)
Strada delle Cacce, 91 - 10135 Torino Italy
tel: ++39 011 3919839 fax: ++39 011 3919834
Personal home page: http://www.inrim.it/~durin/
INRiM home pag: http://www.inrim.it/

Please note my new e-mail: g.durin@...3344...

From: G. Durin [mailto:g.durin@…3344…]
Sent: Tuesday, November 23, 2010 08:34

<snip>

# Update the error bars
barlinecols[0].set_segments(zip(zip(x-xerr,y), zip(x+xerr,y)))
barlinecols[1].set_segments(zip(zip(x,y-yerr), zip(x,y+yerr)))

The last lines are a little clumsy, but I could not find a
better way.

I'm glad you were able to solve your problem. An alternative to the above
lines is

    barlinecols[0].set_segments(
            np.array([[x - xerr, y],
                      [x + xerr, y]]).transpose((2, 0, 1)) )

and likewise for y. The transposition produces a depth stack of 2-by-2
arrays.