196

I am confused. What is the right way to increase font size of text in the title, labels and other places of a plot?

For example

x <- rnorm(100)
hist(x, xlim=range(x), xlab= "Variable Label", 
     ylab="density", main="Title of plot", prob=TRUE, ps=30)

The ps argument does not change font size (but it says in R Help for ?par that it is for "the point size of text (but not symbols)".

Also is it possible to separate changing the font size from the plotting function such as hist?

buhtz
  • 10,774
  • 18
  • 76
  • 149
Tim
  • 1
  • 141
  • 372
  • 590
  • Possible duplicate of [How to change the label size of an R plot](https://stackoverflow.com/questions/13046323/how-to-change-the-label-size-of-an-r-plot) – Waldir Leoncio Jun 01 '17 at 08:47

9 Answers9

183

You want something like the cex=1.5 argument to scale fonts 150 percent. But do see help(par) as there are also cex.lab, cex.axis, ...

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • 1
    Thanks! What is the difference with "ps=1.5"? – Tim Nov 22 '10 at 02:44
  • 6
    why cex=1.5 does not work? But have to specify for each part in terms of cex.lab, cex.axis, cex.main? What is cex=1.5 for? – Tim Nov 22 '10 at 02:49
  • 2
    Did you read `help(par)` about `ps`? Does not seem text-related as far as I can tell. – Dirk Eddelbuettel Nov 22 '10 at 02:51
  • 2
    That's the way it is, in part surely for backwards compatibility with prior implementations of the S language. – Dirk Eddelbuettel Nov 22 '10 at 02:53
  • Thanks! ps means the point size of text. So it is not the size of text, what is it then? – Tim Nov 22 '10 at 02:55
  • 3
    cex is the magnification factor. The default value is 1. If you need to specify font sizes, you had better be prepared to dig into the documentation starting with ?Devices, ?pdfFonts, ?pdf, ?embedFonts, and many others. – IRTFM Nov 22 '10 at 05:24
  • Fontsize for a plot can be changed with `par(ps=14)` followed by plotting. – alexvpickering Sep 22 '21 at 00:49
151

Thus, to summarise the existing discussion, adding

cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5

to your plot, where 1.5 could be 2, 3, etc. and a value of 1 is the default will increase the font size.

x <- rnorm(100)

cex doesn't change things

hist(x, xlim=range(x),
     xlab= "Variable Lable", ylab="density", main="Title of plot", prob=TRUE)

hist(x, xlim=range(x),
     xlab= "Variable Lable", ylab="density", main="Title of plot", prob=TRUE, 
     cex=1.5)

enter image description here

Add cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5

hist(x, xlim=range(x),
     xlab= "Variable Lable", ylab="density", main="Title of plot", prob=TRUE, 
     cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5)

enter image description here

Jeromy Anglim
  • 33,939
  • 30
  • 115
  • 173
  • 3
    BTW, if you're trying to modify the axis in a bar chart (say for the variable importance plot in randomForest or GBM), you need to use `cex.names` (if you're a human who reads things from an upright position, you might also want `las=2`) – geneorama Jan 12 '16 at 20:13
  • 1
    @geneorama thanks!! your comment saved me SO much time. – Daniel Schütte Dec 15 '22 at 16:25
27

By trial and error, I've determined the following is required to set font size:

  1. cex doesn't work in hist(). Use cex.axis for the numbers on the axes, cex.lab for the labels.
  2. cex doesn't work in axis() either. Use cex.axis for the numbers on the axes.
  3. In place of setting labels using hist(), you can set them using mtext(). You can set the font size using cex, but using a value of 1 actually sets the font to 1.5 times the default!!! You need to use cex=2/3 to get the default font size. At the very least, this is the case under R 3.0.2 for Mac OS X, using PDF output.
  4. You can change the default font size for PDF output using pointsize in pdf().

I suppose it would be far too logical to expect R to (a) actually do what its documentation says it should do, (b) behave in an expected fashion.

Urban Vagabond
  • 7,282
  • 3
  • 28
  • 31
22

Notice that "cex" does change things when the plot is made with text. For example, the plot of an agglomerative hierarchical clustering:

library(cluster)
data(votes.repub)
agn1 <- agnes(votes.repub, metric = "manhattan", stand = TRUE)
plot(agn1, which.plots=2)

will produce a plot with normal sized text:

enter image description here

and plot(agn1, which.plots=2, cex=0.5) will produce this one:

enter image description here

Ulrich Dangel
  • 4,515
  • 3
  • 22
  • 30
OskrSaSi
  • 330
  • 2
  • 4
  • Work in `faces2` too (from [Chernoff faces](http://cran.r-project.org/web/packages/TeachingDemos/index.html) ) – Galled Jan 09 '15 at 01:32
  • In my example I had to apply _cex_ **not** to plot but the inner object directly for an effect: `plot(ci(roc(data$a, data$b, auc=TRUE, of="auc", print.auc=TRUE, print.auc.cex=1.5, plot=TRUE), of="thresholds", thresholds="best")))` – Tapper Sep 10 '17 at 18:26
7

I came across this when I wanted to make the axis labels smaller, but leave everything else the same size. The command that worked for me, was to put:

par(cex.axis=0.5)

Before the plot command. Just remember to put:

par(cex.axis=1.0)

After the plot to make sure that the fonts go back to the default size.

4

In case you want to increase the font of the labels of the histogram when setting labels=TRUE

bp=hist(values, labels = FALSE, 
 main='Histogram',
 xlab='xlab',ylab='ylab',  cex.main=2, cex.lab=2,cex.axis=2)

text(x=bp$mids, y=bp$counts, labels=bp$counts ,cex=2,pos=3)
yeinhorn
  • 565
  • 1
  • 8
  • 12
3

For completeness, scaling text by 150% with cex = 1.5, here is a full solution:

cex <- 1.5
par(cex.lab=cex, cex.axis=cex, cex.main=cex)
plot(...)
par(cex.lab=1, cex.axis=1, cex.main=1)

I recommend wrapping things like this to reduce boilerplate, e.g.:

plot_cex <- function(x, y, cex=1.5, ...) {
  par(cex.lab=cex, cex.axis=cex, cex.main=cex)
  plot(x, y, ...)
  par(cex.lab=1, cex.axis=1, cex.main=1)
  invisible(0)
}

which you can then use like this:

plot_cex(x=1:5, y=rnorm(5), cex=1.3)

The ... are known as ellipses in R and are used to pass additional parameters on to functions. Hence, they are commonly used for plotting. So, the following works as expected:

plot_cex(x=1:5, y=rnorm(5), cex=1.5, ylim=c(-0.5,0.5))
Adam Erickson
  • 6,027
  • 2
  • 46
  • 33
1

Alternatively, you can change the resolution of the saved image with the res parameter of the graphics device:

png(file = "myplot1.png",  bg = "transparent", res = 100)   
plot(1:10)                                                  
dev.off()                                                   

plot 1

png(file = "myplot2.png", bg = "transparent", res = 200)    
plot(1:10)                                                  
dev.off()                                                   

plot2

This will keep the same image size in pixels, but it will change the plot's aspect ratio, including font size.

Paul Rougieux
  • 10,289
  • 4
  • 68
  • 110
1

Just to add a simple example where I use cex to change several font sizes on the graph, including adding a subtitle inside the graph using the line command.

par(cex=1, cex.main=2, cex.lab = 1.5, cex.sub=0.8)
plot(gam_d13C_year, residuals = TRUE, pch = 1, mar=c(8, 2, 2, 2) + 1, bty="n")
title(main = TeX('Effect of year in $\\delta ^{13}C$'))
title(sub =paste(gam_d13C_year_stats),line = -2, adj = 0.5)

Change size of font in graph with R