Loop Through a Series of Qplots

Loop through a series of qplots

As the other answers have said, wrap each qplot() call in print() (this is R FAQ 7.22). The reason why is that ggplot's aren't printed to the graphics device until print.ggplot is called on them. print() is a generic function that dispatches to print.ggplot behind the scenes.

When you are working in the repl ("read-evaluate-print loop", aka shell) the return value of the previous input line is automatically printed via an implicit call to print(). That's why
qplot(mtcars[,Var], wt, data=mtcars, xlab=Var) is working for you. It's nothing to do with scope or the for loop. If you were to put that line anywhere else that isn't directly returning to the repl, such as in a function that returns something else, it would do nothing.

Loop multiple qplot in same graph

It's easier to use "long" data rather than "wide" data with ggplot2 (see here). This means the first thing to do is get your data into the right format:

library(reshape2)
myData$Time = time
data.melted = melt(myData, id="Time")

This turns it into a format more like:

Time   variable   value
1 Crude Oil 18.54
2 Crude Oil 17.40

At that point, it's easy to make this kind of plot with facetting (no for loop necessary):

print(ggplot(data.melted, aes(x=time, y=value)) + geom_line() + facet_wrap(~ variable)
+ theme_bw())

qplot Break Formating in a loop

There are a few strange things in your code, and I'm not sure which is causing your problem, but here's a working equivalent:

for(i in unique(cdata$temp)) {

cdata_i <- cdata[cdata$temp == i, ]

my.plot <- ggplot(cdata_i, aes(x = Year, y = Consumption)) +
geom_point() +
labs(x = "Year",
y = "Consumption (kcal)",
title = paste("Consumption:", prettyNum(i, ","))) +
scale_x_continuous(breaks = seq(2010, 2100, by = 10))

print(my.plot)

}

A few suggestions:

  • Don't overwrite i within the loop - i is useful (I use it to make the titles below)
  • Use the function ggplot instead of qplot. qplot is fine for quick, interactive plots, but as soon as you're trying to do something more complex (like this), using ggplot will save you a lot of headaches.
  • Use the limits argument of scale_x_continuous to make sure that your plots all have the same x axis. Setting breaks alone won't guarantee that 2010 and 2100 appear on every plot.

qplot call overwrites list elements

In ggplot the aesthetics are stored as expressions and evaluated when the plot is rendered. So qplot(i) does not generate a plot, but rather a plot definition, using a reference to the variable i. All three plots are the same in the sense that they all reference i.

If you type

list2[[1]]

after the second loop has run, you cause the ggplot object stored in list2[[1]] to be rendered, using whatever value i is set to at the moment (which is 3 after the loop).

Try this:

i <- 4
list2[[1]]

Now the plot rendered is equivalent to qplot(4).

The workaround depends on what you are trying to achieve. The basic idea is not to use external variables in aesthetics. So in your trivial case,

for(i in 1:3){
list2[[i]]<-ggplot(data.frame(x=i), aes(x))+geom_histogram()
}

will work. This is because the reference to the external variable i is not in the aesthetics (e.g., the call to aes(...).

I have a for loop of qplots, how can you structure the plots individually using LaTeX code e.g adding captions to the plots

\documentclass{article}
\begin{document}

<<echo = FALSE, fig.cap = c("First, Second, Third"), results = "asis">>=
library(ggplot2)
for (i in 1:3) {
print(qplot(x = 1, y = i))
cat("Arbitrary \\LaTeX code! \\clearpage")
}
@

\end{document}

You can use the chunk option fig.cap to add captions to your plots. Note that this will wrap your figure in a figure environment, turning it into a float.

Use the chunk option results="asis" to be able to print arbitrary text (including LaTeX markup) into your document using cat().

Looping cut2 color argument in qplot

Your desired output is easier to achieve using ggplot() instead of qplot(), since you can use aes_string(), that accepts strings as arguments.

plotCols <- function(x) { 
cols <- names(x)
for (i in 1:length(cols)) {
assign(paste0("cutEx", i), cut2(x[, i]))

p <- ggplot(x) +
aes_string("index", "CompressiveStrength", color = paste0("cutEx", i)) +
geom_point()

print(p)
}
}

plotCols(training)

Loop through and plot columns of two identical dataframes

As you suggest, I would indeed first rearrange into a list of plottable data frames before calling the plot command. I think that would especially be the way to go if you want to feed the data argument into ggplot. Something like:

plot_dfs <- lapply(names(df1),function(nm)data.frame(col1 = df1[,nm], col2 = df2[,nm]))
for (df in plot_dfs)plot(x = df[,"col1"], y = df[,"col2"])

or using ggplot:

for (df in plot_dfs){
print(
ggplot(data = df, aes(x=col1, y=col2)) +
geom_point())}

and if you want to add the column names as plot titles, you can do:

for (idx in seq_along(plot_dfs)){
print(
ggplot(data = plot_dfs[[idx]], aes(x=col1, y=col2)) +
ggtitle(names(df1)[idx]) +
geom_point())}

How do I plot more than one series using qplot?

I Hope this helps

gplot2 works best with data in long format, like so:

  Year score  sd variable
1 1950 10 1.1 bus
2 1960 20 2.2 bus
3 1970 30 3.3 bus
4 1980 40 4.4 bus
5 1950 20 1.1 car
6 1960 20 2.2 car
7 1970 40 3.3 car
8 1980 40 4.4 car

This will get the data into R:

data <- structure(list(Year = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 
4L), class = "factor", .Label = c("1950", "1960", "1970", "1980"
)), score = c(10, 20, 30, 40, 20, 20, 40, 40), sd = c(1.1, 2.2,
3.3, 4.4, 1.1, 2.2, 3.3, 4.4), variable = c("bus", "bus", "bus",
"bus", "car", "car", "car", "car")), .Names = c("Year", "score",
"sd", "variable"), row.names = c(NA, -8L), class = "data.frame")

And this will make the plot, with dodge an all. You properbly need the dodge, because your data is overlapping. You can control the amount of dodging with the "W" value.

ggplot(data, aes(x=Year, y=score,col=variable))+
geom_point(position=position_dodge(w=0.2))+
geom_pointrange(aes(ymin=score-sd, ymax=score+sd,group=Year),position=position_dodge(w=0.2))

Background picture and loop over qplot, how can I only update the date without reprinting the rest

One way to stop the flashing is to prevent the screen from updating till all the drawing is done. Try

for (i in 1:100){ 
mdat <- data.frame(100+i*5,100+i)
colnames(mdat) <- c("X","Y")
dev.hold() #pause device update
print(plot_field)
dev.flush() #send plot to device
}


Related Topics



Leave a reply



Submit