[R] Draw text with a box surround in plot.
Peter Ehlers
ehlers at ucalgary.ca
Thu Jun 10 01:18:46 CEST 2010
Maybe this can be display-dependent. I just measured
the two diagonals on the plot and they're equal to
within less than one mm (possibly closer but that
was the accuracy of my measuring device (pencil and
strip of paper)).
-Peter Ehlers
On 2010-06-09 16:57, guox at ucalgary.ca wrote:
> For me, the angles circled are not exactly right.
> See the pdf file: plot.pdf.
> But it is OK.
> Thanks Peter for your directions
> -james
>> On 2010-06-09 14:17, guox at ucalgary.ca wrote:
>>> Thank.
>>> Better. Seems that angles are close to but not equal to pi/2.
>>> It may be because the plot box is not a square: the length of
>>> x-axis is not the same as the length of y-axis.
>>> Even curves y = x and y = 1-x look like not orthogonal but
>>> they should since multiplication of their slopes is -1.
>>> -james
>>
>>
>> I disagree. Your eyes may be fooling you. Setting asp=1 ensures
>> that intervals (x1,x2)=(a,b) and (y1,y2)=(a,b) are of equal
>> length on the plot. (This seems to hold even if you resize
>> the plot after drawing.)
>>
>> Try removing the box around the plot:
>>
>> plot(0:30, 0:30, type='n', asp=1, axes=FALSE, xlab="", ylab="")
>> abline(v=c(0,30), h=c(0,30))
>> abline(a=0, b=1, col=2)
>> abline(a=30, b=-1, col=4)
>> polygon(c(x1,x2,x3,x4), c(y1,y2,y3,y4), border="blue", lwd=2)
>> polygon(x.rotated, y.rotated, border="red", lwd=2)
>>
>> Works for me.
>>
>> -Peter Ehlers
>>
>>
>>> plot(1:30,1:30,xlim=c(1,30),ylim=c(1,30),type="n", main = "Rotated
>>> rectangle looks like a parallelogram", asp=1)
>>> ## a rect at (10,20) with w = 3 and h = 2
>>> x = 10
>>> y = 20
>>> w = 3
>>> h = 2
>>> x1=x-w
>>> y1=y-h
>>> x2=x+w
>>> y2=y-h
>>> x3=x+w
>>> y3=y+h
>>> x4=x-w
>>> y4=y+h
>>> polygon(c(x1,x2,x3,x4),c(y1,y2,y3,y4),border="blue")
>>>
>>> ##Rotate it at (10,20) by 45 degree
>>> theta = 45/180*pi
>>> x.rotated = c(10 + (x1-10)*cos(theta)-(y1-20)*sin(theta),
>>> 10 + (x2-10)*cos(theta)-(y2-20)*sin(theta),
>>> 10 + (x3-10)*cos(theta)-(y3-20)*sin(theta),
>>> 10 + (x4-10)*cos(theta)-(y4-20)*sin(theta))
>>> y.rotated = c(20 + (x1-10)*sin(theta)+(y1-20)*cos(theta),
>>> 20 + (x2-10)*sin(theta)+(y2-20)*cos(theta),
>>> 20 + (x3-10)*sin(theta)+(y3-20)*cos(theta),
>>> 20 + (x4-10)*sin(theta)+(y4-20)*cos(theta))
>>>
>>> polygon(x.rotated,y.rotated,border="red")
>>>
>>>> Your transformation assumes that the x- and y-axes are on the
>>>> same scale. Add 'asp = 1' to your plot() call to set the
>>>> appropriate aspect ratio.
>>>>
>>>> -Peter Ehlers
>>>>
>>>>
>>>> On 2010-06-09 10:13, guox at ucalgary.ca wrote:
>>>>> Rectangle R centered at (x,y) with width 2w and height 2h is given by
>>>>>
>>>>> x1=x-w
>>>>> y1=y-h
>>>>> x2=x+w
>>>>> y2=y-h
>>>>> x3=x+w
>>>>> y3=y+h
>>>>> x4=x-w
>>>>> y4=y+h
>>>>> polygon(c(x1,x2,x3,x4),c(y1,y2,y3,y4))
>>>>>
>>>>> Rotating a point (u,v) at (0,0) by theta degree is given by matrix
>>>>> [cos(theta),-sin(theta)
>>>>> sin(theta),cos(theta)]
>>>>> so we have a new point
>>>>> (u*cos(theta)-v*sin(theta),u*sin(theta)+v*cos(theta)).
>>>>>
>>>>> Hence rotated R by theta at (x,y) is given by
>>>>>
>>>>> x.rotated = c(x + (x1-x)*cos(theta)-(y1-y)*sin(theta),
>>>>> x + (x2-x)*cos(theta)-(y2-y)*sin(theta),
>>>>> x + (x3-x)*cos(theta)-(y3-y)*sin(theta),
>>>>> x + (x4-x)*cos(theta)-(y4-y)*sin(theta))
>>>>> y.rotated = c(y + (x1-x)*sin(theta)+(y1-y)*cos(theta),
>>>>> y + (x2-x)*sin(theta)+(y2-y)*cos(theta),
>>>>> y + (x3-x)*sin(theta)+(y3-y)*cos(theta),
>>>>> y + (x4-x)*sin(theta)+(y4-y)*cos(theta))
>>>>>
>>>>> polygon(x.rotated,y.rotated)
>>>>>
>>>>> But it turns out to be a parallelogram with angles not equal to 90,
>>>>> not a rectangle. See R code below.
>>>>>
>>>>> Any way to improve this so that the rotated rectangle looks like a
>>>>> rectangle? Thanks,
>>>>>
>>>>> -james
>>>>>
>>>>>
>>>>> plot(1:10,1:10,xlim=c(1,20),ylim=c(1,40),type="n", main = "Rotated
>>>>> rectangle looks like a ")
>>>>> ## a rect at (10,20) with w = 3 and h = 2
>>>>> x = 10
>>>>> y = 20
>>>>> w = 3
>>>>> h = 2
>>>>> x1=x-w
>>>>> y1=y-h
>>>>> x2=x+w
>>>>> y2=y-h
>>>>> x3=x+w
>>>>> y3=y+h
>>>>> x4=x-w
>>>>> y4=y+h
>>>>> polygon(c(x1,x2,x3,x4),c(y1,y2,y3,y4),border="blue")
>>>>>
>>>>> ##Rotate it at (10,10) by 45 degree
>>>>> theta = 45/180*pi
>>>>> x.rotated = c(10 + (x1-10)*cos(theta)-(y1-20)*sin(theta),
>>>>> 10 + (x2-10)*cos(theta)-(y2-20)*sin(theta),
>>>>> 10 + (x3-10)*cos(theta)-(y3-20)*sin(theta),
>>>>> 10 + (x4-10)*cos(theta)-(y4-20)*sin(theta))
>>>>> y.rotated = c(20 + (x1-10)*sin(theta)+(y1-20)*cos(theta),
>>>>> 20 + (x2-10)*sin(theta)+(y2-20)*cos(theta),
>>>>> 20 + (x3-10)*sin(theta)+(y3-20)*cos(theta),
>>>>> 20 + (x4-10)*sin(theta)+(y4-20)*cos(theta))
>>>>>
>>>>> polygon(x.rotated,y.rotated,border="red")
>>>>>
>>>>>
>>>>>> On 06/04/2010 01:21 AM, guox at ucalgary.ca wrote:
>>>>>>> boxed.labels draw text with box well.
>>>>>>> But, the box cannot be shadowed and srt = 45 seems not to work:
>>>>>>> text is rotated but the box does not.
>>>>>>> polygon.shadow can rotate and shadow but have to calculate its
>>>>>>> dimensions,
>>>>>>> based on the text length and size.
>>>>>>> Do you have any other way to draw text with rotated and shadowed
>>>>>>> box?
>>>>>>
>>>>>> The srt argument was intended to allow the user to rotate the text
>>>>>> in
>>>>>> 90
>>>>>> degree increments, and the box just changes shape to fit whatever is
>>>>>> in
>>>>>> it. The underlying function that draws the box (rect) doesn't have a
>>>>>> rotation argument. It would be possible to write a special function
>>>>>> using polygon, just do the calculations for box size and then rotate
>>>>>> the
>>>>>> text with srt= and the polygon by transforming the coordinates of
>>>>>> the
>>>>>> vertices, as long as the default justification (center) is used. I
>>>>>> can't
>>>>>> do this right at the moment, but if you are really stuck I might be
>>>>>> able
>>>>>> to do it in the near future.
>>>>>>
>>>>>> Jim
>>>>>>
>>>>>>
More information about the R-help
mailing list