I'm relatively new to ggplot, so I apologize if this is easy, but I couldn't find anything online.
I want to display 29 boxplots (numbered 1.1 to 4.0) next to each other in ggplot2 (which I can do) but once I make the tick label the appropriate size (which I can do), the labels overlap and I only want a few (1.5, 2, 2.5 etc) anyways. How can I remove only some of the tick labels? Also, anyway I can include a blank tick mark at 1.0 so my tick labels are nice, round numbers?
My data is list which I 'melted' since each boxplot has a different number of observations.
My current code:
list = list(data11, data12, ... data39, data40) # Elipse denotes the rest of the sequence
df = melt(list)
ggplot(df, aes(factor(variable), value)) +
geom_boxplot(outlier.size=1.5, colour="black") +
xlab("Xlabel") +
ylab("Ylabel") +
theme_classic() +
theme(
axis.text.x = element_text(size=12),
axis.text.y = element_text(size=12),
axis.title.x = element_text(size=14),
axis.title.y = element_text(size=14, angle=90),
axis.line = element_line(size=0.75)
)
This is not a difficult question indeed. The key idea can be easily found here.
Basically, you are missing a single line of code. Since you did not share a sample of your data (shame on you! see this), I generated some. Here's the solution:
df.so1 <- runif(10); df.so2 <- runif(10); df.so3 <- runif(10)
list.so = list(df.so1, df.so2, df.so3)
df.so = melt(list.so)
ggplot(df.so, aes(factor(L1), value)) +
geom_boxplot(outlier.size=1.5, colour="black") +
xlab("Xlabel") + ylab("Ylabel") +
theme_classic() +
theme(
axis.text.x = element_text(size=12),
axis.text.y = element_text(size=12),
axis.title.x = element_text(size=14),
axis.title.y = element_text(size=14, angle=90),
axis.line = element_line(size=0.75)
) +
scale_x_discrete(breaks = c(1,3))
Note that you have full control over axis, ticks, tick labels, etc. See ggplot2 documentation for more.
Upd.
Don't forget to check out related questions before posting: bump1, bump2.
Related
I've tried everywhere to find a solution for my problem, without success.
In my company we have a R project, where we use our own colors to print the plots. One of our colleagues is having trouble with it, and we can't figure it out why (since the plot is working fine for all other colleagues and we all -including her- have the same version of R, R Studio and packages).
The problem is when she is printing the plots, the legend is totally weird and printing way more information (from other plots). We tried everything we could think of...
Unfortunetely I can't display the whole code/plots since is confidential information, but I hope this can help:
correct plot should look like this
incorrect plot look like this
The code is more or less, this one:
ggplot(df , aes(x = factor(columnA), y = value ,fill=factor(variable))) +
geom_bar(stat='identity',position="stack")+
labs(x=element_blank(),y="label")+
scale_x_discrete(breaks = df$columnA ,labels=str_wrap(df$columnB, 15) ) +
ggtitle("Confidential tile") +
theme_ourown + #we have our own theme as well
theme(panel.grid.major = element_line(colour = "grey90"),
axis.ticks = element_blank(), axis.title = element_blank(), axis.text.x = element_text(colour = "grey30"),
axis.text.y = element_blank(), legend.title = element_blank(), plot.title = element_text(hjust = 0.5),
legend.text = element_text(size = rel(1.33)), legend.key.size = unit(1, "cm")) +
scale_fill_manual(values = report_colours) + #here is our colors
coord_polar()
Well, thank you all in advance!
I want to add a legend it shows black for the 7 day moving average and blue for the bars(daily cases). so it looks something similar to the NHS graph , but the legend does not work when i add it into my code?
ggplot(LimerickNew1, aes(x=TimeStamp, y=DailyCCase,Shape=MA7)) +
geom_bar(stat="identity",fill="steelblue") +
geom_line(aes(y=MA7),size=1.5) +
labs( x="", y="Total cases", title="Total Covid Cases for County Limerick 01-03-20 to 01-
06-`20" )+`
theme_bw()+
theme(legend.background = element_rect(fill = "darkgray"),
legend.key = element_rect(fill = "lightblue", color = NA),
legend.key.size = unit(1.5, "cm"),
legend.key.width = unit(0.5,"cm"),
axis.text.x = element_text(face="bold", color="#008000",size=12, angle=0),
axis.text.y = element_text(face="bold", color="#008000",size=12, angle=0),
axis.title.x = element_text(face="bold", size=12, color="black"),
plot.title = element_text( face = "bold", colour = "black", size = 20,, hjust = 0.5))
Without a reproducible example, it's hard to give a more specific answer for your question, but here's a method that expands upon the comment from #teunbrand and should guide you toward showing a legend.
TL;DR - The reason you're not seeing a legend is because you do not have any layers or geoms drawn that have one of the aesthetics mapped to aes(). All aesthetics like color, size, and fill are specified for each geom outside of an aes() function, which means there's no reason for ggplot2 to draw a legend. To get a legend to be drawn, you need to specify the aesthetic inside aes().
Example
Here's an illustrative example that is similar to OP's question.
library(ggplot2)
set.seed(8675309)
df <- data.frame(
x = 1:100,
y = rnorm(100, 10))
df$z <- log(cumsum(df$y))
ggplot(df, aes(x=x)) +
geom_col(aes(y=y), fill='blue', alpha=0.3) +
geom_line(aes(y=z), size=2) +
ylim(0,25) + theme_bw()
Showing a Legend
To get a legend to show, you have to specify one or more aesthetics inside aes(). The fun fact here is that you don't have to specify a column in the dataset when doing this. If you specify a single value, it will apply to the whole dataset, and basically just show a legend key for the entire set of observations. This is what we want.
ggplot(df, aes(x=x)) +
geom_col(aes(y=y, fill="the columns"), alpha=0.3) +
geom_line(aes(y=z, size="the line"), color="black") +
ylim(0,25) + theme_bw()
Formatting
The names come from the values specified in aes(), and the color change is due to default mapping of color values. To get things to look "right", you want to use some theme() elements to:
keep only one name
squish legends together
position on the chart, rather than on the side
The end result is here:
ggplot(df, aes(x=x)) +
geom_col(aes(y=y, fill="the columns"), alpha=0.3) +
geom_line(aes(y=z, size="the line"), color="black") +
ylim(0,25) +
scale_fill_manual(values="blue") + # recolor the columns
guides(
fill=guide_legend(title="My Legend", order=1),
size=guide_legend(title=NULL, order=2)
) +
theme_bw() +
# legend placement and spacing
theme(
legend.title = element_text(margin=margin(b=10)),
legend.spacing.y = unit(-3,'pt'),
legend.position = c(0.8, 0.8)
)
This is a follow up of Question How to fit custom long annotations geom_text inside plot area for a Donuts plot?. See the accepted answer, the resulting plot understandably has extra blank area on the top and on the bottom. How can I get rid of those extra blank areas? I looked at theme aspect.ratio but this is not what I intend though it does the job but distorts the plot. I'm after cropping the plot from a square to a landscape form.
How can I do that?
UPDATE This is a self contained example of my use-case:
library(ggplot2); library(dplyr); library(stringr)
df <- data.frame(group = c("Cars", "Trucks", "Motorbikes"),n = c(25, 25, 50),
label2=c("Cars are blah blah blah", "Trucks some of the best in town", "Motorbikes are great if you ..."))
df$ymax = cumsum(df$n)
df$ymin = cumsum(df$n)-df$n
df$ypos = df$ymin+df$n/2
df$hjust = c(0,0,1)
ggplot(df %>%
mutate(label2 = str_wrap(label2, width = 10)), #change width to adjust width of annotations
aes(x="", y=n, fill=group)) +
geom_rect(aes_string(ymax="ymax", ymin="ymin", xmax="2.5", xmin="2.0")) +
expand_limits(x = c(2, 4)) + #change x-axis range limits here
# no change to theme
theme(axis.title=element_blank(),axis.text=element_blank(),
panel.background = element_rect(fill = "white", colour = "grey50"),
panel.grid=element_blank(),
axis.ticks.length=unit(0,"cm"),axis.ticks.margin=unit(0,"cm"),
legend.position="none",panel.spacing=unit(0,"lines"),
plot.margin=unit(c(0,0,0,0),"lines"),complete=TRUE) +
geom_text(aes_string(label="label2",x="3",y="ypos",hjust="hjust")) +
coord_polar("y", start=0) + scale_x_discrete()
And this is the result I'd like to find an answer to fix those annotated resulting blank spaces:
This is a multi-part solution to answer this and the other related question you've posted.
First, for changing the margins in a single graph, #Keith_H was on the right track; using plot.margin inside theme() is a convenient way. However, as mentioned, this alone won't solve the issue if the goal is to combine multiple plots, as in the case of the other question linked above.
To do that you'll need a combination of plot.margin and a specific plotting order within arrangeGrob(). You'll need a specific order because plots get printed in the order you call them, and because of that, it will be easier to change the margins of plots that are layered behind other plots, instead of in front of plots. We can think of it like covering the plot margins we want to shrink by expanding the plot on top of the one we want to shrink. See the graphs below for illustration:
Before plot.margin setting:
#Main code for the 1st graph can be found in the original question.
After plot.margin setting:
#Main code for 2nd graph:
ggplot(df %>%
mutate(label2 = str_wrap(label2, width = 10)),
aes(x="", y=n, fill=group)) +
geom_rect(aes_string(ymax="ymax", ymin="ymin", xmax="2.5", xmin="2.0")) +
geom_text(aes_string(label="label2",x="3",y="ypos",hjust="hjust")) +
coord_polar(theta='y') +
expand_limits(x = c(2, 4)) +
guides(fill=guide_legend(override.aes=list(colour=NA))) +
theme(axis.line = element_blank(),
axis.ticks=element_blank(),
axis.title=element_blank(),
axis.text.y=element_blank(),
axis.text.x=element_blank(),
panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "white"),
plot.margin = unit(c(-2, 0, -2, -.1), "cm"),
legend.position = "none") +
scale_x_discrete(limits=c(0, 1))
After combining plot.margin setting and arrangeGrob() reordering:
#Main code for 3rd graph:
p1 <- ggplot(mtcars,aes(x=1:nrow(mtcars),y=mpg)) + geom_point()
p2 <- ggplot(df %>%
mutate(label2 = str_wrap(label2, width = 10)), #change width to adjust width of annotations
aes(x="", y=n, fill=group)) +
geom_rect(aes_string(ymax="ymax", ymin="ymin", xmax="2.5", xmin="2.0")) +
geom_text(aes_string(label="label2",x="3",y="ypos",hjust="hjust")) +
coord_polar(theta='y') +
expand_limits(x = c(2, 4)) + #change x-axis range limits here
guides(fill=guide_legend(override.aes=list(colour=NA))) +
theme(axis.line = element_blank(),
axis.ticks=element_blank(),
axis.title=element_blank(),
axis.text.y=element_blank(),
axis.text.x=element_blank(),
panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "white"),
plot.margin = unit(c(-2, 0, -2, -.1), "cm"),
legend.position = "none") +
scale_x_discrete(limits=c(0, 1))
final <- arrangeGrob(p2,p1,layout_matrix = rbind(c(1),c(2)),
widths=c(4),heights=c(2.5,4),respect=TRUE)
Note that in the final code, I reversed the order you had in the arrangeGrob from p1,p2 to p2,p1. I then adjusted the height of the first object plotted, which is the one we want to shrink. This adjustment allows the earlier plot.margin adjustment to take effect, and as that takes effect, the graph printed last in order, which is P1, will start to take the space of what was the margins of P2. If you make one of these adjustments with out the others, the solution won't work. Each of these steps are important to produce the end result above.
You can set the plot.margins to negative values for the top and bottom of the plot.
plot.margin=unit(c(-4,0,-4,0),"cm"),complete=TRUE)
edit: here is the output:
I am plotting an interaction with ggplot using a script from last year. Last year this worked fine, but now that I installed a new version of ggplot2, it seems to have issues. The first issues was that the classic theme was not able to plot the X and Y-axis. I managed to solved this by adding it to the theme formatting. But now, stat_smooth produces three confidence bands when I have a two-level factor. Not sure why this is happening.
This is the code:
gp <- ggplot(data=myData, aes(x=Sbfld,y=mem,colour=factor(status))) + geom_point(shape=17, size=8, na.rm=TRUE)
gp <- gp +
stat_smooth(method="lm", size=2, na.rm=TRUE) +
scale_y_continuous(breaks=seq(-4, max(mem)*1.1, 0.5)) +
theme_classic(base_size=35) +
theme(legend.position="bottom",
legend.title=element_blank(),
legend.text=element_text(size=30, face="bold"),
legend.key.size=unit(2, "cm"),
legend.background = element_rect(colour="black"))+
theme(axis.line.x=element_line(colour="black", size=0.5, linetype="solid"),
axis.line.y=element_line(colour="black", size=0.5, linetype="solid"),
axis.title.y=element_text(vjust=1.6, size = 40, face="bold"),
axis.title.x = element_text(vjust=-0.2, size = 40, face="bold"),
axis.text.x = element_text(size=25,colour="#333333"),
axis.text.y = element_text(size=25,colour="#333333"),
panel.grid.minor=element_blank())
Status has two levels: positive and negative and there are about 7 missing values. X and Y are continuous and there are no missing values there.
This is the output:ggplotoutput
Is this a bug in ggplot? Does anybody know how to solve this?
Thanks!
I am struggling to get the date format right. The data is already in the melt() format. There are four variables in the data which happened to share the same data. I just like to plot a simple line chart with four lines(each variable as an indidividual line) and to display Sep-12 as the latest data point? I am using the older ggplot. Feel free to I have two questions.
First question: How to display the data quarterly (the date intervals are Sep-11, Dec-11,
Mar-12, Jun-12 and Sep-12)?
Second question: How to suppress the grid lines and the grey background?
x4.1.m<-structure(list(Var.1=structure(c(1L,2L,3L,4L,5L,6L,1L,2L,3L,4L,5L,6L,1L,2L,3L,4L,5L,6L,1L,2L,3L,4L,5L,6L,1L,2L,3L,4L,5L,6L),.Label=c("I'vechangedforwork/anewjob/goneonaworkplan","Iwantaphonethat2degreesdoesn'toffer","IwantBestMates/Favourites","Iwasofferedorsawabetterofferonanothernetwork","Issueswiththe2degreesnetwork(poorcoverage)","Other"),class="factor"),YearQuarter=structure(c(1L,1L,1L,1L,1L,1L,2L,2L,2L,2L,2L,2L,3L,3L,3L,3L,3L,3L,4L,4L,4L,4L,4L,4L,5L,5L,5L,5L,5L,5L),.Label=c("2011-09-01","2011-12-01","2012-03-01","2012-06-01","2012-09-01"),class="factor"),value=c(0.23,0.23,0.121,0.25,0.223,0.14,0.39,0.22,0.05,0.37,0.25,0.2,0.09,0.14,0.05,0.3,0.4,0.12,0.13,0.1,0.26,0.38,0.28,0.15,0.33,0.05,0.06,0.44,0.32,0.43)),.Names=c("Var.1","YearQuarter","value"),row.names=c(NA,-30L),class="data.frame")
x4.1.m$YearQuarter <- format(as.Date(x4.1.m$YearQuarter),"%b-%y")
x4.line <- ggplot(data=x4.1.m, aes(x=factor(YearQuarter), y=value,colour=Var.1)) +
geom_smooth(se=F, size=1.5)+labs(y="Percentage",x="Year Quarter")
x4.line+geom_text(aes(label =paste(round(value*100,0), "%", sep=""),group=Var.1),
size = 3, hjust = 0.5, vjust =1.5) +
opts(axis.line = theme_segment(colour = "black"),
panel.grid.major = theme_blank(),
panel.background=theme_blank(),
panel.grid.minor = theme_blank(),
panel.border = theme_blank()) +
scale_y_continuous("Percentage",labels=percent, limits=c(0,0.5)) +
ggtitle("Percentages:Main Reasons for Leaving 2degrees by Quarter") +
theme(plot.title = element_text(size=rel(1.2)))
Unfortunatly, the question is not clear , I can't be sur for the answer. but the final result seems good.
I change your code because I ma using last version of ggplot2.
I don't find a problem with date format ,but you are a little bit confusing with ggplot2.
Notice I l added scales package for percent formatting.
library(scales)
library(ggplot2)
###data
x4.1.m$YearQuarter <- as.Date(x4.1.m$YearQuarter)
x4.1.m$label <- paste(round(x4.1.m$value*100,0), "%", sep="")
### plot
x4.line <- ggplot(data=x4.1.m, aes(x=YearQuarter, y=value,colour=Var.1,group = Var.1))
x4.line <- x4.line + geom_smooth(se=F, size=1.5)
x4.line <- x4.line + geom_text(aes(label = label),size = 3, hjust = 0.5, vjust =1.5)
### theme
x4.line <- x4.line + theme(axis.line = element_line(colour = "black"),
panel.grid.major = element_blank(),
panel.background=element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank())
x4.line <- x4.line + ggtitle("Percentages:Main Reasons for Leaving 2degrees by Quarter") +
theme(plot.title = element_text(size=rel(1.2)))+
scale_y_continuous(labels=percent, limits=c(0,0.5)) +
scale_x_date(labels = date_format("%b-%y"))+
labs(y="Percentage",x="Year Quarter")
x4.line