How to determine symbol size in x and y units - r

I would like to know the approximate dimensions of symbol in my plot area. I think that par()$ps only really refers to text size. So how is a symbol size calculated using the cex parameter? For example, below is a plot of a single point of size cex=10. Can i determine its size from the plot devices par parameters?
plot(50, 50, ylim=c(0,100), xlim=c(0,100), cex=10)
#click on outer x limits
p1 <- locator(n=1,typ="n")
p2 <- locator(n=1,typ="n")
#approx width in x units(~15)
abs(p1$x - p2$x)
Thanks for you help. -Marc

According to the documentation contained in ?par, we have that,
cin - R.O.; character size (width, height) in inches. These are the same measurements as cra, expressed in different units.
cra - R.O.; size of default character (width, height) in ‘rasters’ (pixels). Some devices have no concept of pixels and so assume an arbitrary pixel size, usually 1/72 inch. These are the same measurements as cin, expressed in different units.
On my machine, these values appear to be:
par("cin")
[1] 0.15 0.20
> par("cra")
[1] 10.8 14.4
So character magnification via cex ought to happen relative to these dimensions, presumably by scaling the horizontal and vertical dimensions separately (although I don't know that for sure).

Related

What does the `fontsize` represent in `grid` graphics?

The fontsize is used to determine the size of text or points in R graphics. But what does it actually represent? For example,
grid::grid.newpage()
grid::grid.points(default.units = "npc",
gp = gpar(fontsize = 100))
Here, the point fontsize is 100. So, I have two questions:
What does the value mean, the radius, the diameter or the area of a point? Can I find any reference?
What is the unit of 100? In specific, does it mean 100 pointsize (1 fontsize = 1pt)? Otherwise, is it determined by device-specification? If so, 1 fontsize = ?pt.
Also, I have another question that, in language R, is there any handy functions to convert pt to pixel (px)? For example, we can convert a pt unit to a mm unit as in
convertUnit(unit(1, "pt"), "mm", valueOnly = TRUE)
So, is there any function to query the dimension of the screen and then do the transformation from pt to px?
Thanks!
The size of the symbols drawn by grid.points() depend on several factors, primarily pch, which determines the shape of the symbol, and size. By default, the latter is unit(1, "char"), which means the size further depends on the current font size (fontsize and cex).
Deep in the graphics engine source code (https://github.com/r-devel/r-svn/blob/master/src/main/engine.c#L2110) are some constants that further modify the nominal symbol size based on the symbol shape. For example, pch=1 multiplies size by .375 to get the circle radius.
Yes, fontsize=100 means 100pt.
The following code demonstrates the calculations by drawing a symbol and a rectangle with the same width:
library(grid)
grid.newpage()
pushViewport(viewport())
grid.points(.5, .5)
grid.rect(width=2*.375*unit(1, "char"))
grid.points(.5, .5, gp=gpar(fontsize=100))
grid.rect(width=2*.375*unit(100, "pt"))

How to determine dimensions/area of hexagons in geom_hex

I've currently plotted x and y coordinates to ggplot using geom_hex.
I'm wondering if it's possible to determine size of the hexagons plotted?
(or at least the width of each?)
I recognize they will be in arbitrary units but that is OK. If A) my plot is approximately 50 by 40 (see below) and B)geom_hex(bins = 60) is it accurate to infer that there are 60 hexagons across each x and y dimension;
Therefore, my approximate hexagon width would be 40(x-units)/60(hexagons) = 0.66667?
Thanks for the help!
I found a solution: you can pre-specify the width of each bin within geom_hex with binwidth = –

How to get the width and height of a character in usr coordinates

How can I get the width and height of a character in usr coordinates? I found something on R-help, but that appears not to make it completely clear. I assumed that
plot(NULL, xlim=c(-1,1), ylim=c(-1,1))
h <- par()$cxy
rect(-h[1]/2, -h[2]/2, h[1]/2, h[2]/2)
text(0,0,"M")
would be the answer but the rectangle is slightly too big. Additionally I want the size also to respect different cex values. Thanks for your time!
I finally discovered an answer in the par docu:
cxy
R.O.; size of default character (width, height) in user coordinate
units. par("cxy") is par("cin")/par("pin") scaled to user coordinates.
Note that c(strwidth(ch), strheight(ch)) for a given string ch is
usually much more precise.
Using strwidth and strheight instead of par()$cxy gives much better results.
plot(NULL, xlim=c(-1,1), ylim=c(-1,1))
h <- c(strwidth("M"), strheight("M"))
rect(-h[1]/2, -h[2]/2, h[1]/2, h[2]/2)
text(0,0,"M")

Increasing the yRange by a fixed amount

I want my legend to be inside the plot and therefore, I want to increase the yRange by a fixed amount. However, that fixed amount should be %20 of maximum y amount.
Some graphs I plot are percentages and some of them are just values. Hence, I cannot use the same range for all, but I need to increase the yRange so that legend won't overlap with the plot itself.
How can I do it?
You can use set offsets to achieve this. Use
set offsets 0,0,graph 0.2,0
to expand the upper graph boundary by 20% of the total, automatically calculated height. This might be a bit more then 20% of the maximum y-value because gnuplot first expands to the next major tics. If you want to have exactly 20% of the maximum, you must use
set autoscale yfixmax
set offsets 0,0,graph 0.2,0
If you have Gnuplot version 4.6 then you can leverage stats to get the max/min of the y column in your data file and then use that to augment the yrange. Assuming your y data is in column 1 of your data file:
stats 'datafile' using 1
y_max_augmented = STATS_max + STATS_max * 0.2
set yrange [STATS_min:y_max_augmented] # you may use any other value in place of STATS_min

ggplot2 - The unit of size

A quick question that I can't find answer on the web (or Wickham's book):
What is the unit of the size argument in ggplot2? For example, geom_text(size = 10) -- 10 in what units?
The same question applies to default unit in ggsave(height = 10, width = 10).
The answer is : The unit is the points. It is the unit of fontsize in the grid package. In ?unit, we find the following definition
"points" Points. There are 72.27 points per inch.
(but note the closely related "bigpts" Big Points. 72 bp = 1 in.)
Internally ggplot2 will multiply the font size by a magic number ggplot2:::.pt, defined as 1/0.352777778.
Here a demonstration, I create a letter using grid and ggplot2 with same size:
library(grid)
library(ggplot2)
ggplot(data=data.frame(x=1,y=1,label=c('A'))) +
geom_text(aes(x,y,label=label),size=100)
## I divide by the magic number to get the same size.
grid.text('A',gp=gpar(fontsize=100/0.352777778,col='red'))
Addendum Thanks to #baptiste
The "magic number"(defined in aaa-constants.r as .pt <- 1 / 0.352777778) is really just the conversion factor between "points" and "mm", that is 1/72 * 25.4 = 0.352777778. Unfortunately, grid makes the subtle distinction between "pts" and "bigpts", which explains why convertUnit(unit(1, "pt"), "mm", valueOnly=TRUE) gives the slightly different value of 0.3514598.
The 'ggplot2' package, like 'lattice' before it, is built on the grid package. You can get the available units at:
?grid::unit
?grid::convertX
?grid::convertY
grid::convertX(grid::unit(72.27, "points"), "inches")
(I use the formalism pkg::func because in most cases grid is loaded a a NAMESPACE but not attached when either lattice or `ggplot2 are loaded.)
I earlier posted a comment that I later deleted saying that size was in points. I did so after seeing that the size of the text with size=10 was roughly 10 mm. The "magic" number mentioned by agstudy is in fact within 1% of:
as.numeric(grid::convertX(grid::unit(1, "points"), "mm"))
#[1] 0.3514598
0.352777778/.Last.value
#[1] 1.00375
From ?aes_linetype_size_shape
# Size examples
# Should be specified with a numerical value (in millimetres),
# or from a variable source
height and width in ggsave relate to par("din") from ?par
din
R.O.; the device dimensions, (width, height), in inches. See also dev.size,
which is updated immediately when an on-screen device windows is re-sized.
So I guess size in aes is in millimetres and ggsave height and width are in inches.

Resources