[R] font size relative to graphic
Mike Miller
mbmiller+l at gmail.com
Thu Apr 30 20:01:58 CEST 2009
In my particular situation, the trick was to figure out what worked for
one set of bars, then determine how bar widths changed when various
graphing parameters changed. Then I used that information to decide on a
"cex" (character expansion) multiplier that worked perfectly for every
example I produced (this was called "bar_cex" in my R code, which is shown
below).
There are a couple of neat things about the horizontal bar plot that
everyone can use in choosing their cex. First, when there are n sets of m
bars per set, then the vertical distance from the lower side of the bottom
bar to the top side of the top bar is divided into n*(m+1)-1 equal-height
regions and every bar width (vertical distance for horizontal bars, used
to determine character height) is 1/(n*(m+1)-1) times that total vertical
distance. So just find the right cex for one set of bars, say n=3, m=2,
so that n*(m+1)-1 = 7, then use bar_cex = cex*7/(n*(m+1)-1) for other
values of n and m.
In my situation, using pdf with letter paper, height=11, width=8.5, I also
used a variable number of inches empty on the top of the page. I called
that number of inches "top_inches". I then figured out the correct cex
when the plot height was at a max of .78 and used (.78-top_inches/11) to
figure cex for other values of top_inches. After a little arithmetic I
came up with the equation appended below for bar_cex. It works for me,
but it won't work for other people. This probably will work for other
situations:
bar_cex <- C/(n*(m+1)-1)
Where an appropriate value of C that works for one collection of
horizontal bars (n sets of m bars per set) will work for other sets of
bars.
Mike
bar_cex <- (51/(n*(m+1)-1))*(.78-top_inches/11)
# generate the horizontal bar plot and store values for later use
x.bar.plot <- barplot(as.matrix(x), col=rep(rev(bar.colors[1:m]),n), horiz=TRUE,
beside=TRUE, xlim=c(0,100), main=bar.main.title,
xlab=bar.x.label, las=1, cex.names=min( c(1, 16/L) ),
legend=labels.legend)
# add numbers to bars
text(as.matrix(x), x.bar.plot-.1, as.character(as.matrix(round(x))), pos=2,
offset=0.1, col="black", cex=bar_cex)
If I don't subtract .1 from x.bar.plot, the text is positioned too high
(vertically) on the horizontal bar.
On Fri, 24 Apr 2009, David Winsemius wrote:
>
> On Apr 24, 2009, at 4:10 PM, Mike Miller wrote:
>
>> On Fri, 24 Apr 2009, David Winsemius wrote:
>>
>>> On Apr 24, 2009, at 3:14 PM, Mike Miller wrote:
>>>
>>>> I am printing numbers onto horizontal bars in a bar plots, but I am
>>>> finding it difficult to make the number always the right size. If there
>>>> are more bars, the bars get narrower and the font is too big. I also
>>>> find that if I change the size of the graph, the bars will get wider or
>>>> narrower and the font stays about the same size. The result depends on
>>>> whether I view the graph in X11 or in postscript.
>>>> Is there a way to specify font size relative to bar width, or at least
>>>> specify font size relative to graph coordinates?
>>>> Here's a bit of what I've been doing:
>>>> x.bar.plot <- barplot(as.matrix(x), horiz=TRUE, beside=TRUE,
>>>> xlim=c(0,100), xlab="Score", las=1)
>>>> text(as.matrix(x), x.bar.plot-.07, as.character(as.matrix(round(x))),
>>>> pos=2, col="black")
>>>> The "-.07" is something I added to make the numbers align well with the
>>>> bars under one condition, but it doesn't always help.
>>>> Any tips would be greatly appreciated. Thanks in advance.
>>>
>>> The values returned from the barplot function are the locations of the
>>> bars. Why not call barplot, collect the values, and then use the length of
>>> the result to determine your sizes and widths?
>>
>> That is exactly the kind of thing I want to do, but I don't know how the
>> font size can be specified so that it fits. My bars are horizontal and
>> yours (from code below) are vertical. Your barplot output was called "mp"
>> and mine was called "x.bar.plot" and here is what they looked like:
>>
>>> mp
>> [,1] [,2] [,3] [,4] [,5]
>> [1,] 1.5 6.5 11.5 16.5 21.5
>> [2,] 2.5 7.5 12.5 17.5 22.5
>> [3,] 3.5 8.5 13.5 18.5 23.5
>> [4,] 4.5 9.5 14.5 19.5 24.5
>>
>>> x.bar.plot
>> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
>> [1,] 1.5 4.5 7.5 10.5 13.5 16.5 19.5 22.5 25.5 28.5 31.5 34.5
>> [2,] 2.5 5.5 8.5 11.5 14.5 17.5 20.5 23.5 26.5 29.5 32.5 35.5
>>
>> They are pretty similar numbers. It seems that [1,1] element is always 1.5
>> and consecutive elements in the same column differ by 1.0, but in the rows
>> we see something different: mine are 3.0 apart and yours are 5.0 apart. So
>> what does this tell me? I think fonts are specified in points which
>> correspond to 1/72 inches, while bars are specified in coordinates that are
>> independent of inches. So I need to know how coordinates correspond to
>> inches before I can get this fixed.
>
> They do not correspond to inches, but the the numeric scale of the values.
> Here is your plot with the numbers moved so they are to the right of the bar
> ends:
>
> txt <- "1.5 4.5 7.5 10.5 13.5 16.5 19.5 22.5 25.5 28.5 31.5 34.5
> 2.5 5.5 8.5 11.5 14.5 17.5 20.5 23.5 26.5 29.5 32.5 35.5"
> x <- read.table(textConnection(txt), header=FALSE)
>
> x.bar.plot <- barplot(as.matrix(x), horiz=TRUE, beside=TRUE, xlim=c(0,100),
> xlab="Score", las=1)
> text(as.matrix(x+6), x.bar.plot-.07, as.character(as.matrix(round(x))),
> pos=2, col="black")
>
> # the rounding is what makes the dissimilar bars labeled with the same
> numbers, ... yecch.
>
> Haven't figured out what the requirements on sizing really are; but here is
> an example you might play with:
>
> text(as.matrix(x+6), x.bar.plot-.07, as.character(as.matrix(round(x))),
> pos=2, col="black",
> cex= 24/length(as.matrix(x)))
>
>
> David Winsemius, MD
> Heritage Laboratories
> West Hartford, CT
More information about the R-help
mailing list