英文:
R - Change colors of specific bars in a dodged barplot in ggplot2
问题
我想改变分组条形图中特定日期的颜色。
复制现有图表的代码如下:
df <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <- gather(df, event, total, term_rv:zc_rv)
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#ff8080", "#00cccc"))
这应该会生成一个类似于这样的图表:
我想要与Nov-24关联的两个条形图的颜色不同(或具有边框),以便与其他条形图区分开。所以类似于这样的效果:
是否有一种简单的方法可以做到这一点?请随意更改代码。我使用gather
来创建分组图表,但可能有更简单的方法。
英文:
I'd like to change the colour of a specific date in a dodged bar chart.
The code to replicate the existing chart is as follows:
df <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <- gather(df, event, total, term_rv:zc_rv)
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#ff8080", "#00cccc"))
This should produce a chart like this:
I'd like the two bars associated with Nov-24 to be in a different colour (or with borders) to differentiate them with the rest. So something like this:
Is there a simple way to do this? Feel free to change the code in anyway. I used gather
to create the dodged chart but there might be a easier way.
答案1
得分: 2
I typically use the gghighlight package for this type of task, e.g.
library(tidyverse)
library(gghighlight)
df <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <- df %>%
pivot_longer(cols = -mat,
names_to = "event",
values_to = "total")
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#ff8080", "#00cccc")) +
gghighlight(mat == "Nov-24")
If you use the 'darker colours' for all of the bars, then replace the unhighlighted bars with your 'regular colours', you can get your desired outcome:
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#870017", "#3E4EC8")) +
gghighlight(mat == "Nov-24",
unhighlighted_params = list(fill = rep(c("#ff8080", "#00cccc"),
length(unique(df2$mat)))))
Created on 2023-06-29 with reprex v2.0.2
A potential downside to this approach is the legend is lost. One potential workaround for this is to label the bars of interest, e.g.
library(tidyverse)
library(gghighlight)
library(ggrepel)
df <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <- df %>%
pivot_longer(cols = -mat,
names_to = "event",
values_to = "total")
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#ff8080", "#00cccc")) +
gghighlight(mat == "Nov-24") +
geom_text_repel(aes(label = event),
position = position_dodge(width = 0.8),
min.segment.length = 0)
Created on 2023-06-29 with reprex v2.0.2
英文:
I typically use the gghighlight package for this type of task, e.g.
library(tidyverse)
library(gghighlight)
df <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <- df %>%
pivot_longer(cols = -mat,
names_to = "event",
values_to = "total")
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#ff8080", "#00cccc")) +
gghighlight(mat == "Nov-24")
#> label_key: mat
<!-- -->
If you use the 'darker colours' for all of the bars, then replace the unhighlighted bars with your 'regular colours', you can get your desired outcome:
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#870017", "#3E4EC8")) +
gghighlight(mat == "Nov-24",
unhighlighted_params = list(fill = rep(c("#ff8080", "#00cccc"),
length(unique(df2$mat)))))
#> label_key: mat
<!-- -->
<sup>Created on 2023-06-29 with reprex v2.0.2</sup>
A potential downside to this approach is the legend is lost. One potential workaround for this is to label the bars of interest, e.g.
library(tidyverse)
library(gghighlight)
library(ggrepel)
df <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <- df %>%
pivot_longer(cols = -mat,
names_to = "event",
values_to = "total")
ggplot(df2, aes(x=mat, y=total, fill=event)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
label = c("TF", "ZC"),
values = c("#ff8080", "#00cccc")) +
gghighlight(mat == "Nov-24") +
geom_text_repel(aes(label = event),
position = position_dodge(width = 0.8),
min.segment.length = 0)
#> label_key: mat
<!-- -->
<sup>Created on 2023-06-29 with reprex v2.0.2</sup>
答案2
得分: 1
另一种方法是创建一个新变量,区分感兴趣的元素,并用其自己的填充颜色突出显示。如果需要,突出显示的元素可以包括在图例中。
library(ggplot2)
library(tidyr)
library(dplyr)
df1 <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <-
df1 |>
pivot_longer(cols = -mat,
names_to = "event",
values_to = "total") |>
mutate(event_grp = ifelse(mat == "Nov-24", paste0(event, 1), event))
ggplot(df2, aes(x=mat, y=total, fill=event_grp)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
breaks = c("term_rv", "zc_rv", "term_rv1", "zc_rv1"),
label = c("TF", "ZC", "TF*", "ZC*"),
values = c("#ff8080", "#00cccc", "#870017", "#3E4EC8")) +
theme(legend.position = "bottom")
Created on 2023-06-29 with reprex v2.0.2
英文:
An alternative approach is to create a new variable distinguishing the elements of interest and highlighting them with their own fill colours. The highlighted elements can be included in the legend if required.
library(ggplot2)
library(tidyr)
library(dplyr)
df1 <- data.frame(mat = c("Apr-24", "Nov-24", "Apr-25", "Nov-25", "Apr-26", "Sep-26", "Apr-27"),
term_rv = c(0.14, 0.34, 0.19, 0.22, 0.34, 0.16, 0.27),
zc_rv = c(0.12, 0.31, 0.23, 0.27, 0.36, 0.09, 0.29))
df2 <-
df1 |>
pivot_longer(cols = -mat,
names_to = "event",
values_to = "total") |>
mutate(event_grp = ifelse(mat == "Nov-24", paste0(event, 1), event))
ggplot(df2, aes(x=mat, y=total, fill=event_grp)) +
geom_bar(width = 0.8, stat = "identity", position = 'dodge') +
theme_bw() +
scale_fill_manual(name = c("Method"),
breaks = c("term_rv", "zc_rv", "term_rv1", "zc_rv1"),
label = c("TF", "ZC", "TF*", "ZC*"),
values = c("#ff8080", "#00cccc", "#870017", "#3E4EC8")) +
theme(legend.position = "bottom")
<!-- -->
<sup>Created on 2023-06-29 with reprex v2.0.2</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论