I have a plot in R which has a very large number of sample groups, and therefore the legend is larger than the page size and is cut off. I understand that this is not publication quality, but I need to know the colours to be able to make the legend in Illustrator.
Is there a way to make the page size much bigger or somehow change the legend format so that I can include all the keys? The reason for this is so that I can open the PDF in Illustrator and get the colours for each sample to create a new legend that will be for publication. I thought that maybe there is a clipping mask, and that the actual legend will be preserved, but when I opened in Illustrator, the legend was actually cut at the page ends1.
As was suggested in the comments below I gave nrow a try which helped break the legends up but now the entire page is just legends.
ggplot(purine.n, aes(x=variable, y=value, colour=metabolite_gene, shape=variable))
+geom_abline(slope=0)
+geom_point(size=4, position=position_dodge(width=0.08))
+scale_y_continuous(limit=c(-3.5,5.5), breaks=c(-3,-2,-1,0,1,2,3,4,5))
+scale_shape_manual(values=c(16,17,17), guide=F)
+theme_bw()
+theme(legend.key=element_blank(), legend.key.size=unit(1,"point"))
+guides(colour=guide_legend(nrow=16))
As was suggested in the comments, nrow was the answer to my problem. I had to adjust the value to get the right number of rows to fit my legend. Below is the completed code that worked. There's more tweaking I need to do, like change page size to help make things look better, but that is out of the scope of this question.
ggplot(data.n, aes(x=variable, y=value, colour=metabolite_gene, shape=variable))
+geom_abline(slope=0)+geom_point(size=4, position=position_dodge(width=0.08))
+scale_y_continuous(limit=c(-3.5,5.5), breaks=c(-3,-2,-1,0,1,2,3,4,5))
+scale_shape_manual(values=c(16,17,17), guide=F)
+theme_bw()
+theme(legend.key=element_blank(), legend.key.size=unit(1,"point"))
+guides(colour=guide_legend(nrow=30))
Related
Within R-Studio, I am generating plots with ggplot, then I save them with ggsave() for further use (I know, not ideal, but non-optional right now).
My problem is that when I generate the plot before saving it, R shows it to me in a particular size. With ggsave, I set width and height, so the elements displayed shift etc. I only see this after saving the plot.
I want R to show it to me before. I thus assume that I need to set the size of the plot within ggplot() somewhere , not in ggsave().
How can I do this in the least complicated fashion?
library(ggplot2)
ggplot(mtcars, aes(mpg,disp)) + geom_point() +
labs(title="Rocket science title that will get cut by ggsave")
ggsave("rocketScience.png", width=10, height=7, unit="cm")
You can use the set_panel_size() function from the egg package.
With this function you can fix the panel size of the plot. This can be very useful when creating multiple plots that should have the exact same plotting area but use varying axis labels or something similar that would usually slightly change the panel dimensions. Especially useful for presentations with seamless animations or publications. It also ensures the same dimensions in the preview and the saved plot.
p <- ggplot(mtcars, aes(mpg,disp)) +
geom_point() +
labs(title="Rocket science title that will get cut by ggsave")
#to view the plot
gridExtra::grid.arrange(egg::set_panel_size(p=p, width=unit(5, "cm"), height=unit(7, "cm")))
#to save the plot
ggsave(filename = "myplot.pdf", plot = egg::set_panel_size(p=p, width=unit(5, "cm"), height=unit(7, "cm")))
Within ggsave you can still manipulate the size of the whole "page" saved, but this will only influence the amount of white space around the plot. The actual panel size will stay fixed.
The example plot from above with 5cm or 15cm as width:
I don't believe this is achievable via ggplot settings; you might get around it if using RMarkdown, as you can set with and height of an output of a markdown chunk via fig.width and fig.height params.
In order to save as much as white space as I can, I would like to place the legend entry at the same height as the horizontal axis label. Can this be done and if so, how?
Here's a plot illustrating what I am hoping to achieve, with current and hoped-for legend position illustrated using a (manually added) green box.
I currently place the legend using theme(legend.position=c(0.87,0.1)) (noting that the exact coordinates are not relevant). Ideally, this route would allow for values outside of the [0,1] domain but it appears not to allow for that.
theme(legend.position="bottom") places the legend well outside of the plotting area, thus taking up more white space than I am willing to spare.
You just might have to play around with negative values regarding the y-coordinates of your legend.position-vector.
Here's an example:
library(ggplot2)
ggplot(iris, aes(Sepal.Width, Sepal.Length, color=Species))+
geom_line()+
facet_wrap(~Species)+
theme(legend.position=c(0.87,-0.01))
Note the -0.01 value. Is this what you're looking for?
I am trying to stack plots with common x- and y-axes in ggplot. What I want to do is have only the bottom plot show the x-axis labels and titles. But I've never been able to figure out how to do this cleanly in ggplot2 without having the bottom plot be squished by carrying the virtue of the x-axis labels/title. There must be an easy way to do this- everyone wants to stack graphs, right?!
I'm currently trying with ggarrange. Example code below. Note that the bottom plot gets compressed vertically because it has the tick and axis labels. I could just have the top two have white font labels/title, but then there is an unseemly amount of margin space between the three if you use that hack.
I'm definitely open to packages other than gpubr, but I am hoping for something not too elaborate that I can use in subsequent situations, as I'm sure I'll encounter this again...
Help, please!! -Ryan
#
require(ggplot2); require(ggpubr)
X=data.frame(seq(as.Date("2001-01-01"),as.Date("2001-12-31"),by='days')); colnames(X)='date'
X$Y1=sample(80:100,size=nrow(X),replace=T)
X$Y2=sample(100:120,size=nrow(X),replace=T)
X$Y3=sample(50:70,size=nrow(X),replace=T)
plot.Y1= ggplot(X, aes(x=date,y=Y1))+
geom_line()+lims(y=c(50,150))+
theme(axis.title.x = element_blank(),axis.text.x=element_blank())
plot.Y2= ggplot(X, aes(x=date,y=Y2))+
geom_line()+lims(y=c(50,150))+
theme(axis.title.x = element_blank(),axis.text.x=element_blank())
plot.Y3= ggplot(X, aes(x=date,y=Y3))+
geom_line()+lims(y=c(50,150))
x11(10,8)
ggarrange(plot.Y1,plot.Y2,plot.Y3,nrow=3,ncol=1)
Bottom plot is squished!
try this,
egg::ggarrange(plot.Y1,plot.Y2,plot.Y3,ncol=1)
I don't have to mention I am new, and my problem has too many solutions. I tried about 12 different versions and couldn't solve it:
The example given is close to my desired plot I want to generate.
I overtook a given script from 2013, so I do not entirely understand what to do to change it in the way I would like:
Plot 1's legend in the bottom right corner without a title, transparent background and instead of 1 and 2 the labels "urban" and "non-urban".I am aware that "legend.position="none"" delets all legends, but was not able to find a solution that looked like at least close to this. Still it is not on the plot, not transparent and has a title.
Unfortunately somehow the dots changed into squares in this process and I have no clue why. I didn't change geom_point.
Another flaw I want to change is to remove the top line over the central plot. But how?
And last but not least I am not sure if the function geom.mooth(method=lm) does reflect the regression line + confidence interval, because the description says it adds a conditional mean which is, afaIk, not the same. Is my concern unnecessary?
Edit: shorter Version plot1 out of 3 merged plots:
library(ggplot2)
library(gridExtra)
set.seed(42)
DF <- data.frame(x=rnorm(100,mean=c(1,5)),y=rlnorm(100,meanlog=c(8,6)),group=1:2)
p1 <- ggplot(DF,aes(x=x,y=y,colour=factor(group))) + geom_point(shape=16) +
scale_x_continuous(expand=c(0.02,0)) +
scale_y_continuous(expand=c(0.02,0)) +
geom_rug() +
geom_smooth(method=lm,alpha=0.3) +
theme_bw()+
theme(legend.position=c(0.9,0.09),
legend.title=element_blank(),
plot.margin=unit(c(0,0,0,0),
"points"))
Thanks for any advice, I am researching on this topic since 2 weeks, even though I thought I am studying psychology, I learned a lot ... but not enough in the short time to success. :/
I want to draw a bar plot, with ggplot and geom_bar, but it seems that the behavior of geom_bar is not consistent. I don't understand why.
My data is a time series of precipitations:
library(ggplot2)
library(data.table)
library(lubridate)
set.seed(42)
dt1 <- data.table(dateHeure=seq(ymd_hms("2014-06-04 13:30:00"),
ymd_hms("2014-10-20 08:30:00"), by='1 hour'),
rain=sample(c(rep(5,15), rep(10,15), rep(20,10),
rep(30, 5), 40, rep(0, 3262))))
Then i plot it, and not all the data appears... Why is some data missing?
ggplot(data=dt1)+
geom_bar(aes(x=dateHeure, y=rain),
stat="identity",
fill="blue") # doesn't work!
But if i add the variable color in aes, then the plot is correct!
ggplot(data=dt1)+
geom_bar(aes(x=dateHeure, y=rain, color="rain"),
stat="identity",
width=0.2) # work properly
So someone know why geom_bar doesn't work properly without color? Because i can't rely on it if sometimes not all the data is correctly plotted...
thanks!
edit: to respond to #eipi10, i added the plots. The strange thing is that when i resize the plot window in the first case, the data which is plotted changes!
Based on the edit to your question, I think I know what's happening: In the first plot, you use fill="blue". But the bin widths are very small compared to the overall range of the x-axis. This results in very, very thin vertical bars--so thin that you can't see some of them on your screen, but they appear when you expand the physical width of the plot.
On the other hand, in your second plot you used colour="rain", which adds a border to each bar, making each bar thicker, so they are visible, even when the physical width of the plot is relatively small.
Try adding colour="blue"(or "red" or whatever) to your first plot and I think you'll see all the bars, even without resizing. On the other hand, try changing colour="rain" to fill="rain" on your second plot and see if that creates the "disappearing data" effect on your second plot.
UPDATE: In response to your comment, you can use the colour parameter and then set the line width to get exactly the bar thickness you want, so you don't really need fill. For example:
ggplot(data=dt1)+
geom_bar(aes(x=dateHeure, y=rain),
stat="identity",
colour="blue", lwd=0.5)
Just set lwd (line width) to a value that gives you the bar-width you want. And, of course, you can also change the colour as well.