Save ggplot with a function
You can use print()
to save plots produced from ggplot2
to a file.
First, define your function to save plots:
savePlot <- function(myPlot) {
pdf("myPlot.pdf")
print(myPlot)
dev.off()
}
Create your plot:
myPlot <- ggplot(ggplot(data=df.music, aes(x=music, y=number)) +
geom_bar(stat="identity") +
xlab(colnames(df.music)[1]) +
ylab(colnames(df.music)[2]) +
ylim(c(0,11)) +
ggtitle("Ulubiony typ muzyki wśród studentów")
And finally call the function:
savePlot(myPlot)
Alternatively, you could just use ggsave()
after creating your plot:
ggsave(filename="myPlot.pdf", plot=myPlot)
Use of ggplot() within another function in R
As Joris and Chase have already correctly answered, standard best practice is to simply omit the meansdf$
part and directly refer to the data frame columns.
testplot <- function(meansdf)
{
p <- ggplot(meansdf,
aes(fill = condition,
y = means,
x = condition))
p + geom_bar(position = "dodge", stat = "identity")
}
This works, because the variables referred to in aes
are looked for either in the global environment or in the data frame passed to ggplot
. That is also the reason why your example code - using meansdf$condition
etc. - did not work: meansdf
is neither available in the global environment, nor is it available inside the data frame passed to ggplot
, which is meansdf
itself.
The fact that the variables are looked for in the global environment instead of in the calling environment is actually a known bug in ggplot2 that Hadley does not consider fixable at the moment.
This leads to problems, if one wishes to use a local variable, say, scale
, to influence the data used for the plot:
testplot <- function(meansdf)
{
scale <- 0.5
p <- ggplot(meansdf,
aes(fill = condition,
y = means * scale, # does not work, since scale is not found
x = condition))
p + geom_bar(position = "dodge", stat = "identity")
}
A very nice workaround for this case is provided by Winston Chang in the referenced GitHub issue: Explicitly setting the environment
parameter to the current environment during the call to ggplot
.
Here's what that would look like for the above example:
testplot <- function(meansdf)
{
scale <- 0.5
p <- ggplot(meansdf,
aes(fill = condition,
y = means * scale,
x = condition),
environment = environment()) # This is the only line changed / added
p + geom_bar(position = "dodge", stat = "identity")
}
## Now, the following works
testplot(means)
save plots made by loop in a file
In the code you had shared:
for(i in 1:28) {
plot_i <- ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
ggtitle(names(Num)[i])+theme_classic()
ggplot2::ggsave(filename = paste0("plot_",i,".png"),plot_i, path = "E:/Folder1")
}
You are storing the plot object in the variable plot_i
. You are not printing those plots. You need to insert, print(plot_i)
statement before saving the plot using ggplot
as follows:
for(i in 1:28) {
plot_i <- ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
ggtitle(names(Num)[i])+theme_classic()
print(plot_i)
ggplot2::ggsave(filename = paste0("plot_",i,".png"),plot_i, path = "E:/Folder1")
}
The reason why you need to print is because, ggsave
defaults to save the last displayed plot, and by printing you actually display on the Rs display devices. In simpler words this is what ggsave
does:
png('file_name.png') #it opens a graphics devices, can be other also like jpeg
print(plot_i) #displays the plot on graphics device
dev.off() #closes the graphic device
ggplot2 does not appear to work when inside a function R
It's an R FAQ -- you need print()
around it, or a ggsave()
which is particular to ggplot2.
From the FAQ:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such asxyplot()
create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). Theprint()
method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but insource()
or
inside your own functions you will need an explicitprint()
statement.
Use apply() to ggplot() to create and save individual jpegs
I think the main problem with the example you provided is that the loop is made over the "parks" vector, which only contains the levels of "Park_name". I think a better approach would be to loop over the data, subsetting by each "Park_name" entry.
I am also assuming that you have a column with the "units" variable (I added it in the plot as "Units"); however, if that is not the case, you may be able to create it using dplyr::separate
. I hope you find this code useful!
# determine park levels
parks <- unique(data[,"Park_name"])
# lapply for each park entry
p <- lapply(parks, function(park) {
#Subset the data by the each entry in the parks vector
subdata <- subset(data,data$Park_name == park)
#Collapse the zone vector as a string
zones <- paste(unique(subdata[,"Zone"]),
collapse = " ")
##ggplot
ggplot(subdata, aes(x=as.factor(Year), y=Height_mm)) +
facet_grid(Zone~.) +
geom_point() +
#Add the title and y lab as variables defined by park name, zones and a column with unit information
labs(title = paste(subdata$Park_name, zones, sep = " "),
y = paste0("Height (", subdata$Units,")"),
x = "Year") +
stat_summary(fun.data="mean_cl_boot", color="red")
#Save the plot, define your folder location as "C:/myplots/"
ggsave(filename = paste0(folder, park,".jpeg"),
device = "jpeg",
width = 15,
height = 10,
units = "cm",
dpi = 200)
})
how to combine ggsave in a function of ggplot?
Use ggsave
invisible(by(df, df$ID, function(i) {
p <- ggplot(i, aes(Date, EC))+
geom_line() +
geom_point() +
ggtitle(unique(i$ID))
ggsave(sprintf("file%s.pdf", unique(i$ID)),p)
}))
Related Topics
Varying Axis Labels Formatter Per Facet in Ggplot/R
Assigning Null to a List Element in R
How to Use a Graphic Imported with Grimport as Axis Tick Labels in Ggplot2 (Using Grid Functions)
How to Get Multiple Ggplot2 Scale_Fill_Gradientn with Same Scale
Index Unique Values in Data.Table
How to Access Dimensions of Labels Plotted by 'Geom_Text' in 'Ggplot2'
Ggplot2 - Using Two Different Color Scales for Overlayed Plots
Regression (Logistic) in R: Finding X Value (Predictor) for a Particular Y Value (Outcome)
How to Convert Time to Decimal
Convert Accented Characters into Ascii Character
Weird Characters Added to First Column Name After Reading a Toad-Exported CSV File
Generating Multiple Plots in Ggplot by Factor
Dual Y Axis in Ggplot2 for Multiple Panel Figure
How to Add a Condition to the Geom_Point Size
R Shiny, How to Make Datatable React to Checkboxes in Datatable
List Members Can Be Accessed with Partial Name? Is This a Feature
Keeping Only Certain Rows of a Data Frame Based on a Set of Values