How to change a density curve without changing the legend in ggplot2? - r

I want to change the color of the density curve but when I change it, the border of the boxes from the legend changes too.
Original plot:
When I change the color of the density curve:
Also, if I add lwd=1.2 from the density curve, the legend changes too.
Does anyone know how to fix it?
(I want to change the line width and the colour of the density curve, but I don't want to change how the legend looks).
This is the code:
val1 <- c(2.1490626,3.7928443,2.2035281,1.5927854,3.1399245,2.3967338,3.7915825,4.6691277,3.0727319,2.9230937,2.6239759,3.7664386,4.0160378,1.2500835,4.7648343,0.0000000,5.6740227,2.7510256,3.0709322,2.7998003,4.0809085,2.5178086,5.9713330,2.7779843,3.6724801,4.2648527,3.6841084,2.5597235,3.8477471,2.6587736,2.2742209,4.5862788,6.1989269,4.1167091,3.1769325,4.2404515,5.3627032,4.1576810,4.3387921,1.4024381,0.0000000,4.3999099,3.4381837,4.8269218,2.6308474,5.3481382,4.9549753,4.5389650,1.3002293,2.8648220,2.4015338,2.0962332,2.6774765,3.0581759,2.5786137,5.0539080,3.8545796,4.3429043,4.2233248,2.0434363,4.5980727)
val2 <- c(3.7691229,3.6478055,0.5435826,1.9665861,3.0802654,1.2248374,1.7311236,2.2492826,2.2365337,1.5726119,2.0147144,2.3550348,1.9527204,3.3689502,1.7847986,3.5901329,1.6833872,3.4240479,1.8372175,0.0000000,2.5701453,3.6551315,4.0327091,3.8781182)
df1 <- data.frame(value = val1)
df2 <- data.frame(value = val2)
data <- bind_rows(lst(df1, df2), .id = 'id')
data %>%
ggplot(aes(value)) +
geom_histogram(aes(y=..density.., fill = id), bins=10, col="black", alpha=0.4) +
geom_density(lwd = 1.2,
colour = "red") +
facet_grid(id ~ .) +
scale_x_continuous(breaks=pretty(data$value, n=10)) +
ggtitle("My histogram....") +
guides(fill=guide_legend(title="My legend...")) +
theme(strip.text.x = element_blank(),strip.text.y = element_blank())
Thanks very much in advance!
Regards

Add show.legend = FALSE to geom_density()
library(ggplot2)
library(dplyr)
data %>%
ggplot(aes(value)) +
geom_histogram(aes(y=..density.., fill = id), bins=10, col="black", alpha=0.4) +
geom_density(lwd = 1.2, colour = "red", show.legend = FALSE) +
facet_grid(id ~ .) +
scale_x_continuous(breaks=pretty(data$value, n=10)) +
ggtitle("My histogram....") +
guides(fill = guide_legend(title="My legend...")) +
theme(strip.text.x = element_blank(),strip.text.y = element_blank())
Created on 2021-12-17 by the reprex package (v2.0.1)

Related

how to add text for the dots in ggplot graph R

I'm trying to add the numbers for the dots in my graph. thanks for the help!
percentage.no.work <- cleanData %>% group_by(AREA) %>%
summarise(percentage = mean(ESTIMATED.CITY.UNEMPLOYMENT))
ggplot() +
geom_point(data=percentage.no.work, aes(x=AREA, y=percentage), alpha=0.6, color="purple", size=2) +
geom_smooth(method = "lm") +
theme_minimal() + ggtitle("Percentage Estimated City Unemployment") +
ylab("Percentage")
Using a little made-up data, you can add text labels like this. Note, you also need the aes() in ggplot rather than geom_point and a group = 1 so that you get the geom_smooth rendered.
library(tidyverse)
tribble(
~AREA, ~percentage,
"a", 0.2,
"b", 0.4
) |>
ggplot(aes(AREA, percentage, group = 1), alpha = 0.6, color = "purple", size = 2) +
geom_point() +
geom_text(aes(label = percentage), nudge_x = 0.1) +
geom_smooth(method = "lm") +
theme_minimal() +
ggtitle("Percentage Estimated City Unemployment") +
ylab("Percentage")
Created on 2022-06-04 by the reprex package (v2.0.1)

Underline effect for graph and text using ggplot2

Do you know how to add the yellow highlight effect of this 538 graph for both text and graphs using ggplot2?
Thanks in advance!
Update after clarification
It really depends on the structure of the data and what you are using to plot. However, if you wanted to add large highlights to particular plots, then you could plot the same geom_line but change the aesthetics of it (though the highlight will not connect to adjacent plots).
library(ggplot2)
hlines <- mtcars %>%
group_by(cyl) %>%
summarise(MN = min(wt))
ggplot(mtcars) +
geom_line(aes(mpg, wt), colour = "lightyellow", size = 80) +
geom_line(aes(mpg, wt)) +
geom_hline(
data = hlines,
aes(yintercept = MN),
linetype = "dotted",
color = "grey",
size = 1.5
) +
facet_wrap( ~ cyl) +
theme_bw()
Output
For text, in ggplot2, you can add fill to the background of annotations. But it again really depends on the structure and how you are plotting the text. You could split up the annotations, so that you could fill one and not the other part of the text.
ggplot(mtcars) +
geom_line(aes(mpg, wt), colour = "lightyellow", size = 80) +
geom_line(aes(mpg, wt)) +
annotate(
geom = "text",
x = 30,
y = 5,
label = "It hasn't really dropped off"
) +
annotate(
geom = "label",
x = 30,
y = 4.75,
label = "since he first won office in 2016",
fill = "lightyellow",
label.size = NA
)
Output
First Answer
It depends on what exactly you are looking for/what your data looks like. But if you are wanting to place a line at the minimum under a line graph in a faceted plot, then you could do something like this:
library(ggplot2)
hlines <- mtcars %>%
group_by(cyl) %>%
summarise(MN = min(wt))
ggplot(mtcars) +
geom_line(aes(mpg, wt)) +
geom_hline(
data = hlines,
aes(yintercept = MN),
linetype = "dotted",
color = "grey",
size = 1.5
) +
facet_wrap( ~ cyl) +
theme_bw()
Output
If you just have a single plot, then you can use geom_hline and just provide the y intercept.
ggplot(mtcars) +
geom_line(aes(mpg, wt)) +
geom_hline(yintercept = 3.5,
linetype = "dotted",
color = "grey",
size = 1.5
) +
theme_bw()

Add in legend to ggplot

I know this question is similar to ones that has been asked before but the suggested solutions don't seem to apply.
I set up the problem as follows
mat1 <- NULL
mat2 <- NULL
mat1 <- data.frame(matrix(nrow =16, ncol =2, data = rnorm(32, 0, 1)))
mat2 <- data.frame(matrix(nrow =16, ncol =2, data = rnorm(32, 0, 1)))
mat1[,1] = mat2[,1] = 1:16
colnames(mat1) = c("Window", "CM")
colnames(mat2) = c("Window", "FM")
ggplot() +
geom_line(data = mat1, aes(x = mat1$Window, y= mat1$CM), linetype ="twodash", color ="steelblue") +
geom_line(data = mat2, aes(x = mat2$Window, y= mat2$FM), color = "black") +
theme_classic() + xlab("Quater after alpha assessment") + ylab("Estimated Coefficient") + labs(fill = "cohort model")
I want to add in a legend. Specifically i want the blue line to be labelled as CM and the black line to be labelled as FM
In these kind of scenarios I think it is often the easiest to bring your data into the appropriate format for ggplot. Then you can properly use all of the ggplot toolset.
library(tidyverse)
mat3 = bind_cols(mat1, mat2) %>%
select(-Window1) %>%
gather(type, value, -Window)
mat3 %>%
ggplot(aes(x = Window, y = value, group = type, color = type, linetype = type)) +
geom_line() +
scale_color_manual("cohort model",
values = c("CM" = "steelblue","FM" = "black"),
breaks = c("CM", "FM")) +
scale_linetype_manual("cohort model",
values = c("twodash", "solid"),
breaks = c("CM", "FM")) +
labs(x = "Quater after alpha assessment", y = "Estimated Coefficient") +
theme_classic()
I assume the simplest way to do this would be to use annote():
ggplot() +
geom_line(data = mat1, aes(x = mat1$Window, y= mat1$CM), linetype ="twodash", color ="steelblue") +
geom_line(data = mat2, aes(x = mat2$Window, y= mat2$FM), color = "black") +
theme_classic() + xlab("Quater after alpha assessment") + ylab("Estimated Coefficient") + labs(fill = "cohort model") +
xlim(NA,18) +
annotate(geom="text", x=16.5, y=1.51232841, label="CM", color="blue", size=3) +
annotate(geom="text", x=16.5, y=-0.487350382, label="FM", color="black", size=3)
You can easily change and adjust the position with x= and y=. I also slightly extended the upper limit of x-scale so that the text fits in.
Of course, I don't know if that's enough for you. Otherwise, you could also add a text field as legend. But this would be the easiest and fastest way.

ggplot2: doughnuts, how to conditional color fill with if_else

Following guides like ggplot Donut chart I am trying to draw small gauges, doughnuts with a label in the middle, with the intention to put them later on on a map.
If the value reaches a certain threshold I would like the fill of the doughnut to change to red. Is it possible to achieve with if_else (it would be most natural but it does not work).
library(tidyverse)
df <- tibble(ID=c("A","B"),value=c(0.7,0.5)) %>% gather(key = cat,value = val,-ID)
ggplot(df, aes(x = val, fill = cat)) + scale_fill_manual(aes,values = c("red", "yellow"))+
geom_bar(position="fill") + coord_polar(start = 0, theta="y")
ymax <- max(df$val)
ymin <- min(df$val)
p2 = ggplot(df, aes(fill=cat, y=0, ymax=1, ymin=val, xmax=4, xmin=3)) +
geom_rect(colour="black",stat = "identity") +
scale_fill_manual(values = if_else (val > 0.5, "red", "black")) +
geom_text( aes(x=0, y=0, label= scales::percent (1-val)), position = position_dodge(0.9))+
coord_polar(theta="y") +
xlim(c(0, 4)) +
theme_void() +
theme(legend.position="none") +
scale_y_reverse() + facet_wrap(facets = "ID")
Scale fill manual values= if else.... this part does not work, the error says: Error in if_else(val > 0.5, "red", "black") : object 'val' not found. Is it my error, or some other solution exists?
I also realize my code is not optimal, initially gather waited for more variables to be included in the plot, but I failed to stack one variable on top of the other. Now one variable should be enough to indicate the percentage of completion. I realise my code is redundant for the purpose. Can you help me out?
A solution for the color problem is to first create a variable in the data and then use that to map the color in the plot:
df <- tibble(ID=c("A","B"),value=c(0.7,0.5)) %>% gather(key = cat,value = val,-ID) %>%
mutate(color = if_else(val > 0.5, "red", "black"))
p2 = ggplot(df, aes(fill=color, y=0, ymax=1, ymin=val, xmax=4, xmin=3)) +
geom_rect(colour="black",stat = "identity") +
scale_fill_manual(values = c(`red` = "red", `black` = "black")) +
geom_text( aes(x=0, y=0, label= scales::percent (1-val)), position = position_dodge(0.9))+
coord_polar(theta="y") +
xlim(c(0, 4)) +
theme_void() +
theme(legend.position="none") +
scale_y_reverse() + facet_wrap(facets = "ID")
The result would be:

Coloring the vertical lines by Class in ggplot

I want to plot the distribution of a variable by Class and add vertical lines denoting the means of the subsets defined by each Class and having them colored by Class. While I succeed to color the distributions by Class, the vertical lines appear gray. For a reproducible example see below:
library(data.table)
library(ggplot2)
library(ggthemes)
data(mtcars)
setDT(mtcars)
mtcars[, am := factor(am, levels = c(1, 0))]
mean_data <- mtcars[, .(mu = mean(hp)), by = am]
ggplot(mtcars, aes(x = hp, fill = am , color = am)) +
geom_histogram(aes(y=..density..), position="identity",alpha = 0.4) + guides(color = FALSE) +
geom_density (alpha = 0.5)+
geom_vline(data = mean_data, xintercept = mean_data$mu, aes(color = as.factor(mean_data$am)), size = 2, alpha = 0.5) +
ggtitle("Hp by am") + scale_fill_discrete(labels=c("am" , "no am")) +
labs(fill = "Transmission") + theme_economist()
This code renders the following plot:
Your advice will be appreciated.
You need to include the xintercept mapping in your aes call, so that ggplot properly maps all the aesthetics:
ggplot(mtcars, aes(x = hp, fill = am , color = am)) +
geom_histogram(aes(y=..density..), position="identity",alpha = 0.4) + guides(color = FALSE) +
geom_density (alpha = 0.5)+
geom_vline(data = mean_data, aes(xintercept = mu, color = as.factor(am)), size = 2, alpha = 0.5) +
ggtitle("Hp by am") + scale_fill_discrete(labels=c("am" , "no am")) +
labs(fill = "Transmission") + theme_economist()
Anything you put in a geom call that's not in aes gets treated as a one-off value, and doesn't get all the mapped aesthetics applied to it.

Resources