TalkingQuickly
TalkingQuickly

Reputation: 548

Rotation of patches in matplotlib not functioning as expected

I am trying to overlay a rotated rectangle onto a matplotlib chart. I have the following code:

    fig = Figure((3.8, 3.4))
    subp = fig.add_subplot(111)
    
    fig.axes[0].set_autoscale_on(False)
    fig.axes[0].set_ylim([float(self.getConfig('GUI', 'chartmin', '-1')),float(self.getConfig('GUI', 'chartmax','4' ))])
    fig.axes[0].set_xlim([dataSet[0][2]/1000,dataSet[-1][2]/1000])
    fig.axes[0].yaxis.grid(True, which='major') 
    
    timevals = []
    dataPoints = []

#timevals and datapoints are then populated and added to chart correctly, code removed for easier reading

    subp.plot(timevals, dataPoints)
    rect = matplotlib.patches.Rectangle( ((dataSet[0][2]/1000)+3,0), width=1.5, height=3, alpha=0.50)
    rect2 = matplotlib.patches.Rectangle( ((dataSet[0][2]/1000)+3,0), width=1.5, height=3, color="red", alpha=0.50)
    
    t_start = subp.transData
    t = matplotlib.transforms.Affine2D().rotate_deg(-45)
    t_end = t_start + t  
    rect.set_transform(t_end)
    subp.add_patch(rect)
    subp.add_patch(rect2)

dataSet[0][2]/1000)+3 gives the start of the charts time series + 3 seconds

The chart which is being generated has y values of between 0 and 4 and x values can be anything (it's a force (y) against time (x) plot).

The output from the above was intended to be that rect2 (the blue one) would be the same as rect (the red one) but rotated by 45 degrees. What I actually get is this:

Which is a 45 degree rotation as expected but also a translation, I've tried rotate_deg_around(0,0,-45) but this doesn't seem to help. Can anyone see what I'm doing wrong here or am I misunderstanding how rotate works?

Upvotes: 1

Views: 4349

Answers (1)

Ferdinand Beyer
Ferdinand Beyer

Reputation: 67197

By default, rotations are defined with respect to the origin. You don't want to rotate the blue rectangle around the origin, but around its center point. This is the same as first translating it so that its center lies on the origin, performing the rotation, then translating it back.

Fortunately, matplotlib has a handy function to make your life easier: rotate_deg_around(x, y, degrees). Just pass the center of your rectangle and you should be fine.

Upvotes: 6

Related Questions