[matplotlib-devel] improved performance for quiver

2009-06-30 Thread Ray Speth
I believe I have found a simple change that improves the rendering speed 
of quiver plots, which can be quite slow for large vector fields. Based 
on some profiling, the problem appears to stem from the use of numpy's 
MaskedArrays in PolyCollection.set_verts. If I add the following line to 
the top of the PolyCollection.set_verts function in collections.py:

verts = np.asarray(verts)

I find that quiver plots are drawn about 3 times as quickly, going from 
2.6 seconds for a 125x125 field to 0.65 seconds. This does not seem to 
break the use of MaskedArrays as inputs, and masked regions are still 
hidden in the final plot. I do not know if this has any adverse effects 
in other classes that inherit from PolyCollection.

Using:
python 2.6.2 on Windows XP
numpy 1.3.0
matplotlib 0.98.5.3, Qt4Agg backend

I do not know why iterating over MaskedArrays is so slow, but perhaps 
this information can be used to speed up some other functions as well.

Ray Speth

--
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


[matplotlib-devel] problem with scatter legend entries with dpi != 72

2010-03-13 Thread Ray Speth

Hello,

I am encountering a problem with the legend entries for scatter plots 
when setting a figure DPI different from the default of 72. When the DPI 
is higher than 72, the markers in the legend become disproportionately 
large and get scrunched together. It looks like what is happening is the 
marker size is being transformed twice, and the offsets are not being 
transformed at all.


I have tried to debug it, and it looks like the problem is the way that 
the DrawingArea that contains the legend interacts with the Collection 
object. To fix the spacing, the _transOffset property of the Collection 
needs to be set, but the transform being applied by the DrawingArea ends 
up scaling the marker size instead.


I have attached a sample script which shows the problem. I am using the 
current development version of matplotlib checked out from git, with 
Python 2.6.2. The issue also exists in version 0.99.1.


Thanks,
Ray Speth
#!/usr/bin/python
import matplotlib.pyplot as plt
import numpy as np

f = plt.figure()
f.set_dpi(200)
x = np.arange(10)
h = plt.scatter(x,-x)
g = plt.plot(x,x,'ro-')
L = plt.legend([h,g],['scatter','plot'])
#f.savefig('scatterdbg.png',dpi=200)
plt.show()
--
Download IntelĀ® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


[matplotlib-devel] Patch to extend functionality of Figure.legend

2010-03-15 Thread Ray Speth

Hello all,

I have written a small patch which extends the functionality of
Figure.legend and pyplot.figlegend to match that of Axes.legend.

This patch allows figlegend to automatically build a legend for lines 
with the "label" property set when figlegend is called without a list of 
strings or object handles.


Also, the "loc" argument is made optional, and defaults to the upper 
right, same as Axes.legend.


I hope the attached patch is suitable for inclusion. I have also 
attached a test script showing each of the call signatures.


Thanks,
Ray Speth

 lib/matplotlib/figure.py |  119 +++---
 lib/matplotlib/pyplot.py |   13 -
 2 files changed, 102 insertions(+), 30 deletions(-)

diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py
index 36fe423..8204ddd 100644
--- a/lib/matplotlib/figure.py
+++ b/lib/matplotlib/figure.py
@@ -818,33 +818,43 @@ class Figure(Artist):
 def get_axes(self):
 return self.axes
 
-def legend(self, handles, labels, *args, **kwargs):
-"""
-Place a legend in the figure.  Labels are a sequence of
-strings, handles is a sequence of
-:class:`~matplotlib.lines.Line2D` or
-:class:`~matplotlib.patches.Patch` instances, and loc can be a
-string or an integer specifying the legend location
-
-USAGE::
-
-  legend( (line1, line2, line3),
-  ('label1', 'label2', 'label3'),
-  'upper right')
-
-The *loc* location codes are::
-
-  'best' : 0,  (currently not supported for figure legends)
-  'upper right'  : 1,
-  'upper left'   : 2,
-  'lower left'   : 3,
-  'lower right'  : 4,
-  'right': 5,
-  'center left'  : 6,
-  'center right' : 7,
-  'lower center' : 8,
-  'upper center' : 9,
-  'center'   : 10,
+def legend(self, *args, **kwargs):
+"""
+call signatures::
+
+  legend()
+  legend(labels)
+  legend(loc)
+  legend(labels, loc)
+  legend(handles, labels)
+  legend(handles, labels, loc)
+
+Place a legend in the figure. *labels* is a sequence of
+strings. *handles* is a sequence of
+:class:`~matplotlib.lines.Line2D`,
+:class:`~matplotlib.patches.Patch`, or
+:class:`~matplotlib.collections.RegularPolyCollection`
+instances. If neither *labels* nor *handles* is specified,
+legend entries will be created for those line, patch, and
+collection instances with a *label* property.
+
+*loc* can be a string or an integer specifying the legend
+location. The *loc* location codes are::
+
+  ===   =
+  Location String   Location Code
+  ===   =
+  'upper right' 1
+  'upper left'  2
+  'lower left'  3
+  'lower right' 4
+  'right'   5
+  'center left' 6
+  'center right'7
+  'lower center'8
+  'upper center'9
+  'center'  10
+  ===   =
 
 *loc* can also be an (x,y) tuple in figure coords, which
 specifies the lower left of the legend box.  figure coords are
@@ -907,8 +917,61 @@ class Figure(Artist):
 
 .. plot:: mpl_examples/pylab_examples/figlegend_demo.py
 """
+if len(args)==0:
+handles = []
+labels = []
+for ax in self.get_axes():
+axhandles, axlabels = ax.get_legend_handles_labels()
+handles.extend(axhandles)
+labels.extend(axlabels)
+
+if len(handles) == 0:
+warnings.warn("No labeled objects found. "
+  "Use label='...' kwarg on individual plots.")
+return None
+
+elif len(args)==1:
+if is_string_like(args[0]) or isinstance(args[0], int):
+# LOC
+kwargs['loc'] = args[0]
+handles = []
+labels = []
+for ax in self.get_axes():
+axhandles, axlabels = ax.get_legend_handles_labels()
+handles.extend(axhandles)
+labels.extend(axlabels)
+
+else:
+# LABELS
+labels = args[0]
+handles = []
+for ax in self.get_axes():
+handles.extend(ax._get_legend_han