In this plot
library(ggplot2)
df <- data.frame(year = c(2011,2012,2013,2014,2015,2016,2017,2018),
value = c(337,423,551,661,846,1387,2222,3580))
ggplot(df, aes(year, value)) +
geom_point() +
geom_line() +
geom_text(aes(label = value, y = (value - 50)*0.9))
How is it possible to make the color of numbers of value red?
Like this?
library(ggplot2)
df <- data.frame(year = c(2011,2012,2013,2014,2015,2016,2017,2018),
value = c(337,423,551,661,846,1387,2222,3580))
ggplot(df, aes(year, value)) +
geom_point() +
geom_line() +
geom_text(aes(label = value, y = (value - 50)*0.9), color = "red")
Or like this?
library(ggplot2)
df <- data.frame(year = c(2011,2012,2013,2014,2015,2016,2017,2018),
value = c(337,423,551,661,846,1387,2222,3580))
ggplot(df, aes(year, value)) +
geom_point() +
geom_line() +
geom_text(aes(label = value, y = (value - 50)*0.9), color = "red") +
theme(axis.text.y = element_text(colour = "red"))
Related
using the data set airquality I have written the following code:
library("tidyverse")
data(airquality)
airquality <- na.omit(airquality)
airquality$date <- as.Date(paste("1973", airquality$Month, airquality$Day,
sep="-"))
p1 <- ggplot(airquality, aes(x= date, y = Ozone, col=factor(Month))) +
geom_point() +
geom_line()
p1
Now I would like to plot in the same graph the mean of ozone for each months. How can I do this?
You could add the mean as a dashed line. The easiest way to do this might be to simply pass the data you want to a geom_line layer:
ggplot(airquality, aes(x = date, y = Ozone, col = factor(Month))) +
geom_point() +
geom_line(alpha = 0.5) +
geom_line(data = airquality %>%
group_by(Month) %>%
summarise(Ozone = mean(Ozone),
date = c(first(date), last(date)),
Month = mean(Month)),
linetype = 2, size = 1) +
scale_color_brewer(palette = "Set1") +
theme_minimal(base_size = 16)
If you just want points showing the mean, you could simplify things with stat_mean from ggpubr
ggplot(airquality, aes(x = date, y = Ozone, col = factor(Month))) +
geom_point() +
geom_line(alpha = 0.5) +
ggpubr::stat_mean(size = 5, shape = 21,
aes(fill = factor(Month)), color = "black") +
scale_color_brewer(palette = "Set1") +
scale_fill_brewer(palette = "Set1") +
theme_minimal(base_size = 16)
To join these dots up, you could do:
ggplot(airquality, aes(x = date, y = Ozone, col = factor(Month))) +
geom_point() +
geom_line(alpha = 0.5) +
geom_line(data = airquality %>%
group_by(Month) %>%
summarise(Ozone = mean(Ozone), date = mean(date)),
color = "black", linetype = 2) +
ggpubr::stat_mean(size = 5, shape = 21,
aes(fill = factor(Month)), color = "black") +
scale_color_brewer(palette = "Set1") +
scale_fill_brewer(palette = "Set1") +
theme_minimal(base_size = 16)
I am trying to draw a density curve over histogram using ggplot but to no avail. dlist is a vector with numeric values.
Here is my code:
ggplot() +
geom_histogram(aes(x=dlist), bins = 30, fill = "#B3E4F7") +
geom_density() +
geom_vline(aes(xintercept = mean(dlist)),
color="#D2091F", linetype="dashed",size=1)
You need to set y to ..density... For example:
ggplot(data.frame(dlist), aes(x=dlist, y = ..density..)) +
geom_histogram(bins = 30, fill = "#B3E4F7") +
geom_density() +
geom_vline(aes(xintercept = mean(dlist)),
color="#D2091F", linetype="dashed",size=1)
A reproducible example:
library(ggplot2)
ggplot(mtcars, aes(x = mpg, y = ..density..)) +
geom_histogram(bins = 30, fill = "#B3E4F7") +
geom_density()
The geom_desntity has no data. Put the data in the ggplot() or in all functions.
ggplot(aes(x=dlist)) +
geom_histogram(bins = 30, fill = "#B3E4F7") +
geom_density() +
geom_vline(aes(xintercept = mean(dlist)),color="#D2091F", linetype="dashed",size=1)
However, if you want to compare both, you may want to plot the histogram with a density stat:
ggplot(aes(x=dlist)) +
geom_histogram(aes(y = ..density..),bins = 30, fill = "#B3E4F7") +
geom_density() +
geom_vline(aes(xintercept = mean(dlist)),color="#D2091F", linetype="dashed",size=1)
If you have a numeric vector dlist, you can create a data.frame before ggplot as follows:
dlist <- rnorm(1000)
tibble(dlist = dlist) %>%
ggplot(aes(x=dlist)) +
geom_histogram(aes(y = ..density..),bins = 30, fill = "#B3E4F7") +
geom_density() +
geom_vline(aes(xintercept = mean(dlist)),
color="#D2091F", linetype="dashed",size=1)
I try to set alpha parameter 0.1 for background in my animation:
library(tidyverse)
library(gganimate)
mtcars_ <- rename(mtcars, mpg_ = mpg, disp_ = disp)
mtcars_$mpg = min(mtcars$mpg)
gg <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_density_2d_filled(data = mtcars_, aes(x = mpg_, y = disp_), alpha = 0.1) + geom_line() + theme(legend.position = "none")
gg
anim <- gg + transition_reveal(mpg) + shadow_wake(1)
anim
but alpha is 1 in final movie. How to fix it?
I need movie with this image
One way to do this would be to replicate the data you need for each frame. geom_density should see everything in every frame, but geom_line should only "see" the values up to the currently displayed value. We could accomplish that using tidyr::uncount to make copies of our data, and then creating a variable for geom_line that is NA when the value is too high for the current frame.
library(tidyverse)
library(gganimate)
distinct_mpg <- mtcars %>% distinct(mpg) %>% arrange(mpg) %>% pull(mpg)
mtcars_frames <- mtcars %>%
uncount(length(distinct_mpg), .id = "frame") %>%
mutate(mpg_reveal = distinct_mpg[frame],
mpg_shown = if_else(mpg <= mpg_reveal, mpg, NA_real_))
animate(
ggplot(mtcars_frames, aes(y = disp)) +
geom_density_2d_filled(aes(x = mpg), alpha = 0.1) +
geom_line(aes(x = mpg_shown, group = frame)) +
transition_states(frame) +
scale_fill_viridis_d(guide = NULL),
fps = 20
)
You might just want either to remove the shadow_wake() or set its wake_length closer to 0. The visual results will be similar, but the computation time will be higher for the shadow_wake() option.
gg1 <- ggplot(mtcars, aes(x = mpg, y = disp)) +
geom_density_2d_filled(data = mtcars_, aes(x = mpg_, y = disp_), alpha = 0.2) + geom_line() +
theme(legend.position = "none",
panel.background = element_blank())
gg1 + transition_reveal(mpg)
shadow_wake() removed
Or set shadow_wake to a lower setting.
gg2 <-
ggplot(data = mtcars, aes(x = mpg, y = disp)) +
geom_density_2d_filled(data = mtcars_ , aes(x = mpg_, y = disp_), alpha = 0.2) +
geom_line() +
theme(legend.position = "none",
panel.background = element_blank())
gg2 + transition_reveal(mpg) + shadow_wake(wake_length = 0.05)
shadow_wake() lowered
I have the following dataframe:
df <- tribble(
~group, ~value, ~ci_low, ~ci_upper,
"group1", 0.0577434, 0.0567665, 0.0587203,
"group2", 0.0941233, 0.0801769, 0.1080698)
I want to plot the column "value" as a point and then a dashed line that goes "under" which minimum point is ci_low and high point is ci_upper.
So far I have this:
ggplot(df, aes(group, value)) +
geom_point(size = 4)
And I want something like this:
To have control over the line ends, use geom_segment:
ggplot(df, aes(group, value)) +
geom_segment(aes(xend = group, y = ci_low, yend = ci_upper), color = "red", size = 2, lineend = "round") +
geom_point(size = 4) +
theme_bw()
If square line ends are OK, use geom_linerange:
ggplot(df, aes(group, value)) +
geom_linerange(aes(ymin = ci_low, ymax = ci_upper), color = "red", size = 2) +
geom_point(size = 4) +
theme_bw()
This should do the trick.
ggplot(df, aes(x=group, y=value)) +
geom_pointrange(aes(ymin=ci_low, ymax=ci_upper))
I am trying to reduce the space between my long axis labels. In base R graphics I would use lheight, but is seems to have no effect in ggplot. Is there a ggplot equivalent?
Toy example to show the problem:
library("tidyverse")
df0 <- mtcars %>%
rownames_to_column("car") %>%
mutate(car = str_wrap(car, width = 10))
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip()
# has no effect
par(lheight = 0.5)
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip()
You may be looking for a combination of options. The closest to lheight is likely setting lineheight in element_text. I also made the font smaller, just to show options.
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip() +
theme(axis.text.y = element_text(lineheight = 0.5,
size = 6))
I had a same problem and I found a solution in reducing my list with: slice(1:40)
library("tidyverse")
df0 <- mtcars %>%
rownames_to_column("car") %>%
mutate(car = str_wrap(car, width = 10)) %>% slice(1:40)
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip()
# has no effect
par(lheight = 0.6)
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip()
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip() +
theme(axis.text.y = element_text(lineheight = 0.6, size = 5))
Another option is using guide_axis with n.dodge in scale_y_discrete to automatically dodge the labels like this:
library("tidyverse")
df0 <- mtcars %>%
rownames_to_column("car") %>%
mutate(car = str_wrap(car, width = 10))
ggplot(data = df0, aes(x = car, y = mpg)) +
geom_bar(stat = "identity") +
coord_flip() +
scale_y_discrete(guide = guide_axis(n.dodge = 2)) +
theme(axis.text.y = element_text(size = 5))
Created on 2022-10-20 with reprex v2.0.2