[R] multiple graphs with a single legend and trellis graph
Rosa Oliveira
rosita21 at gmail.com
Wed Jul 8 15:14:14 CEST 2015
Dear Jim,
first of all, thank you very much :)
can you please explain me how to use split.screen?
I attach my previous graphs and my data, so you can see :)
I’m very naive and new in R :(
I really tried:
library(plotrix)
# start a wide plotting device
x11(width=10,height=4)
y<-runif(100)
oldpar<-panes(matrix(1:6,nrow=2,byrow=TRUE),widths=c(1,1,1.7))
par(mar=c(0,2,1.8,0))
mse <- plot(mse.alpha1$lambda[mse.alpha1$nsample==50],
mse.alpha1$mse.naive[mse.alpha1$nsample==50],
xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
xlim=c(.6,1), ylim=c(0,1), cex.lab=1.5
#,main="yaxs default"
)
lines(mse.alpha1$lambda[mse.alpha1$nsample==50],mse.alpha1$mse.RegCal[mse.alpha1$nsample==50],col=2,lty=2)
lines(mse.alpha1$lambda[mse.alpha1$nsample==50],mse.alpha1$mse.PL[mse.alpha1$nsample==50],col=3,lty=3)
tab.title("alpha 1 N sample=50",tab.col="#88dd88",cex=1)
# tab.title("\n\n sample size=50")
# problem: when I run: tab.title("Mean squared error for ", paste(alpha[1]))",tab.col="#88dd88",cex=1)
# I get an error message: unexpected string constant in "tab.title("Mean squared error for ", paste(alpha[1]))",tab.col=""
# I searched but wasn't able to fix this one, neither the other "subtitle":
# tab.title("\n\n sample size=50")
box()
par(mar=c(0,0,1.8,0))
plot(mse.alpha1$lambda[mse.alpha1$nsample==250],
mse.alpha1$mse.naive[mse.alpha1$nsample==250],
xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
xlim=c(.6,1), ylim=c(0,1), cex.lab=1.5
#,main="yaxs default"
)
lines(mse.alpha1$lambda[mse.alpha1$nsample==250],mse.alpha1$mse.RegCal[mse.alpha1$nsample==250],col=2,lty=2)
lines(mse.alpha1$lambda[mse.alpha1$nsample==250],mse.alpha1$mse.PL[mse.alpha1$nsample==250],col=3,lty=3)
tab.title ( "alpha 1 N sample=250",tab.col="#dd8800",cex=1)
box()
plot(mse.alpha1$lambda[mse.alpha1$nsample==1000],
mse.alpha1$mse.naive[mse.alpha1$nsample== 1000],
xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
xlim=c(.6,1), ylim=c(0,1), cex.lab=1.5
#,main="yaxs default"
)
lines(mse.alpha1$lambda[mse.alpha1$nsample== 1000],mse.alpha1$mse.RegCal[mse.alpha1$nsample== 1000],col=2,lty=2)
lines(mse.alpha1$lambda[mse.alpha1$nsample== 1000],mse.alpha1$mse.PL[mse.alpha1$nsample== 1000],col=3,lty=3)
tab.title("alpha 1 N sample=1000",tab.col="#8888dd",cex=1)
box()
par(mar=c(2,2,1.8,0))
plot(mse.alpha2$lambda[mse.alpha2$nsample==50],
mse.alpha2$mse.naive[mse.alpha2$nsample==50],
xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
xlim=c(.6,1), ylim=c(0,.17), cex.lab=1.5
#,main="yaxs default"
)
lines(mse.alpha2$lambda[mse.alpha2$nsample==50],mse.alpha2$mse.RegCal[mse.alpha2$nsample==50],col=2,lty=2)
lines(mse.alpha2$lambda[mse.alpha2$nsample==50],mse.alpha2$mse.PL[mse.alpha2$nsample==50],col=3,lty=3)
box()
tab.title("alpha 2 N sample=50",tab.col="#aabbcc",cex=1)
par(mar=c(2,0,1.8,0))
plot(mse.alpha2$lambda[mse.alpha2$nsample==250],
mse.alpha2$mse.naive[mse.alpha2$nsample==250],
xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
xlim=c(.6,1), ylim=c(0,.17), cex.lab=1.5
#,main="yaxs default"
)
lines(mse.alpha2$lambda[mse.alpha2$nsample==250],mse.alpha2$mse.RegCal[mse.alpha2$nsample==250],col=2,lty=2)
lines(mse.alpha2$lambda[mse.alpha2$nsample==250],mse.alpha2$mse.PL[mse.alpha2$nsample==250],col=3,lty=3)
box()
tab.title("alpha 2 N sample=250",tab.col="#ddbc44",cex=1)
# center the title at the middle of the fifth plot
mtext("Mean Squared Error",side=1,line=0.8,cex=1.5)
par(mar=c(2,0,1.8,12))
plot(mse.alpha2$lambda[mse.alpha2$nsample==1000],
mse.alpha2$mse.naive[mse.alpha2$nsample== 1000],
xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
xlim=c(.6,1), ylim=c(0,.17), cex.lab=1.5
#,main="yaxs default"
)
lines(mse.alpha2$lambda[mse.alpha2$nsample== 1000],mse.alpha2$mse.RegCal[mse.alpha2$nsample==250],col=2,lty=2)
lines(mse.alpha2$lambda[mse.alpha2$nsample== 1000],mse.alpha2$mse.PL[mse.alpha2$nsample== 1000],col=3,lty=3)
box()
tab.title("alpha 2 N sample=1000",tab.col="#ff33cc",cex=1)
legend(115,1.8,
c("alpha 1 N sample=50","alpha 1 N sample=250","alpha 1 N sample=1000",
"alpha 2 N sample=50","alpha 2 N sample=250","alpha 2 N sample=1000"),
fill=c("#88dd88","#dd8800","#8888dd","#aabbcc","#ddbc44","#ff33cc"),
xpd=NA)
legend(115,1.8,
c("Naive", "Regression Calibration", "Pseudo Likelihood"),
bty = "n",col=c(4,2,3),lty=c(4,2,3),
xpd=NA)
and I got:
Thanks again for your help ;)
Atenciosamente,
Rosa Oliveira
--
____________________________________________________________________________
Rosa Celeste dos Santos Oliveira,
E-mail: rosita21 at gmail.com
Tlm: +351 939355143
Linkedin: https://pt.linkedin.com/in/rosacsoliveira
____________________________________________________________________________
"Many admire, few know"
Hippocrates
> On 08 Jul 2015, at 11:35, Dennis Murphy <djmuser at gmail.com> wrote:
>
> Hi:
>
> The general process for doing this kind of thing in either ggplot2 or
> lattice is:
>
> (1) Row concatenate the data frames, assuming they all have the same
> structure. It's a good idea to have a number or character string that
> identifies each data frame.
> (2) After concatenating the data frames, convert the identifier to a factor.
> (3) Using ggplot2 or lattice, create the core features of your plot.
> In ggplot2, the data frame identifier would be a faceting variable; in
> lattice, it would be a conditioning variable in the plot formula: y ~
> x | identifier
>
> I didn't take the time to look at your code carefully, but it appears
> this could be done pretty easily in ggplot2 and probably in lattice as
> well. One difference is that it typically takes less code to create a
> ggplot2 legend than it does to create one in lattice.
>
> Here's a reproducible toy example to illustrate how one could do this
> in principle with ggplot2.
>
> DF <- data.frame(id = factor(rep(LETTERS[1:6], each = 10)),
> v = factor(sample(1:2, 60, replace = TRUE)),
> x = seq_len(10),
> y = 0.2 + rep(seq(0.1, 0.6, by = 0.1), each = 10) *
> seq_len(10) + rnorm(60))
>
> Think of id as the row concatenation of your data frames, where it is
> assumed that each data frame has the same variables and the same
> structure. The variable v is a manufactured factor to show that you
> can make multiple plots and return one legend. The rest is simply fake
> data to fit regression lines in each sub-data frame identified with
> the same id with different true slopes in each subset but the same
> intercept. The code for the plot is
>
> library(ggplot2)
> ggplot(DF, aes(x = x, y = y)) +
> geom_point(aes(color = v)) +
> geom_smooth(method = "lm", color = "blue", se = FALSE) +
> facet_wrap(~ id, ncol = 2)
>
> The feature of interest in the produced graph is that there are six
> panels (produced by the call to facet_wrap()) but only one legend. A
> similar graphic in lattice would be
>
> library(lattice)
> xyplot(y ~ x | id, data = DF, type = c("p", "r"),
> as.table = TRUE, col = DF$v,
> auto.key = list(text = levels(DF$v),
> space = "right",
> points = TRUE))
>
> The problem with the legend in the lattice plot is that the non-red
> color in the graph is black but the corresponding color in the legend
> is blue. More work is required in lattice to accurately map the
> colors, shapes, etc. between the graph and legend. It's not worth
> going there at this point.
>
> In ggplot2, guides (axes or legends) are mappings of aesthetics (in
> this case, x, y and color) to variables (x, y and v, respectively). By
> default, ggplot2 produces a guide for each mapped aesthetic, which is
> defined within the function aes().
> When aes() is used in the ggplot() function, the mappings are global -
> i.e., they apply to all subsequent layers produced by a geom or stat
> function. When aes() is called inside a geom or stat function, the
> mapping is local to the layer produced by the geom/stat call. Wherever
> an aesthetic mapping is declared, a guide will be produced unless it
> is turned off. With this convention, it is much easier to produce
> legend guides in ggplot2 than in lattice. If you want to fine tune the
> contents of a legend, there exist functions of the form
> scale_<aesthetic>_<type>() that give you more freedom in defining
> specific colors, point shapes, etc., as well as labels in the legend.
>
> Since you did not supply a reproducible example, I would follow steps
> (1) and (2) above to arrange your data, and then follow the guidelines
> from my fake data example to produce the plot. The trick, especially
> with ggplot2, is to figure out how to produce one graph, and then use
> faceting to map that structure to all groups.
>
> From what I can tell, you'll probably need to do some type of melting
> operation with reshape2::melt() to stack the three columns Naive,
> RegCal and PL, since that is apparently what you want for the legend.
> You'll need two faceting variables: nsample and data set identifier.
> It appears as though you want to plot points and lines in each panel,
> so if you're using ggplot2, you'd use geom_point() and geom_line().
> The titles are not really necessary, as you can produce the
> information you need in the strip panels.
>
> If I read this right, you have:
>
> * two data sets
> * nsample as a faceting/conditioning variable within sample
> * lambda as the x-variable
> * points and lines for three types of response variables (MSEs) that
> are to be compared and labeled in a legend
>
> If that is correct, I'd suggest the following:
>
> 1. myDF <- rbind(mse.alpha1, mse.alpha2) # assumes both data frames
> have the same variables in the same order
> 2. myDF$ID <- factor(rep(c("alpha1", "alpha2"), times =
> c(nrow(mse.alpha1), nrow(mse.alpha2)))
> 3. Melt the three columns to be plotted, something like
>
> library(reshape2)
> myDF.melt <- melt(myDF, id = c("ID", "nsample", "lambda"), measure =
> c("Naive", "RegCal", "PL"))
>
> This will return a data frame with 3 * nrow(DF) rows and 5 columns.
> The two derived columns are named variable and value, the first of
> which returns the variable names as factor levels and the second of
> which contains the corresponding values. Then,
>
> library(ggplot2)
> ggplot(myDF.melt, aes(x = lambda, y = value, color = variable)) +
> geom_point() + geom_line() +
> facet_grid(ID ~ nsample) +
> labs(x = expression(lambda), y = "MSE", color = "Type")
>
> That's the best I can do without access to the data, so you're on your
> own to figure this out. If this doesn't work or I misperceived certain
> elements of your desired graph (a distinct possibility), then please
> re-post a _reproducible example_ back to R-help, which contains both
> data and code. You want the example to be minimal so that potential
> helpers can quickly see the problem and respond with useful
> suggestions. The length of my response in an attempt to divine the
> structure of your data punctuates the need for you to provide data +
> code + expected outcome. By helping potential helpers to help you, you
> are likely to get better and more accurate replies in much less time.
>
> HTH,
> Dennis
>
> On Tue, Jul 7, 2015 at 2:45 PM, Rosa Oliveira <rosita21 at gmail.com> wrote:
>> Iam trying to plot 6 graphs in one single plot and I was able to, nonetheless I wanted that all graphs had just 1 common legend, as the legend is the same for all the 6 graphs and there is no sense in repeating it 6 times and even more, the legends in each graph sometimes don’t fit the graph.
>>
>> Is there a way to put just one legend for all the 6 graphs ate the same time?
>>
>> I was told to use a trellis graph, but after days of trying to do that I wasn’t able to.
>>
>> Can anyone help me?
>>
>>
>> library(ggplot2)
>> library(reshape)
>> library(lattice)
>>
>> par(mfrow=c(2,3))
>> mse.alpha1 <-read.csv(file="graphs_mse_alpha1.csv",head=TRUE,sep=",")
>> attach(mse.alpha1)
>> names(mse1000.alpha1)
>> mse.alpha2 <-read.csv(file="graphs_mse_alpha2.csv",head=TRUE,sep=",")
>> attach(mse.alpha2)
>> names(mse.alpha2)
>> nsample==50
>>
>> plot(mse.alpha1$lambda[mse.alpha1$nsample==50],
>> mse.alpha1$mse.naive[mse.alpha1$nsample==50],
>> xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
>> xlim=c(.6,1), ylim=c(0,1), cex.lab=1.5
>> )
>> lines(mse.alpha1$lambda[mse.alpha1$nsample==50],mse.alpha1$mse.RegCal[mse.alpha1$nsample==50],col=2,lty=2)
>> lines(mse.alpha1$lambda[mse.alpha1$nsample==50],mse.alpha1$mse.PL[mse.alpha1$nsample==50],col=3,lty=3)
>> title ( expression (paste ("Mean squared error for ", alpha[1])), cex.main=1.5)
>> title("\n\n sample size=50")
>> legend(.7,1, legend= c("Naive", "Regression Calibration", "Pseudo Likelihood"), bty = "n",col=c(4,2,3),lty=c(4,2,3))
>>
>> plot(mse.alpha1$lambda[mse.alpha1$nsample==250],
>> mse.alpha1$mse.naive[mse.alpha1$nsample==250],
>> xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
>> xlim=c(.6,1), ylim=c(0,1), cex.lab=1.5
>> )
>> lines(mse.alpha1$lambda[mse.alpha1$nsample==250],mse.alpha1$mse.RegCal[mse.alpha1$nsample==250],col=2,lty=2)
>> lines(mse.alpha1$lambda[mse.alpha1$nsample==250],mse.alpha1$mse.PL[mse.alpha1$nsample==250],col=3,lty=3)
>> title ( expression (paste ("Mean squared error for ", alpha[1])), cex.main=1.5)
>> title("\n\n sample size=250")
>> legend(.7,1, legend= c("Naive", "Regression Calibration", "Pseudo Likelihood"), bty = "n",col=c(4,2,3),lty=c(4,2,3))
>>
>>
>> plot(mse.alpha1$lambda[mse.alpha1$nsample==1000],
>> mse.alpha1$mse.naive[mse.alpha1$nsample== 1000],
>> xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
>> xlim=c(.6,1), ylim=c(0,1), cex.lab=1.5
>> )
>> lines(mse.alpha1$lambda[mse.alpha1$nsample== 1000],mse.alpha1$mse.RegCal[mse.alpha1$nsample== 1000],col=2,lty=2)
>> lines(mse.alpha1$lambda[mse.alpha1$nsample== 1000],mse.alpha1$mse.PL[mse.alpha1$nsample== 1000],col=3,lty=3)
>> title ( expression (paste ("Mean squared error for ", alpha[1])), cex.main=1.5)
>> title("\n\n sample size=1000")
>> legend(.7,1, legend= c("Naive", "Regression Calibration", "Pseudo Likelihood"), bty = "n",col=c(4,2,3),lty=c(4,2,3))
>>
>> plot(mse.alpha2$lambda[mse.alpha2$nsample==50],
>> mse.alpha2$mse.naive[mse.alpha2$nsample==50],
>> xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
>> xlim=c(.6,1), ylim=c(0,.17), cex.lab=1.5
>> )
>> lines(mse.alpha2$lambda[mse.alpha2$nsample==50],mse.alpha2$mse.RegCal[mse.alpha2$nsample==50],col=2,lty=2)
>> lines(mse.alpha2$lambda[mse.alpha2$nsample==50],mse.alpha2$mse.PL[mse.alpha2$nsample==50],col=3,lty=3)
>> title ( expression (paste ("Mean squared error for ", alpha[2])), cex.main=1.5)
>> title("\n\n sample size=50")
>> legend(.7,.17, legend= c("Naive", "Regression Calibration", "Pseudo Likelihood"), bty = "n",col=c(4,2,3),lty=c(4,2,3))
>>
>>
>> plot(mse.alpha2$lambda[mse.alpha2$nsample==250],
>> mse.alpha2$mse.naive[mse.alpha2$nsample==250],
>> xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
>> xlim=c(.6,1), ylim=c(0,.17), cex.lab=1.5
>> )
>> lines(mse.alpha2$lambda[mse.alpha2$nsample==250],mse.alpha2$mse.RegCal[mse.alpha2$nsample==250],col=2,lty=2)
>> lines(mse.alpha2$lambda[mse.alpha2$nsample==250],mse.alpha2$mse.PL[mse.alpha2$nsample==250],col=3,lty=3)
>> title ( expression (paste ("Mean squared error for ", alpha[2])), cex.main=1.5)
>> title("\n\n sample size=250")
>> legend(.7,.17, legend= c("Naive", "Regression Calibration", "Pseudo Likelihood"), bty = "n",col=c(4,2,3),lty=c(4,2,3))
>>
>> plot(mse.alpha2$lambda[mse.alpha2$nsample==1000],
>> mse.alpha2$mse.naive[mse.alpha2$nsample== 1000],
>> xlab=expression(paste(lambda)),ylab="MSE",type="l",col=4,lty=4,
>> xlim=c(.6,1), ylim=c(0,.17), cex.lab=1.5
>> )
>> lines(mse.alpha2$lambda[mse.alpha2$nsample== 1000],mse.alpha2$mse.RegCal[mse.alpha2$nsample==250],col=2,lty=2)
>> lines(mse.alpha2$lambda[mse.alpha2$nsample== 1000],mse.alpha2$mse.PL[mse.alpha2$nsample== 1000],col=3,lty=3)
>> title ( expression (paste ("Mean squared error for ", alpha[2])), cex.main=1.5)
>> title("\n\n sample size=1000")
>> legend(.7,.17, legend= c("Naive", "Regression Calibration", "Pseudo Likelihood"), bty = "n",col=c(4,2,3),lty=c(4,2,3))
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> Atenciosamente,
>> Rosa Oliveira
>>
>> --
>> ____________________________________________________________________________
>>
>>
>> Rosa Celeste dos Santos Oliveira,
>>
>> E-mail: rosita21 at gmail.com
>> Tlm: +351 939355143
>> Linkedin: https://pt.linkedin.com/in/rosacsoliveira
>> ____________________________________________________________________________
>> "Many admire, few know"
>> Hippocrates
>>
>> ______________________________________________
>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list