Hello everyone,
Hello John,
as you advised in a Mail some days ago concerning a fastplot-command I wrote
a polygon_factory and it worked quite well (In large parts taken from
Line2D). See the code attached.
What I now want to ask you is:
Would it be good to write this object-oriented (propably yes, so one gets
rid of all those tiny funktions _make_...(size))? One drawback which comes
into my mind is: How should this class be used within fastplot()? Initialize
an instance each time you plot a single point? Wouldn't this slow down
everything a bit (or am I overestimating the time-scales)?
On the otherhand using a class would look very 'tidy'.
Thanks for your suggestion.
Bye,
Martin
···
#--------------------------------------------------------------------
""" A routine which uses blitting so that it is possible to plot
seperate markers faster than usual.
"""
from pylab import *
import time # for profiling
#--------------------------------------------------------------------
from matplotlib.lines import Line2D
from matplotlib.transforms import identity_transform, lbwh_to_bbox
from Numeric import pi
def _make_point(size):
size *= .5
if size <= 0.5:
return _make_pixel()
elif size <= 2:
return _make_hexagon1(size, point=True)
else:
return _make_circle(size, point=True)
def _make_pixel():
return ((-0.5, -0.5),
(-0.5, 0.5),
( 0.5, 0.5),
( 0.5, -0.5))
def _make_circle(size, point=False):
if point:
size *= .5
N = 50.0
r = size/2.0
rads = (2*pi/N)*arange(N)
xs = r*cos(rads)
ys = r*sin(rads)
verts = [(xs[0], ys[0])]
for x, y in zip(xs[1:], ys[1:]):
verts.append((x, y))
return tuple(verts)
def _make_triangle_up(size):
return (( 0, size),
(-size, -size),
( size, -size))
def _make_triangle_down(size):
return ((-size, size),
( size, size),
( 0, -size))
def _make_triangle_left(size):
return ((-size, 0),
( size, -size),
( size, size))
def _make_triangle_right(size):
return (( size, 0),
(-size, -size),
(-size, size))
def _make_tri_down(size):
size1 = size*0.8
size2 = size*0.5
return ((-size1, size2),
( 0, 0),
( size1, size2),
( 0, 0)
( 0, -size)
( 0, 0))
def _make_tri_up(size):
size1 = size*0.8
size2 = size*0.5
return ((-size1, -size2),
( 0, 0),
( size1, -size2),
( 0, 0),
( 0, size),
( 0, 0))
def _make_tri_left(size):
size1 = size*0.8
size2 = size*0.5
return ((size2, -size1),
( 0, 0),
(size2, size1),
( 0, 0),
(-size, 0),
( 0, 0))
def _make_tri_right(size):
size1 = size*0.8
size2 = size*0.5
return ((-size2, -size1),
( 0, 0),
(-size2, size1),
( 0, 0),
( size, 0),
( 0, 0))
def _make_square(size):
return ((-size, -size),
(-size, size),
( size, size),
( size, -size))
def _make_diamond(size):
return (( size, 0),
( 0, -size),
(-size, 0),
( 0, size))
def _make_thin_diamond(size):
xsize = 0.6*size
return (( xsize, 0),
( 0, -size),
(-xsize, 0),
( 0, size))
def _make_pentagon(size):
sizeX1 = size*0.95
sizeY1 = size*0.31
sizeX2 = size*0.59
sizeY2 = size*0.81
return (( 0, size),
(-sizeX1, sizeY1),
(-sizeX2, -sizeY2),
( sizeX2, -sizeY2),
( sizeX1, sizeY1))
def _make_hexagon1(size, point=False):
if point:
size *= .5
sizeX1 = size*0.87
sizeY1 = size*0.5
return (( 0, size),
(-sizeX1, sizeY1),
(-sizeX1, -sizeY1),
( 0, -size),
( sizeX1, -sizeY1),
( sizeX1, sizeY1))
def _make_hexagon2(size):
sizeX1 = size*0.5
sizeY1 = size*0.87
return (( size, 0),
( sizeX1, sizeY1),
(-sizeX1, sizeY1),
( -size, 0),
(-sizeX1, -sizeY1),
( sizeX1, -sizeY1))
def _make_plus(size):
return ((-size, -size),
( size, size),
( 0, 0),
( size, -size),
(-size, size),
( 0, 0))
def _make_x(size):
return ((-size, 0),
( size, 0),
( 0, 0),
( 0, -size),
( 0, size),
( 0, 0))
def _make_vline(size):
return ((0, -size),
(0, size))
def _make_hline(size):
return ((-size, 0),
( size, 0))
markerd = {
'.' : _make_point,
',' : _make_pixel,
'o' : _make_circle,
'v' : _make_triangle_down,
'^' : _make_triangle_up,
'<' : _make_triangle_left,
'>' : _make_triangle_right,
'1' : _make_tri_down,
'2' : _make_tri_up,
'3' : _make_tri_left,
'4' : _make_tri_right,
's' : _make_square,
'p' : _make_pentagon,
'h' : _make_hexagon1,
'H' : _make_hexagon2,
'+' : _make_plus,
'x' : _make_x,
'D' : _make_diamond,
'd' : _make_thin_diamond,
'|' : _make_vline,
'_' : _make_hline
}
def polygon_factory(ax, marker, size, args, **kwargs):
""" This function creates a Polygon-instance having a shape
according to the given marker. This instance is located at
the position specified by the args (containing two
floats x and y).
"""
func = markerd[marker]
renderer = ax.get_renderer_cache()
verts = func(size = 1.0*renderer.points_to_pixels(int(size)))
trans = identity_transform()
trans.set_offset( (args[0], args[1]), ax.transData)
poly = Polygon( verts, transform=trans, **kwargs )
poly.set_clip_box(ax.bbox)
return poly
def fastplot_points(*args, **kwargs):
"""This program tries to enable a routine 'fastplot' using
JDH's method of reblitting only a small region around
the new object.
Notice: args have to be (x, y) and not ([x], [y])
like for plot().
You can select the markers with the keyword marker = 'h'
for example.
To change their color use
facecolor = 'g' or fc = 'g'
and
edgecolor = 'b' or ec = 'b' respectivly.
To vary their size use either ms = 4.5 or markersize = 4.5.
For a change of the markeredgewidth use
markeredgewith, mew, linewidth or lw
(If more of them are given they are respected in this order)
Also all other kwargs can be used (antialiased, alpha, ...)
"""
ax = gca()
trans = identity_transform()
trans.set_offset(args, ax.transData)
marker = kwargs.pop('marker', 'o') # which marker is desired
# (default:'o')?
msize = kwargs.pop('markersize', kwargs.pop('ms', 6))
# filter out the desired size
# (If both kwargsare given
# 'markersize' is prefered.)
lw = kwargs.pop('markeredgewidth',
kwargs.pop('mew',
kwargs.pop('linewidth',
kwargs.pop('lw', .5))))
# filter out the desired
kwargs.update({'lw':lw}) # edgewidth
p = polygon_factory(ax, marker, msize, args, **kwargs)
p.set_clip_box(ax.bbox)
l,b,w,h = p.get_window_extent().get_bounds()
pad = 3
bbox = lbwh_to_bbox(l-pad, b-pad, w+2*pad, h+2*pad)
ax.draw_artist(p)
ax.figure.canvas.blit(bbox)
#-------------------------------------------------------------------
n=300
phi=2.0*pi*arange(n)/n
x=cos(phi)
y=sin(phi)
ion()
figure(1)
subplot(111, autoscale_on=False)
tstart = time.time()
title('point by point with blitting')
axis([-1,1,-1,1])
axis('scaled')
for i in xrange(n): # plot all data step by step
fastplot_points( x[i], y[i],marker='o', fc = 'b')
tend = time.time()
t_fast = tend - tstart
close(1)
ioff()
print " It took %6.2f s."%(t_fast)
#-------------------------------------------------------------------
--
5 GB Mailbox, 50 FreeSMS http://www.gmx.net/de/go/promail
+++ GMX - die erste Adresse f�r Mail, Message, More +++