I have the following barplot which was produced from the data-set 'temp' (the data is situated at the bottom of this stack overflow page and can also be found by following this link above).
PROBLEM
The objective is to add a legend to the right hand side of the barplot (above) titled as Canopy Type with labels denoting Under Canopy and Open Canopy.
I tried using scale_colour_manual as given in another stackoverflow answer but I can't get a legend to show up.
If anyone can help, then many thanks in advance
The code to generate the barplot was:
Assuming you want to plot means of Canopy_Index for each Under_Open, Topography cell, you can form means first:
df.means <- aggregate(Canopy_Index ~ Under_Open + Topography, df.melt, mean)
Then, plot df.means using the code from your question:
ggplot(df.means, aes(x = Topography, y = Canopy_Index,
fill = factor(Under_Open), group = Under_Open)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_discrete(name = "Topographical Feature",
breaks = c("Under_tree", "Open_Canopy"),
labels = c("Under Canopy", "Open Canopy")) +
xlab("Topographical Feature") + ylab("Canopy Index") +
scale_colour_manual("Canopy Type", values = c("red", "blue")) +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
text = element_text(size=14)) +
theme(panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank()) +
theme(axis.line.x = element_line(color="black", size = 0.8),
axis.line.y = element_line(color="black", size = 0.8))
Many thanks to 'Thales' for providing the code to resolve this problem
Code to produce the barplot with associated legend:
ggplot(df.means, aes(x=Topography, y=Canopy_Index,fill=Under_Open)) +
geom_bar(stat="identity", position="dodge") +
scale_fill_discrete(name="Canopy Type",
breaks=c("Under_tree", "Open_Canopy"),
labels=c("Under Canopy", "Open Canopy")) +
xlab("Topographical Feature") + ylab("Canopy Index")
Barplot
Related
It took me hours to find how to add a y axis label after I hide y axis. Basically, I wish to make a plot like figure 1 as attached enter image description here, so y axis shows label as "Individuals", and x as "Trait", and labels for legend as "Trait response", with 3 values, 0=low, 1=average, 2=high.
I searched various sources, and did not find a solution, so appreciating any help. My data include the following variables:
ID: 1 to 25, and
4 main variables, each has 3 values, 0 (low response), 1 (average response) and 2 (high response)
And I would like to make a plot like figure 1 as attached above.
My initial R codes as below:
ggplot(melt_df, aes(x = variable, y = PID, fill = value)) + geom_tile() +
scale_fill_manual(values = c("Red", "Black", "Green" )) + theme_classic() +
theme(axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank())
It produced a plot without y axis label and legend labels as attached figure 2 enter image description here .
Then I continued to modify my codes based on R CHEAT SHEET below:
ggplot(melt_df, aes(x = variable, y = PID, fill = value)) + geom_tile() +
scale_fill_manual(values = c("Red", "Black", "Green" )) + theme_classic() +
theme(axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank()) +
xlab("Trait") +
ylab("Individuals") +
scale_fill_discrete(name = "Trait response", labels=c('Low', 'Average', 'High'))
It created a figure as attached with colors change not as expected and without y axis label enter image description here.
The reasons I like to hide y axis label just because I don't want to display values, so it can be neatly presented like a heatmap, but then when I added label for y, it did not work.
Therefore, I appreciate if any of our members could land a solution.
I look forward to receiving your support. I can provide data if necessary; yet it seems there is no field to attach data via this channel.
If you want a reproduction of the figure in the 1st attachment, you want to remove y axis text, ticks and lines, and add an angle in the y title and x text. The vjust and hjust are for justification of the text to stay in their position.
You don't have to add twice a scale_fill function, since you can add labels in the _manual function.
Since you add more than 1 labels you can use the labs function to include them all in one.
ggplot(melt_df, aes(x = variable, y = PID, fill = value)) +
geom_tile() +
scale_fill_manual(values = c("Red", "Black", "Green" ),
labels = c('Low', 'Average', 'High')) +
theme_classic() +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.line.y = element_blank(),
axis.title.y = element_text(angle = 0, vjust = 0.5),
axis.text.x = element_text(angle = -45, hjust = 0)) +
labs(x = "Trait", y = "Individuals",
fill = "Trait response")
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)
)
novice user here so please be kind and gentle! :)
I am dealing with the following dataset and R script:
#Create pvalue ranges
pvalue <- c(".000 - .005",".005 - .010",".010 - .015",".015 - .020",".020 - .025",".025 - .030",".030 - .035",".035 - .040",".040 - .045",".045 - .050")
#Create frequency counts
count <- c(5000,4000,3100,2540,2390,2260,2150,2075,2050,2025)
dat <- data.frame(pvalue = pvalue, count = count)
#Create plot
myPlot <- ggplot(data=dat, aes(x=pvalue, y=count, group=1)) +
geom_line() +
geom_point() +
geom_vline(xintercept=which(dat$pvalue == '.045 - .050'), linetype = "dashed") +
theme_bw() +
theme(axis.text.x = element_text(angle=90),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank()) +
theme(panel.border = element_blank()) +
ggtitle(paste("Insert Plot Title Here")) +
labs(x = "insert x-axis title here", y = "insert y-axis title here") +
theme(plot.title = element_text(lineheight=0.5,family = "TNR")) +
theme(axis.line.x = element_line(color="black"),
axis.line.y = element_line(color="black")) +
scale_y_discrete(breaks=NULL)
myPlot
The above dataset and R script produce the following plot:
Note that I do not have enough "points" to embed an image so a link to the image has been created by Stack Overflow
An inspection of the image reveals that the left panel border (or the vertical axis) is missing. I want the left panel border to be included in the plot. However, I want to exclude the tick marks on the left panel border (or the vertical axis). Taken together, my desired plot would
include a vertical line for the y-axis,
include a horizontal line for the x-axis,
remove tick marks along the y-axis (vertical axis)
remove the top panel border
remove the right panel border
The above R script takes care of #2-5 in this list. However, I have tried and tried and am unable to figure out how to take care of #1 in this list -- despite including the following in my R script:
theme(axis.line.x = element_line(color="black"),
axis.line.y = element_line(color="black")) +
Can somebody help me to produce the desired image? Very much appreciated :)
The scale_y_discrete(breaks = NULL) breaks the y axis, as it interpret as show nothing.
Removing that line we have the y axis and we can then remove ticks and text:
library(ggplot2)
ggplot(data=dat, aes(x=pvalue, y=count, group=1)) +
geom_line() +
geom_point() +
geom_vline(xintercept=which(dat$pvalue == '.045 - .050'), linetype = "dashed") +
ggtitle(paste("Insert Plot Title Here")) +
labs(x = "insert x-axis title here", y = "insert y-axis title here") +
theme_bw() +
theme(plot.title = element_text(lineheight=0.5,family = "TNR"),
axis.line = element_line(),
axis.ticks.y = element_blank(), ## <- this line
axis.text.y = element_blank(), ## <- and this line
axis.text.x = element_text(angle=90),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
panel.border = element_blank())
I’m working with faceted plots and I’m having an issue trying to move facet labels that have two lines near the plotting area.
Consider the minimal example:
require(ggplot2)
labs <- as_labeller(c(`0` = "LABEL 1",
`1` = "LABEL 2 HAS TWO LINES\nBECAUSE IT'S TOO LONG"))
p <- ggplot(mtcars, aes(disp, drat)) +
geom_point() +
theme_bw() +
geom_hline(yintercept=2, linetype="solid") +
geom_vline(xintercept=50, linetype="solid") +
scale_x_continuous(limits=c(50,500), expand =c(0,0)) +
scale_y_continuous(limits = c(2, 5), expand = c(0,0)) +
theme(panel.border = element_blank(),
strip.background = element_blank(),
strip.text = element_text(size=9),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
facet_wrap(~am, labeller = labs)
p
Now adding vjust=-0.62 to move the facet labels near the plotting area we have the following:
p + theme(strip.text = element_text(size=9, vjust=-0.62))
As you can see only LABEL 1, the single line label, is moved close to the plotting area - and that’s the problem.
I wished that both labels could have moved. Does anyone have any suggestion?
*Observation: I’m working with a considerable amount of faceted plots so making and customizing plots one-by-one doesn’t seem to be a good idea.
Hope this may helpful for you
p + theme(strip.text = element_text(size=9, vjust=1))
I have been trying to shift my legend title across to be centered over the legend contents using the guide function. I've been trying to use the following code:
guides(colour=guide_legend(title.hjust = 20))
I thought of trying to make a reproducable example, but I think the reason it's not working has something to do with the above line not matching the rest of my code specifically. So here is the rest of the code I'm using in my plot:
NH4.cum <- ggplot(data=NH4_by_Date, aes(x=date, y=avg.NH4, group = CO2, colour=CO2)) +
geom_line(aes(linetype=CO2), size=1) + #line options
geom_point(size=3) + #point symbol sizes
#scale_shape_manual(values = c(1, 16)) + #manually choose symbols
theme_bw()+
theme(axis.text.x=element_text(colour="white"), #change x axis labels to white.
axis.title=element_text(size=12),
axis.title.x = element_text(color="white"), #Change x axis label colour to white
panel.border = element_blank(), #remove box boarder
axis.line.x = element_line(color="black", size = 0.5), #add x axis line
axis.line.y = element_line(color="black", size = 0.5), #add y axis line
legend.key = element_blank(), #remove grey box from around legend
legend.position = c(0.9, 0.6))+ #change legend position
geom_vline(xintercept=c(1.4,7.5), linetype="dotted", color="black")+ #put in dotted lines for season boundaries
scale_color_manual(values = c("#FF6600", "green4", "#0099FF"),
name=expression(CO[2]~concentration~(ppm))) + #manually define line colour
scale_linetype_manual(guide="none", values=c("solid", "solid", "solid")) + #manually define line types
scale_shape_manual(values = c(16, 16, 16)) + #manually choose symbols
guides(colour=guide_legend(title.hjust = 20))+
scale_y_continuous(expand = c(0, 0), limits = c(0,2200), breaks=seq(0,2200,200))+ #change x axis to intercept y axis at 0
xlab("Date")+
ylab(expression(Membrane~available~NH[4]^{" +"}~-N~(~mu~g~resin^{-1}~14~day^{-1})))+
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
geom_errorbar(aes(ymin = avg.NH4 - se.NH4, #set y error bars
ymax = avg.NH4 + se.NH4),
width=0.1)
I have tried doing the following instead with no luck:
guides(fill=guide_legend(title.hjust=20)
I have also adjusted the hjust value from values between -2 to 20 just to see if that made a difference but it didn't.
I'll try to attach a picture of the graph so far so you can see what I'm talking about.
I've looked through all the questions I can on stack overflow and to the best of my knowledge this is not a duplicate as it's specific to a coding error of my own somewhere.
Thank-you in advance!!
The obvious approach e.g.
theme(legend.title = element_text(hjust = .5))
didn't work for me. I wonder if it is related to this open issue in ggplot2. In any case, one manual approach would be to remove the legend title, and position a new one manually:
ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(cyl))) +
geom_point() +
stat_smooth(se = FALSE) +
theme_bw() +
theme(legend.position = c(.85, .6),
legend.title = element_blank(),
legend.background = element_rect(fill = alpha("white", 0)),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
annotate("text", x = 5, y = 27, size = 3,
label = "CO[2]~concentration~(ppm)", parse = TRUE)
Output: