Reputation: 5059
I need to generate a plot with bar graph for two variables and a line with the third variable.
I can create a column graph for one variable like below
df <- head(mtcars)
df$car <- row.names(df)
ggplot(df) + geom_col(aes(x=car, y=disp))
Ref this answer - I can plot two variables - disp
and hp
as below
library(tidyr)
df$car = row.names(df)
df_long = gather(df, key = var, value = value, disp, hp)
ggplot(df_long, aes(x = car, y = value, fill = var)) +
geom_bar(stat = 'identity', position = 'dodge')
I need to have a third variable qsec
plotted as a line like as in the below chart - how to go about this ?
Upvotes: 0
Views: 2736
Reputation: 17648
You can try:
library(tidyverse)
# some data
data <- mtcars %>%
mutate(car = rownames(mtcars)) %>%
slice(1:6) %>%
select(car, disp, hp)
data %>%
gather(key, value, -car) %>%
group_by(car) %>%
mutate(qsec_value = median(value)) %>%
mutate(qsec = factor("qsec")) %>%
ggplot() +
geom_col(aes(x=car, y=value, fill = key), position = "dodge") +
geom_point(aes(x=car, y=qsec_value,color = qsec)) +
geom_line(aes(x=car, y=qsec_value, color = qsec, group =1)) +
scale_colour_manual(name= "", values = 1) +
theme(legend.position = "top",
legend.title = element_blank())
Less code, same result:
data %>%
pivot_longer(-1) %>%
ggplot(aes(x = car)) +
geom_col(aes(y=value, fill = name), position = "dodge") +
stat_summary(aes(y=value, group=1, color="qseq"), fun = "median", geom = "point")+
stat_summary(aes(y=value, group=1, color="qseq"), fun = "median", geom = "line")+
scale_colour_manual(name= "", values = 1)
Upvotes: 2
Reputation: 2101
You need another layer and because geom_line
is for continuous data, you need to do as if your x-values are for the line-layer. By doing so, order of data becomes crucial, hence you have also to sort it:
gather(df, key = var, value = value, disp, hp, qsec) %>%
arrange(car) %>%
{
print(
ggplot() +
geom_bar(stat = 'identity', position = 'dodge', data = filter(., var != "qsec"), mapping = aes(x = car, y = value, fill = var)) +
geom_line(mapping = aes(x = 1:length(car), y = value), data = filter(., var == "qsec"))
)
}
Edit:
btw, you can check the correct order of qsec
to the respective x-value by calling plotly::ggplotly()
, then you can read the values better and compare them to the df
, because they will show up if you point on the element...
Upvotes: 0