Related
I am trying to save a plot created with ggplot from R to paste on my report in Word, but I am having issue with the dimensions.
plot_2.2 <- ggplot(data = data_2.2_melted, aes(x=value, y=variable, shape = Gender)) +
geom_point(size = 1.8, alpha = 0.5, col = "black")
#Change size of text and position of legend
plot_2.2_final <- plot_2.2 + theme(axis.text = element_text(size = 10, colour = "black")) +
theme(legend.position = "left",
axis.title.x=element_blank(),
axis.title.y=element_blank()) +
scale_shape_manual(values = c("M"= 17, "F" = 19))
I am trying
png(file="folder/saving_plot2.2.png",
width=790, height=840)
plot_2.2_final
dev.off()
But the dimensions are too small. If I try bigger dimension, eg
width=990, height=1140)
plot_2.2_final
dev.off()
I still get the dimensions of the first plot. It is like R is imposing size limits.
I have similar issues when I try to copy directly from R (i.e. Plot - Export - Copy to Clipboard) as I can get bigger plots.
I also tried to save in PDF to get a bigger plot, but it is smaller.
Could anyone help?
Thank you
I need to export graphics from R for the use in different publications formats, i.e., scientific poster, Journal Articel, Powerpoint presentation. As Long as I'm not aware of using R-Markdown and Latex, Or Sweave to produce pdf slides, i need to use Microsoft applications.
I do graphics in R with ggplot2.
My MWE
df1 <- expand.grid(Year = c(2000, 2010),
Treat = c("TreatA","TreatB"),
Location = c("Berlin", "Munich", "Kansas", "Paris"),
rep = c(1,2,3,4,5,6,7,8,9,10))
df1 <- cbind(df1,
Var1 = runif(160, -10,25) + rnorm(160,8,4))
My Graphics Code:
p1 <- ggplot(aes(y = Var1, x = Treat, na.rm=TRUE, fill=Location), data = df1) +
stat_boxplot(geom ='errorbar', width= 0.5) +
geom_boxplot(outlier.shape = 1, outlier.size = 2, linetype="solid", size = 1) +
facet_grid( Year ~ Location) +
scale_y_continuous(limits=c(-20,60)) +
scale_fill_manual(values=c("#E69F00", "#009E73", "#0072B2", "#D55E00")) +
ylab("Magic Skills") +
xlab("Magic Juice") +
theme(text=element_text(family="Arial", size=18),
axis.text.x = element_text(angle = 30, hjust = 1),
line=element_line(size=1),
rect=element_rect(colour="red", size=1),
panel.background=element_rect(colour="black",fill="white", size=1),
strip.background=element_rect(colour="dark grey", fill="black"),
strip.text=element_text(face="bold", colour="white"),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
legend.position="none");p1
How I save the graph:
ggsave(p1, file="Results/Figures/Abb2_Boxplots_LarvenPuppen2.svg", width=35, height=20, units = "cm", dpi=500)
I set the font size with "theme(text=element_text(family="Arial", size=18)" for the whole graph.
During ggsave I adjust the height and width, for the Poster the height should be 20 cm and width 35 cm. I save in .svg since I made best experience with the quality of the graph, furthermore I can edit anything at anytime in Inkscape, that's great!
So far so good, yet, it appears, that the text is by no means 18 pt, later in the powerpoint-poster, after exporting the graph (without editing!) as .png from Inkscape. It is even not 20 x 35 cm, I found that i loose about 5 cm or more during the saving and export process.
I guess R is doing write, when i say save 20x35 cm R will do it. Where in the whole process were my settings changed, and how can I handle it?
Best regards,
Pharcyde
There's a few things to consider:
SVG units – Note the discussion about user units, and pt vs px
grid graphics parameters and how they're interpreted by the device
ggplot2, and how its theme settings affect the font size
Here's a pure grid example that illustrates the second point,
library(grid)
g <- grobTree(rectGrob(), textGrob("test", gp=gpar(fontsize=12)))
ggplot2::ggsave("size.svg", g, width = 10, height=10, units = "in")
tmp <- readLines("size.svg")
grep("test", tmp, value = TRUE)
# "<text x='350.33' y='364.30' style='font-size: 12.00px; font-family: Arial;' textLength='19.34px' lengthAdjust='spacingAndGlyphs'>test</text>"
grep("viewBox", tmp, value = TRUE)
# "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 720.00 720.00'>"
So short answer is that the svg produced by R (svglite here) contains a seemingly consistent font size (12px), but the 10 inches is interpreted as 720px regardless of dpi. Looking at the source this 72 factor comes from R graphics conventions (typically devices follow the pdf device, which defaults to a 72DPI resolution. Why this is not affected by the various dpi/res/pointsize parameters is a mystery to me).
The gridSVG package by-passes the usual graphics engine system, and appears to produce more straight-forward sizes,
library(gridSVG)
gridsvg("size.svg", res = 1000, width=10, height=5)
grid.draw(g)
dev.off()
tmp <- readLines("size.svg")
grep("viewBox", tmp, value = TRUE)
# "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"10000px\" height=\"5000px\" viewBox=\"0 0 10000 5000\" version=\"1.1\">"
though this time the font size is scaled (it is 12 for the default 72DPI resolution),
grep("font-size", tmp, value = TRUE)
# "<text x=\"0\" y=\"0\" id=\"GRID.text.41.1.1.text\" text-anchor=\"middle\" font-size=\"166.67\" fill=\"rgb(0,0,0)\" fill-opacity=\"1\">"
On the ggplot2 side, things get even murkier because of some built-in settings for the inheritance of theme elements, rel()ative scaling, scales, that may or may not be documented (and have changed in the past IIRC).
"18pt" in an SVG is not the same as 18pt on a printed page.
One point ("pt") in a CSS style attribute has been defined - like in the printing industry - as 1/72 of an inch. However in CSS, an inch is not a real-world inch, but instead it is 96 "CSS pixels".
That dpi of 96, is a arbitrary value chosen a long time ago. Computer monitors aren't 96 pixels per inch any more (if any ever were).
If you want something to match the real world - for example one real inch on a printed page or screen - you will have to test your environment and output method, and apply a scaling factor to your SVG units. Or to your conversion technique.
Here is how it worked:
p1 <- ggplot(aes(y = Var1, x = Treat, na.rm=TRUE, fill=Location), data = df1) +
stat_boxplot(geom ='errorbar', width= 0.5) +
geom_boxplot(outlier.shape = 1, outlier.size = 2, linetype="solid", size = 1) +
facet_grid( Year ~ Location) +
scale_y_continuous(limits=c(-20,60)) +
scale_fill_manual(values=c("#E69F00", "#009E73", "#0072B2", "#D55E00")) +
ylab("Magic Skills") +
xlab("Magic Juice") +
theme(text=element_text(family="Arial", size=36*96/72),
axis.text.x = element_text(angle = 30, hjust = 1),
line=element_line(size=1),
rect=element_rect(colour="red", size=1),
panel.background=element_rect(colour="black",fill="white", size=1),
strip.background=element_rect(colour="dark grey", fill="black"),
strip.text=element_text(face="bold", colour="white"),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
legend.position="none");p1
ggsave(p1, file="Results/Figures/Trial.svg", width=35*1.25, height=20*1.25, units="cm", dpi=96)
With this code, I got an 35x20 cm plot both in Inkscape and in Powerpoint.
Furthermore the size of the letters was pretty much the size of letters in powerpoint.
This time I chose letter size 36pt, since this is more useful for Poster-presentations. I did not make further trials with changing the dpi.
Here my findings so far:
R uses 72 dpi by default, the formula: size * new resolution DPI / 72 DPI,
e.g.: 36 * 96/72, delivers almost similar pt sizes in Microsoft office documents. Irrespective of both the dpi settings used in ggsave as well as the height and width settings.
10 cm specified in R via ggsave() correspond to 8.060 cm in Inkscape. Multiplying the admired width/height by 1.25 delivers correct image sizes in Inkscape and also in MS Office, irrespective of the dpi set in the Export settings.
Something that makes me still wonder is that although I made the same settings for font size for the WHOLE plot via "text=element_text(family="Arial", size=36*96/72)"
Label titles are taller than tick labels or text in the facet boxes.
best wishes,
Pharcyde
The font size used by ggplot matches font size in word the problem is that the figure gets resized during saving, during importing, or both. The best solution for me has been to set a graphics window to the size the figure will be in the document (5.33" x 4" usually looks good in Word; 7.5" x 10" for a 4:3 PowerPoint), and then save the figure as that size. You may need to play around with file types (.tif doesn't play nice in PowerPoint and gets resized for some reason). That said, if you use this method and be sure that the figure isn't resized after it is exported from R it will have the exact size font as you had when you made your ggplot.
Here is the code I use,
dev.new(width = 10, height = 7.5, unit="in", noRStudioGD = T);last_plot() #Set new windo size and replot whatever plot you just made.
ggsave("workingdirectory/plot.png",width = dev.size()[1],height = dev.size()[2]);dev.off() #Save the plot and set the size using `dev.siz()` so you don't have to ever change that part and cannot possibly have a typo.
And here is a full example with output that you can bring into a 4:3 PowerPoint and see for yourself that it works.
measure1<-as.numeric(1:50)
category<-rep(c("a","b","c","d","e"),each=10)
df<-data.frame(measure1,category)
library(ggplot2)
library(extrafont)
ggplot(df, aes(x = category , y = measure1, fill = category, colour = category)) +
geom_boxplot(outlier.shape = NA, show.legend = F, notch = F) +
geom_point(aes(),size = 3, shape=16, colour="white", alpha=.6) +
stat_summary(fun.y=mean, show.legend = FALSE, geom="point", shape=18, size=5, colour = "white", na.rm = TRUE) +
ylab("Measure") +
xlab("Category") +
ggtitle("") +
scale_y_continuous (limits = c(0,50), expand = c(0,0), breaks=seq(0,50,5))+
scale_x_discrete(limits=c("a","b","c","d","e")) +
scale_fill_manual(values = rep("black",5))+
scale_colour_manual(values = rep("white",5))+
theme_bw() +
theme (text=element_text(size=24, family="Times New Roman"),
axis.title.y=element_text(size=24, vjust=2, colour="white"),
axis.title.x=element_text(size=24, hjust=0.5, colour="white"),
panel.border = element_blank(),
plot.title=element_blank(),
plot.margin = unit(c(.5, .5, .5, .5), "cm"),
panel.background = element_rect(fill = "black"),
plot.background = element_rect(fill = "black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none",
axis.ticks = element_line(size=0.8, colour = "white"),
axis.ticks.length=unit(0.2,"cm"),
axis.text.x=element_text(colour="white",size=24,angle=0,hjust=.5),
axis.text.y=element_text(colour="white",size=24),
axis.line = element_line(colour="white", size=0.8, lineend = "square"))
dev.new(width = 10, height = 7.5, unit="in", noRStudioGD = T);last_plot()
ggsave("C:/Users/s39f171/Documents/plot.png",width = dev.size()[1],height = dev.size()[2]);dev.off()
Sample of the dataset.
nq
0.140843018
0.152855833
0.193245919
0.156860105
0.171658019
0.186281942
0.290739146
0.162779517
0.164694042
0.171658019
0.195866609
0.166967913
0.136841748
0.108907644
0.264136384
0.356655651
0.250508305
I would like to make a Percentage Bar plot/Histogram like this question: RE: Alignment of numbers on the individual bars with ggplot2
The max value of NQ for full dataset is 21 and minimum value is 0.00005
But I am unable to adapt the code as I don't have a Freq column and I have one series.
I have made a mockup of the figure I am trying to make.
Could you please help?
Would that work for you?
nq <- read.table(text = "
0.140843018
0.152855833
0.193245919
0.156860105
0.171658019
0.186281942
0.290739146
0.162779517
0.164694042
0.171658019
0.195866609
0.166967913
0.136841748
0.108907644
0.264136384
0.356655651
0.250508305", header = F) # Your data
nq$V2 <- cut(nq$V1, 5, include.lowest = T)
nq2 <- aggregate(V1 ~ V2, nq, length)
nq2$V3 <- nq2$V1/sum(nq2$V1)
library(ggplot2)
ggplot() + geom_bar(data = nq2, aes(V2, V1), stat = "identity", width=1, fill = "white", col = "black", size = 2) +
geom_text(vjust=1, fontface="bold", data = nq2, aes(label = paste(sprintf("%.1f", V3*100), "%", sep=""), x = V2, y = V1 + 0.4), size = 5) +
theme_bw() +
scale_x_discrete(expand = c(0,0), labels = sprintf("%.3f",seq(min(nq$V1), max(nq$V1), by = max(nq$V1)/6))) +
ylab("No. of Cases") + xlab("") +
scale_y_continuous(expand = c(0,0)) +
theme(
axis.title.y = element_text(size = 20, face = "bold", angle = 0),
panel.grid.major = element_blank() ,
panel.grid.minor = element_blank() ,
panel.border = element_blank() ,
panel.background = element_blank(),
axis.line = element_line(color = 'black', size = 2),
axis.text.x = element_text(face="bold"),
axis.text.y = element_text(face="bold")
)
I thought this would be easy, but it turned out to be frustrating. So perhaps the "right" way is to transform your data before using ggplot as it looks like #DavidArenburg has done. But, if you feel like hacking ggplot, here's what I ended up doing.
First, some sample data.
set.seed(15)
dd<-data.frame(x=sample(1:25, 100, replace=T, prob=25:1))
br <- seq(0,25, by=5) # break points
My first attempt was
library(ggplot2)
ggplot(dd, aes(x)) +
stat_bin(position="stack", breaks=br) +
geom_text(aes(y=..count.., label=..density..*..width.., ymax=..count..+1),
vjust=-.5, breaks=br, stat="bin")
but that didn't make "pretty labels"
so i thought i'd use the percent() function from the scales package to make it pretty. However, silly ggplot doesn't really make it possible to use functions with ..().. variables because it evaluates them in the data.frame only (then the empty baseenv()). It doesn't have a way to find the function you use. So this is when I turned to hacking. First i'll extract the "Layer" definition from ggplot and the map_statistic from it. (NOTE: this was done with "ggplot2_1.0.0" and is specific to that version; this is a private function that may change in future releases)
orig.map_statistic <- ggplot2:::Layer$map_statistic
new.map_statistic <- orig.map_statistic
body(new.map_statistic)[[9]]
# stat_data <- as.data.frame(lapply(new, eval, data, baseenv()))
here's the line that's causing grief I would prefer it the function resolved other names in the plot environment that are not found in the data.frame. So I decided to change it with
body(new.map_statistic)[[9]] <- quote(stat_data <- as.data.frame(lapply(new, eval, data, plot$plot_env)))
assign("map_statistic", new.map_statistic, envir=ggplot2:::Layer)
So now I can use functions with ..().. variables. So I can do
library(scales)
ggplot(dd, aes(x)) +
stat_bin(position="stack", breaks=br) +
geom_text(aes(y=..count.., ymax=..count..+2,
label=percent(..density..*..width..)),
vjust=-.5, breaks=br, stat="bin")
to get
So i'm not sure why ggplot has this default behavior. There could be some good reason for it but I don't know what it is. This does change how ggplot will behave for the rest of the session. You can change back to default with
assign("map_statistic", orig.map_statistic, envir=ggplot2:::Layer)
Is there a way to have the value of the fill (the label) become the fill itself? For instance, in a stacked bar plot, I have
require(ggplot2)
big_votes_movies = movies[movies$votes > 100000,]
p = ggplot(big_votes_movies, aes(x=rating, y=votes, fill=year)) + geom_bar(stat="identity")
Can the values of 1997 and whatnot be the fill itself? A motif plot, if you will? An example of a motif plot is:
If this is possible, can I also plot these values on polar coordinates, so the fill would become the value?
p + coord_polar(theta="y")
There is a way to do it, but it's a little ugly.
When I first looked at it, I wondered if it could be done using geom_text, but although it gave a representation, it didn't really fit the motif structure. This was a first attempt:
require(ggplot2)
big_votes_movies = movies[movies$votes > 100000,]
p <- ggplot(big_votes_movies, aes(x=rating, y=votes, label=year))
p + geom_text(size=12, aes(colour=factor(year), alpha=0.3)) + geom_jitter(alpha=0) +
scale_x_continuous(limits=c(8, 9.5)) + scale_y_continuous(limits=c(90000,170000))
So then I realised you had to actually render the images within the grid/ggplot framework. You can do it, but you need to have physical images for each year (I created rudimentary images using ggplot, just to use only one tool, but maybe Photoshop would be better!) and then make your own grobs which you can add as custom annotations. You then need to make your own histogram bins and plot using apply. See below (it could be prettied up fairly easily). Sadly only works with cartesian co-ords :(
require(ggplot2)
require(png)
require(plyr)
require(grid)
years<-data.frame(year=unique(big_votes_movies$year))
palette(rainbow(nrow(years)))
years$col<-palette() # manually set some different colors
# create a function to write the "year" images
writeYear<-function(year,col){
png(filename=paste(year,".png",sep=""),width=550,height=300,bg="transparent")
im<-qplot(1,1,xlab=NULL,ylab=NULL) +
theme(axis.text.x = element_blank(),axis.text.y = element_blank()) +
theme(panel.background = element_rect(fill = "transparent",colour = NA), plot.background = element_rect(fill = "transparent",colour = NA), panel.grid.minor = element_line(colour = "white")) +
geom_text(label=year, size=80, color=col)
print(im)
dev.off()
}
#call the function to create the placeholder images
apply(years,1,FUN=function(x)writeYear(x["year"],x["col"]))
# then roll up the data
summarydata<-big_votes_movies[,c("year","rating","votes")]
# make own bins (a cheat)
summarydata$rating<-cut(summarydata$rating,breaks=c(0,8,8.5,9,Inf),labels=c(0,8,8.5,9))
aggdata <- ddply(summarydata, c("year", "rating"), summarise, votes = sum(votes) )
aggdata<-aggdata[order(aggdata$rating),]
aggdata<-ddply(aggdata,.(rating),transform,ymax=cumsum(votes),ymin=c(0,cumsum(votes))[1:length(votes)])
aggdata$imgname<-apply(aggdata,1,FUN=function(x)paste(x["year"],".png",sep=""))
#work out the upper limit on the y axis
ymax<-max(aggdata$ymax)
#plot the basic chart
z<-qplot(x=10,y=10,geom="blank") + scale_x_continuous(limits=c(8,9.5)) + scale_y_continuous(limits=c(0,ymax))
#make a function to create the grobs and call the annotation_custom function
callgraph<-function(df){
tiles<-apply(df,1,FUN=function(x)return(annotation_custom(rasterGrob(image=readPNG(x["imgname"]),
x=0,y=0,height=1,width=1,just=c("left","bottom")),
xmin=as.numeric(x["rating"]),xmax=as.numeric(x["rating"])+0.5,ymin=as.numeric(x["ymin"]),ym ax=as.numeric(x["ymax"]))))
return(tiles)
}
# then add the annotations to the plot
z+callgraph(aggdata)
and here's the plot with photoshopped images. I just save them over the generated imaages, and ran the second half of the script so as not to regenerate them.
OK - and then because it was bothering me, I decided to install extrafont and build the prettier graph using just R:
and here's the code:
require(ggplot2)
require(png)
require(plyr)
require(grid)
require(extrafont)
#font_import(pattern="Show") RUN THIS ONCE ONLY
#load the fonts
loadfonts(device="win")
#create a subset of data with big votes
big_votes_movies = movies[movies$votes > 100000,]
#create a custom palette and append to a table of the unique years (labels)
years<-data.frame(year=unique(big_votes_movies$year))
palette(rainbow(nrow(years)))
years$col<-palette()
#function to create the labels as png files
writeYear<-function(year,col){
png(filename=paste(year,".png",sep=""),width=440,height=190,bg="transparent")
im<-qplot(1,1,xlab=NULL,ylab=NULL,geom="blank") +
geom_text(label=year,size=70, family="Showcard Gothic", color=col,alpha=0.8) +
theme(axis.text.x = element_blank(),axis.text.y = element_blank()) +
theme(panel.background = element_rect(fill = "transparent",colour = NA),
plot.background = element_rect(fill = "transparent",colour = NA),
panel.grid.minor = element_line(colour = "transparent"),
panel.grid.major = element_line(colour = "transparent"),
axis.ticks=element_blank())
print(im)
dev.off()
}
#call the function to create the placeholder images
apply(years,1,FUN=function(x)writeYear(x["year"],x["col"]))
#summarize the data, and create bins manually
summarydata<-big_votes_movies[,c("year","rating","votes")]
summarydata$rating<-cut(summarydata$rating,breaks=c(0,8,8.5,9,Inf),labels=c(0,8,8.5,9))
aggdata <- ddply(summarydata, c("year", "rating"), summarise, votes = sum(votes) )
aggdata<-aggdata[order(aggdata$rating),]
aggdata<-ddply(aggdata,.(rating),transform,ymax=cumsum(votes),ymin=c(0,cumsum(votes))[1:length(votes)])
#identify the image placeholders
aggdata$imgname<-apply(aggdata,1,FUN=function(x)paste(x["year"],".png",sep=""))
ymax<-max(aggdata$ymax)
#do the basic plot
z<-qplot(x=10,y=10,geom="blank",xlab="Rating",ylab="Votes \n",main="Big Movie Votes \n") +
theme_bw() +
theme(panel.grid.major = element_line(colour = "transparent"),
text = element_text(family="Kalinga", size=20,face="bold")
) +
scale_x_continuous(limits=c(8,9.5)) +
scale_y_continuous(limits=c(0,ymax))
#creat a function to create the grobs and return annotation_custom() calls
callgraph<-function(df){
tiles<-apply(df,1,FUN=function(x)return(annotation_custom(rasterGrob(image=readPNG(x["imgname"]),
x=0,y=0,height=1,width=1,just=c("left","bottom")),
xmin=as.numeric(x["rating"]),xmax=as.numeric(x["rating"])+0.5,ymin=as.numeric(x["ymin"]),ymax=as.numeric(x["ymax"]))))
return(tiles)
}
#add the tiles to the base chart
z+callgraph(aggdata)
I am looking for a way to modify font types in ggplot. At the moment I would be happy enough to simply change fonts to the 'courier' font family, but ultimately my goal is to call a custom font template--any input on this latter point would be very much appreciated.
I've done a bit of homework, looking at the following posts and articles:
ggplot2: How to change font of labels in geom_text
R News Volume 6/2,
Non-Standard Fonts in PostScript and PDF
Graphic, Murrell and Ripley.
ComputerModern font in ggplot2 graphics?
It may be because I am still a hopeless amateur with ggplot2, but I haven't even been able to switch chart fonts to courier. Any help? I've included the data for the chart in question, below, along with the code, so hopefully this is all easy enough to follow.
I think your answer is fine but you can do it more simply:
install.packages("extrafont");library(extrafont)
font_import("Trebuchet MS")
library(ggplot2)
qplot(1:10)+theme(text=element_text(family="Trebuchet MS"))
Sorted out my query with fairly minimal hassle. It was a two-step solution that I wouldn't have arrived at without following the advice of the members who responded.
To change the ggplot text defaults, I adapted the code that Brandon referred me to at:
http://johndunavent.com/combined-line-and-bar-chart-ggplot2
Where John Dunavent creates a function, theme_min, that can be edited to provide the default options for a ggplot, including using fonts imported from Windows with the windowsFonts command. My adaptation of his code looks like this:
theme_min = function (size=10, font=NA, face='plain',
panelColor=backgroundColor, axisColor='#999999',
gridColor=gridLinesColor, textColor='black')
{
theme_text = function(...)
ggplot2::theme_text(family=font, face=face, colour=textColor,
size=size, ...)
opts(
axis.text.x = theme_text(),
axis.text.y = theme_text(),
axis.line = theme_blank(),
axis.ticks = theme_segment(colour=axisColor, size=0.25),
panel.border = theme_rect(colour=backgroundColor),
legend.background = theme_blank(),
legend.key = theme_blank(),
legend.key.size = unit(1.5, 'lines'),
legend.text = theme_text(hjust=0),
legend.title = theme_text(hjust=0),
panel.background = theme_rect(fill=panelColor, colour=NA),
panel.grid.major = theme_line(colour=gridColor, size=0.33),
panel.grid.minor = theme_blank(),
strip.background = theme_rect(fill=NA, colour=NA),
strip.text.x = theme_text(hjust=0),
strip.text.y = theme_text(angle=-90),
plot.title = theme_text(hjust=0),
plot.margin = unit(c(0.1, 0.1, 0.1, 0.1), 'lines'))
}
##Create a custom font type. Could be 'F', 'TEST', whatever
windowsFonts(F = windowsFont('Wide Latin'))
##and insert this line of code into the original code I list above:
+ theme_min(font='F', size=10)
Awkwardly, there is no way (that I found) to generically modify the font settings for geom_text objects before a plot is created. James' solution above worked perfectly for this, though. Instead of using a standard font, I set fontfamily="F" to bring in the custom font that I selected in theme_min(), i.e.:
grid.gedit("GRID.text",gp=gpar(fontfamily="F"))
Hopefully this is useful to any other users looking to modify fonts on their graphs.
Cheers to all who helped me sort this out!
Aaron
Have a look at the family argument of theme_text()
dummy <- data.frame(A = rnorm(10), B = rnorm(10))
ggplot(dummy, aes(x = A, y = B)) + geom_point()
#helvetica = default
ggplot(dummy, aes(x = A, y = B)) + geom_point() + opts(axis.title.x = theme_text(family = "sans", face = "bold"))
#times
ggplot(dummy, aes(x = A, y = B)) + geom_point() + opts(axis.title.x = theme_text(family = "serif", face = "bold"))
#courier
ggplot(dummy, aes(x = A, y = B)) + geom_point() + opts(axis.title.x = theme_text(family = "mono", face = "bold"))
Inspired by a post on kohske's blog I came up with this:
theme_set( theme_bw( base_family= "serif"))
theme_update( panel.grid.minor= theme_blank(),
panel.grid.major= theme_blank(),
panel.background= theme_blank(),
axis.title.x= theme_blank(),
axis.text.x= theme_text( family= "serif",
angle= 90, hjust= 1 ),
axis.text.x= theme_text( family= "serif"),
axis.title.y= theme_blank())
theme_map <- theme_get()
theme_set( theme_bw())
Now when I want to use that particular theme:
last_plot() + theme_map
YMMV.
BTW, if I had the power I would vote down the preferred answer:
> grid.gedit("GRID.text",gp=gpar(fontfamily="mono"))
Error in editDLfromGPath(gPath, specs, strict, grep, global, redraw) :
'gPath' (GRID.text) not found
Not sure what this means. Nor was I offered a link to comment on that answer; maybe something has changed on the site.
You can set the font of the labels produced by geom_text with grid.gedit:
grid.gedit("GRID.text",gp=gpar(fontfamily="mono"))
Call this after you have produced your original plot.
Also check out the Cairo package, which has support for totally switching out all of the fonts with those of your choosing. http://rforge.net/doc/packages/Cairo/00Index.html
This seems like the simplest solution, for my money.
Some play data in df, and made into a simple graph, "p", with nice long x and y labels, so we can see the font change:
df <- data.frame(A = rnorm(10), B = rnorm(10))
p = ggplot(data = df, aes(x = A, y = B)) + geom_point()
p = p + xlab("A long x-string so we can see the effect of the font switch")
p = p + ylab("Likewise up the ordinate")
And we view the default plot in whatever that font is:
p
Now we switch to Optima, adding some nice title and subtitle to bask in the glory of Optima:
label = "Now we switch to Optima"
subtitle = "Optima is a nice font: https://en.wikipedia.org/wiki/Optima#Usages"
And after all that, we print in the new font
# the only line you need to read:
p + theme(text = element_text(family = "Optima", , face = "bold"))
p = p + ggtitle(label = label, subtitle = subtitle)
p