Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib: rotating a patch

I wanted to rotate a Rectangle in matplotlib but when I apply the transformation, the rectangle doesn't show anymore:

rect = mpl.patches.Rectangle((0.0120,0),0.1,1000)
t = mpl.transforms.Affine2D().rotate_deg(45)
rect.set_transform(t)

is this a known bug or do I make a mistake?

like image 648
Mermoz Avatar asked Nov 26 '10 12:11

Mermoz


People also ask

How do I rotate a patch in MatPlotLib?

MatPlotLib with Python To rotate the rectangle patch in a plot, we can use angle in the Rectangle() class to rotate it.

What is MatPlotLib rotation?

Text objects in matplotlib are normally rotated with respect to the screen coordinate system (i.e., 45 degrees rotation plots text along a line that is in between horizontal and vertical no matter how the axes are changed).


2 Answers

The patch in the provided code makes it hard to tell what's going on, so I've made a clear demonstration that I worked out from a matplotlib example:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib as mpl

fig = plt.figure()
ax = fig.add_subplot(111)

r1 = patches.Rectangle((0,0), 20, 40, color="blue", alpha=0.50)
r2 = patches.Rectangle((0,0), 20, 40, color="red",  alpha=0.50)

t2 = mpl.transforms.Affine2D().rotate_deg(-45) + ax.transData
r2.set_transform(t2)

ax.add_patch(r1)
ax.add_patch(r2)

plt.xlim(-20, 60)
plt.ylim(-20, 60)

plt.grid(True)

plt.show()

enter image description here

like image 70
Nick Avatar answered Nov 09 '22 23:11

Nick


Apparently the transforms on patches are composites of several transforms for dealing with scaling and the bounding box. Adding the transform to the existing plot transform seems to give something more like what you'd expect. Though it looks like there's still an offset to work out.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib as mpl
fig = plt.figure()
ax = fig.add_subplot(111)

rect = patches.Rectangle((0.0120,0),0.1,1000)

t_start = ax.transData
t = mpl.transforms.Affine2D().rotate_deg(-45)
t_end = t_start + t

rect.set_transform(t_end)

print repr(t_start)
print repr(t_end)
ax.add_patch(rect)

plt.show()
like image 43
mjhm Avatar answered Nov 10 '22 01:11

mjhm