[Rd] mtext adj= wrong with several las= (PR#7188)

Uwe Ligges ligges at statistik.uni-dortmund.de
Tue Aug 24 10:08:03 CEST 2004


Paul Murrell wrote:

> Hi
> 
> 
> Uwe Ligges wrote:
> 
>> ligges at statistik.uni-dortmund.de wrote:
>>
>>> joehl at gmx.de wrote:
>>>
>>>
>>>> Dear all,
>>>> Our quite basic function mtext() does wrong adjustments in some 
>>>> parameter
>>>> configurations. This gets obvious when using multi line texts: There 
>>>> is no
>>>> way to properly adjust text perpendicular to axis 2, for example.
>>>>
>>>> Best
>>>>
>>>>
>>>> Jens Oehlschlägel
>>>>
>>>>
>>>> m <- matrix(1:9, 3)
>>>> colnames(m) <- c("several\nlines", "several\nlines", "several\nlines")
>>>>
>>>> par(mfrow=c(2,2))
>>>> barplot(m, horiz=TRUE, axes=FALSE, axisnames=FALSE, main="las=0 
>>>> adj=0.5 is
>>>> fine")
>>>> mtext(colnames(m), 2, at=seq(0.5+0.2, by=1+0.2, length=3), las=0, 
>>>> adj=0.5)
>>>> barplot(m, horiz=TRUE, axes=FALSE, axisnames=FALSE, main="las=0 
>>>> adj=1 is
>>>> different")
>>>> mtext(colnames(m), 2, at=seq(0.5+0.2, by=1+0.2, length=3), las=0, 
>>>> adj=1)
>>>> barplot(m, horiz=TRUE, axes=FALSE, axisnames=FALSE, main="las=1 
>>>> adj=0.5 is
>>>> NOT fine")
>>>> mtext(colnames(m), 2, at=seq(0.5+0.2, by=1+0.2, length=3), las=1, 
>>>> adj=0.5)
>>>> barplot(m, horiz=TRUE, axes=FALSE, axisnames=FALSE, main="at las=1, 
>>>> adj=1
>>>> works the wrong direction", sub="no way to get adj=c(1, 0.5) with 
>>>> las=1 (or
>>>> 2)")
>>>> mtext(colnames(m), 2, at=seq(0.5+0.2, by=1+0.2, length=3), las=1, 
>>>> adj=1)
>>>> par(mfrow=c(1,1))
>>>>
>>>
>>>
>>> Left / right adjustemnt seems to be perfectly OK.
>>> The thing that matters is centering "several lines" to the specified 
>>> ("at=") location.
>>> In fact, mtext() is not centering but bottom-aligning by adding a 
>>> negative distance that looks OK for one line in the default font 
>>> size, but not in most other cases.
>>>
>>> Hence this is the same as Paul Murrell's PR#1659 ("mtext() alignment 
>>> of perpendicular text"). Fixing this, and/or improving mtext()'s 
>>> "adj" argument to accept 2 dimensions is desirable, but might be not 
>>> that easy... I'll take a look during the next days, but nothing 
>>> promised.
>>>
>>> Uwe Ligges
>>
>>
>>
>>
>> Having looked into the code, there are three possible solution (all with
>> some drawbacks) I can see. Well, the current argument "adj" becomes
>> "xadj" in the C sources (graphics.c, GMtext), and "yadj" is set to 0. 
>> Hence the ugly hard coded LineBias of 0.3.
>>
>>
>> Solutions
>> =========
>> 1: Hardcode "yadj" to 0.5 and remove all those 0.3 biases. Looks good 
>> for axes, but it might break some code --> bad.
>> On the other hand, GMMathText has hardcoded yadj=0.5. Is there a 
>> problem with some special devices? Or any other reason not to center 
>> stuff using "adj=0.5"?
>>
>> 2: Allow the typical 2-value adj, take the first as xadj, the second one
>> as yadj. This might break some code, because currently adj of
>> arbitrary length (!=0) is allowed and recycled.
>>
>> 3: Invent an argument "padj" for mtext() that represents adjustment
>> *p*erpendicular to the text direction and gets mapped to "yadj" in
>> GMtext. In that case the hardcoded 0.3 bias mentioned above can be
>> removed. The question is whether to set the default to 0.5 (will still
>> break code, but easily to fix by setting padj to 0).
>>
>> I'd like to propose the third solution and would be happy to provide a
>> patch of GMText, including corresponding patches to GMMathText, as 
>> well as mtext(), title() and axis() (and their inderlying do_* 
>> components).
>>
>> Are there any objections? Any reasons not to do it?
> 
> 
> 
> It hurts my head to think about this stuff.  There are so many 
> combinations to worry about:
> (i)   The las setting
> (ii)  The axis (bottom, left, top, right)
> (iii) Whether adj has been specified
> (iv)  Whether the text is multi-line
> 
> I think mtext() does ok as long as adj is not specified and the text is 
> single-line.

Unfortunately it does *not* (using axis() here for simplicity):
   plot(1:10)
   axis(3, cex.axis=5, las=2)


> I would suggest addressing the multi-line problem for unspecified adj as 
> a first step.  And I will definitely not mourn the passing of the 0.3 
> constant.  Setting yadj to 0.5 is not enough though because that doesn't 
> make sense for multi-line text that is parallel to an axis (in that 
> case, yadj should probably be 0 for axis 2 and 3 and 1 for axis 1 and 4; 
>  did I mention that there are lots of combinations to worry about?).

I think most of the stuff is already quite pretty.
The point is whether we are going to distinguish cases for 
(p)adj={0,0.5,1} automatically or not. If the latter, we can omit 
several of the cases mentioned above in (i)-(iv).
I think - as the first step - we should set the default to center (note 
that text() does so as well), and let the user change padj for 
multi-line text as required.

I'll try to provide a collection of patches as a proposal within, say, 
two weeks.

Uwe


> For user-specified adj, I agree that a 2-value adj is not a good 
> solution (adj is assumed to be horizontal adjustment) so maybe a padj 
> would be best to allow user control of vertical alignment.
 >
> Paul



More information about the R-devel mailing list