Add simple histogram to legend in ggplot2 - r

Given a ggplot plot generated using the following code
size = 10000
d = data.frame(
type = rep(c("A","B","C"), each=size),
val = c(rnorm(size, 0, 1), rnorm(size, 1, 2),rnorm(size, 2, 3))
)
require(ggplot2)
(
ggplot(subset(d, is.element(type, c("A", "C"))), aes(x=val))
+ geom_histogram(aes(y=..density..), bins=100, position="identity", alpha=0.5)
+ geom_line(aes(color=type), stat="density", size=1)
)
Is it possible to add a grey square with a custom label representing the simple histogram to the legend? Can it be done without creating a dummy item?

All you need is to put fill= into aes() for the geom_histogram() line. You don't have a column in your dataset to assign to this, but if you assign fill="string name" in aes(), then ggplot will create a fill legend with that as the label.
Of course, the color will default to the ggplot "red" color, so if you want to go with gray again, you have to set that with scale_fill_manual(), since fill= outside aes() will overwrite anything you put within aes().
ggplot(d, aes(x=val)) +
geom_histogram(aes(y=..density.., fill='histogram'),
bins=100, position="identity", alpha=0.5) +
geom_line(aes(color=type), stat="density", size=1) +
scale_fill_manual(values='gray20')

Related

Color labels appearing as color code in gganimate for ggplot

I'm graphing data with ggplot and animating it using gganimate. I have colors as my labels and when I add a geom_label_repel() part to my graph it adds the labels but displays the colors as the color code. (Example Blue is displayed as #0000FFFF). Here is a snapshot of my animated graph.
My data is just cumulative percentages for m&m's colors in each bag.
Here is what I currently have for my ggplot() and am wondering if I have something wrong or if there is a reason why it's changing the labels from color names to the number codes.
df<- data.frame(x=mm_data$Bag,
y= c(mm_data$totalp_red,mm_data$totalp_blue,
mm_data$totalp_orange,mm_data$totalp_yellow,
mm_data$totalp_brown,mm_data$totalp_green),
group = c(rep("Red", nrow(mm_data)),
rep("Blue", nrow(mm_data)),
rep("Orange", nrow(mm_data)),
rep("Yellow", nrow(mm_data)),
rep("Brown", nrow(mm_data)),
rep("Green", nrow(mm_data))))
group.colors <- c( "blue3","sandybrown","green3","darkorange"
,"red2","yellow")
ggplot(df, aes(x, y, group=group, color=group)) +
geom_line() +
geom_point() +
geom_label_repel(label= df$group,max.overlaps = Inf)+
scale_color_manual(values = group.colors)+
ggtitle("Colors present in my M&M Bag") +
ylab("Distribution percentage") +
xlab("Bags of M&M's")+
transition_reveal(x)```
Don't use df$ in your ggplot verbs when you are referring to the same data;
You need aes(..), even in geom_label_repel.
Try this.
ggplot(df, aes(x, y, group=group, color=group)) +
geom_line() +
geom_point() +
geom_label_repel(aes(label=group),max.overlaps = Inf)+
scale_color_manual(values = group.colors)+
ggtitle("Colors present in my M&M Bag") +
ylab("Distribution percentage") +
xlab("Bags of M&M's")+
transition_reveal(x)
For some reason when the labels are as.character() they will show up like this. All I had to do was save them as as.factor and they appeared as "BLUE", "GREEN", "YELLOW", etc instead of the color code.

Add a legend for multiple geom_segments while maintaining a "solid" linetype in ggplot2

I've created a plot using geom_segment and I'd like to add a legend for the different line colours. The only solution I've found suggests modifying the linetype in aes(), but this only works for one segment - when I add a second label to another geom_segment then the linetype becomes dashed and the legend just changes to the new colour.
Here's the code for the plot:
library(ggplot2)
rib_x <- seq(1,10,0.5)
rib_ymin <- seq(3,12,0.5)
rib_ymax <- c(3.0,4.4,5.55,6.55,7.28,8.1,8.6,9.1,9.52,9.98,10.3,10.62,10.98,11.2,11.4,11.52,11.7,11.8,12)
ggplot(data.frame())+
geom_segment(aes(x=1, xend=10, y=12, yend=3),colour="dark red",size=1.5)+
geom_segment(aes(x=1, y=3,xend=10,yend=12),colour="green",size=1.5)+
stat_smooth(aes(x=rib_x,y=rib_ymax),se=FALSE,colour="dark green",size=1.5)+
xlab("Agroecological zone")+
ylab("Productivity")+
geom_segment(aes(x=0, xend = 0, y=2, yend=12), size=1.5, arrow=arrow(length=unit(0.6,"cm")))+
theme_bw()+
annotate("text", label="Arid", x=2, y=1)+
annotate("text", label="Semi-arid", x=5, y=1)+
annotate("text", label="Humid", x=8, y=1)+
theme(axis.title=element_text(size=14),axis.text=element_blank(),legend.title=element_blank(),
axis.ticks=element_blank(),panel.border=element_blank(),
panel.grid.major = element_blank(),panel.grid.minor = element_blank())
I'd like to add a legend for the three line colours, where I can also specify the text used in the legend.
Many thanks!
Move the colour aesthetics inside aes() and name them with the actual strings you want to use to label each color. Then add scale_colour_manual() at the end to get the specific colors you want. See the example below.
In the "standard" ggplot2 workflow, you would map some categorical column to colour inside aes() (e.g., ggplot(iris, aes(x=Petal.Width, y=Sepal.Width, colour=Species)) + geom_smooth(se=FALSE, method="lm")) and then the geoms (e.g., points, lines, smooths, etc.) would appear in a different color for each unique value of the categorical column that was mapped to colour. Here, we're not using a data frame, so we create "dummy" mappings to the colour aesthetic. Putting them inside aes() causes ggplot to generate the legend.
ggplot() +
geom_segment(aes(x=1, xend=10, y=12, yend=3, colour="name1"), size=1.5) +
geom_segment(aes(x=1, y=3,xend=10,yend=12, colour="name2"), size=1.5) +
stat_smooth(aes(x=rib_x,y=rib_ymax, colour="name3"),se=FALSE,size=1.5) +
labs(x="Agroecological zone", y="Productivity", colour="Type") +
geom_segment(aes(x=0, xend = 0, y=2, yend=12), size=1.5, arrow=arrow(length=unit(0.6,"cm"))) +
annotate("text", label="Arid", x=2, y=1) +
annotate("text", label="Semi-arid", x=5, y=1) +
annotate("text", label="Humid", x=8, y=1) +
theme_void() +
theme(axis.title=element_text(size=14, margin=margin(b=3)),
axis.title.y=element_text(angle=90)) +
scale_color_manual(values=c("name1"="darkred", "name2"="green", "name3"="darkgreen"))

How can I use different color or linetype aesthetics in same plot with ggplot?

I'm creating a plot with ggplot that uses colored points, vertical lines, and horizontal lines to display the data. Ideally, I'd like to use two different color or linetype scales for the geom_vline and geom_hline layers, but ggplot discourages/disallows multiple variables mapped to the same aesthetic.
# Create example data
library(tidyverse)
library(lubridate)
set.seed(1234)
example.df <- data_frame(dt = seq(ymd("2016-01-01"), ymd("2016-12-31"), by="1 day"),
value = rnorm(366),
grp = sample(LETTERS[1:3], 366, replace=TRUE))
date.lines <- data_frame(dt = ymd(c("2016-04-01", "2016-10-31")),
dt.label = c("April Fools'", "Halloween"))
value.lines <- data_frame(value = c(-1, 1),
value.label = c("Threshold 1", "Threshold 2"))
If I set linetype aesthetics for both geom_*lines, they get put in the
linetype legend together, which doesn't necessarily make logical sense
ggplot(example.df, aes(x=dt, y=value, colour=grp)) +
geom_hline(data=value.lines, aes(yintercept=value, linetype=value.label)) +
geom_vline(data=date.lines, aes(xintercept=as.numeric(dt), linetype=dt.label)) +
geom_point(size=1) +
scale_x_date() +
theme_minimal()
Alternatively, I could set one of the lines to use a colour aesthetic,
but then that again puts the legend lines in an illogical legend
grouping
ggplot(example.df, aes(x=dt, y=value, colour=grp)) +
geom_hline(data=value.lines, aes(yintercept=value, colour=value.label)) +
geom_vline(data=date.lines, aes(xintercept=as.numeric(dt), linetype=dt.label)) +
geom_point(size=1) +
scale_x_date() +
theme_minimal()
The only partial solution I've found is to use a fill aesthetic instead
of colour in geom_pointand setting shape=21 to use a fillable shape,
but that forces a black border around the points. I can get rid of the
border by manually setting color="white, but then the white border
covers up points. If I set colour=NA, no points are plotted.
ggplot(example.df, aes(x=dt, y=value, fill=grp)) +
geom_hline(data=value.lines, aes(yintercept=value, colour=value.label)) +
geom_vline(data=date.lines, aes(xintercept=as.numeric(dt), linetype=dt.label)) +
geom_point(shape=21, size=2, colour="white") +
scale_x_date() +
theme_minimal()
This might be a case where ggplot's "you can't have two variables mapped
to the same aesthetic" rule can/should be broken, but I can't figure out clean way around it. Using fill with geom_point shows the most promise, but there's no way to remove the point borders.
Any ideas for plotting two different color or linetype aesthetics here?

ggplot2 legend, geom_abline and stat_gg

I have been trying to plot a Normal Q-Q plot with a red line across, in R with ggplot2. I have been unable to add a legend (with LaTeX math) to explain the red line
Here is the code for the basic figure:
ggplot(stdres_df, aes(sample=stdres)) +
stat_qq(color="black") +
geom_abline(slope = 1,
intercept = 0, color ="red")
Thanks in advance.
To get a legend, you need to map something to a color aesthetic inside a call to aes(). In this case, there's no grouping variable to map to colour, but you can just map colour to the name you want to use for the red line.
The line will be red by default, because ggplot uses hcl(15, 100, 65) (a light red) as the first color in its default color palette. However, you can set the color to whatever you want using scale_colour_manual, as shown in the example below. For example:
set.seed(2)
df <- data.frame(y = rnorm(200))
ggplot(df, aes(sample = y)) +
stat_qq() +
geom_abline(aes(slope=1, intercept=0, colour="Test"), size=1) +
coord_equal(xlim=range(df$y)) +
labs(colour="") +
scale_colour_manual(values="red")
Something like this?
ggplot() +
stat_qq(aes(sample=1:100), distribution = qt,dparams = list(df=5)) +
geom_abline(aes(linetype = "line"), slope = 1, intercept = 0, color ="red") +
geom_text(aes(3, 0, label = "TEXT HERE"))

ggplot: Manually add legends for aesthetics that are not mapped

I want to produce a barplot overlayed with dots where both have separate legends. Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes(). As both are not mapped, no legend is produced.
1) How can I add a legend manually for both fill and size?
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5)
This is what I came up with: I used dummy mappings and modified the legend according to my needs afterwards. But this approach appears clumsy to me.
2) Is there a manual way to say: Add a legend with this title, these shapes, these colors etc.?
d <- data.frame(dummy1="d1",
dummy2="d2",
group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop, fill=dummy1, size=dummy2)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5) +
scale_fill_discrete(name="fill legend", label="fill label") +
scale_size_discrete(name="size legend", label="size label")
Above I mapped fill to dummy1. So I would expect scale_fill_discrete to alter this legend. But it appears to modify the size legend instead.
3) I am not sure what went wrong here. Any ideas?
I'm not sure why you say "Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes()". Is it something you're trying to do or is it something that you have to do given how ggplot works?
If it's the latter, one solution is as under -
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity",aes( fill="label")) +
geom_point(aes(size='labelsize')) +
scale_fill_manual(breaks = 'label', values = 'red')+
scale_size_manual(breaks = 'labelsize', values = 5)

Resources