Performance problems plotting several lines

Hi,

I have some performance problems when plotting several lines and would
appreciate some comments. My application plots lots of lines (~5000)
of different sizes. The performance bottleneck lies in the following
code snippet:

for s in data.layout.segment:
    x = []
    y = []
    for p in s.part:
        for px, py in p.curve_points():
            x.append(px)
            y.append(py)
    axes.plot(x, y, 'g', label = '_nolegend_')

Profiling showed that half of the time was spent in parsing the plot
arguments and most of the other half was spent in
Axes._set_artist_props.

I could speed up the application by using Line2D and
Axes.add_lines. But the only way to come around the time spent in
Axes._set_artist_props that I could come up with is this ugly hack
where I only call Axes.add_line for the first line and after that use
copies that are added directly to Axes.lines.

org_line = None
for s in data.layout.segment:
    x = []
    y = []
    for p in s.part:
        for px, py in p.curve_points():
            x.append(px)
            y.append(py)
    if not org_line:
        org_line = matplotlib.lines.Line2D(numpy.array(x), numpy.array(y),
                                           color='green', label = '_nolegend_')
        axis.add_line(org_line)
    else:
        line = copy.copy(org_line)
        line.set_xdata(numpy.array(x))
        line.set_ydata(numpy.array(y))
        axis.lines.append(line)

Is there a cleaner way to do this?

Also, my feelings is that matplotlib 1.0 is slower with my original
code than previous version. But I have no numbers to back it up with.

regards
Ulf Larsson

Use a LineCollection:

http://matplotlib.sourceforge.net/search.html?q=codex+linecollection

JDH

···

On Wed, Aug 4, 2010 at 9:42 AM, Ulf Larsson <ulf.j.larsson@...32...> wrote:

Hi,

I have some performance problems when plotting several lines and would
appreciate some comments. My application plots lots of lines (~5000)
of different sizes. The performance bottleneck lies in the following
code snippet:

for s in data.layout.segment:
x = []
y = []
for p in s.part:
for px, py in p.curve_points():
x.append(px)
y.append(py)
axes.plot(x, y, 'g', label = '_nolegend_')

Profiling showed that half of the time was spent in parsing the plot
arguments and most of the other half was spent in
Axes._set_artist_props.

I could speed up the application by using Line2D and
Axes.add_lines. But the only way to come around the time spent in
Axes._set_artist_props that I could come up with is this ugly hack
where I only call Axes.add_line for the first line and after that use
copies that are added directly to Axes.lines.

org_line = None
for s in data.layout.segment:
x = []
y = []
for p in s.part:
for px, py in p.curve_points():
x.append(px)
y.append(py)
if not org_line:
org_line = matplotlib.lines.Line2D(numpy.array(x), numpy.array(y),
color='green', label = '_nolegend_')
axis.add_line(org_line)
else:
line = copy.copy(org_line)
line.set_xdata(numpy.array(x))
line.set_ydata(numpy.array(y))
axis.lines.append(line)

Is there a cleaner way to do this?

Is there a cleaner way to do this?

Use a LineCollection:

http://matplotlib.sourceforge.net/search.html?q=codex+linecollection

JDH

Exactly what I was looking for. Thank you.

/Ulf Larsson