"Paul Smith" <[EMAIL PROTECTED]> writes:
> I've been looking around for any info how one might go about
> rotating patches, such as Rectangles, by a user supplied angle. The
> transform module/affine class mention this but I'm struggling with
> how to actually use them this way (LazyValues?) and haven't found an
> example to illustrate it yet.
I thought this would be easy, but I can't quite get it to work.
Perhaps there is a bug in my code, or perhaps we need someone more
knowledgeable in matplotlib transformations to explain the right
way to do this.
One problem is that the angles of the resulting "rectangle" don't
quite look like right angles; another is that because the
transformation is divorced from ax.transData, panning and zooming
have no effect on the rectangle.
#!/usr/bin/env python
import math
import matplotlib
from matplotlib.transforms import Affine, multiply_affines, \
translation_transform, Value, zero
from matplotlib.patches import Rectangle
import pylab
# First build a figure
fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot([0,1,2,3,4,5,6,7,8,9],'o')
ax.set_aspect('equal')
# Where we want the rectangle
x,y,w,h = 2,5,2,2
# How much to rotate
angle = math.pi/3
# We will rotate around the center
cx,cy = x+w/2.0,y+h/2.0
# Rotation:
cos = Value(math.cos(angle))
sin = Value(math.sin(angle))
rotate = Affine(cos, zero()-sin, sin, cos, zero(), zero())
# Rotate around center:
to_origin = translation_transform(Value(-cx),Value(-cy))
and_back = translation_transform(Value(cx),Value(cy))
trans = multiply_affines(multiply_affines(and_back,rotate),to_origin)
# The transformation must be combined with ax.transData,
# but that is not an Affine...
origin, unit = map(ax.transData.xy_tup, [(0,0),(1,1)])
scalex, scaley = unit[0]-origin[0], unit[1]-origin[1]
transData = Affine(Value(scalex), zero(), zero(), Value(scaley),
Value(origin[0]), Value(origin[1]))
final_trans = multiply_affines(transData,trans)
rec = Rectangle((x,y),w,h,ec=[1,0,0],fc=[0,1,.7],lw=2,
transform=final_trans)
ax.add_patch(rec)
pylab.show()
(Some patches have built-in support: Ellipse takes an 'angle' in
degrees, and RegularPolygon a 'rotation' in radians.)
> Also is there a way to use normalised coordinates rather than data
> for positioning patches? I'd like it to appear in the same place
> (lower right) without having to adjust if the plot scaling changes.
Use transAxes:
http://www.scipy.org/Cookbook/Matplotlib/Transformations
--
Jouni
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users