R语言 ggplot镜像几何图形条自定义颜色

fafcakar  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(125)

我在镜像条形图中绘制了最高温度(平均tmax)与降雨量(平均降雨量)的关系:max temp向上显示,rain值向下显示在负刻度上。这两个值存储在“name”变量中。为了突出显示所绘制的32年中的最高值,我创建了两个向量colVecTmax和colVecRain。它们分别返回一个长度为32的颜色向量,最大值的索引标记不同。
但是当添加这两个向量以填充geom_bar时(),结果是ggplot在16个柱之后停止计数顶部,并向下移动到负刻度继续计数。因此,它不按名称计数(mean_tmax,或mean_rain)变量。这会把图弄乱,我不确定如何首先在max_temperature的顶部条上通过ggplot计数,由colVecTmax着色,然后向下移动以使用colVecRain

对负刻度上的雨进行相同的操作。
谁能给予个提示如何解决这个问题?

colVecTmax <- rep("orange",32)
colVecTmax[which.max(as.numeric(unlist(df.long[df.long$place=="sheffield" & df.long$name == "mean_tmax",4])))] <- "blue"

colVecRain <- rep("grey",32)
colVecRain[which.max(as.numeric(unlist(df.long[df.long$place=="sheffield" & df.long$name == "mean_rain",4])))] <- "blue"
  
ggplot(df.long[df.long$name %in% c('mean_rain', 'mean_tmax'), ] %>% filter(place== "sheffield")%>%
         group_by(name) %>% mutate(value = case_when(
           name == 'mean_rain' ~ value/10 * -1,
           TRUE ~ value)) %>% mutate(place==str_to_sentence(placenames)) %>%
         mutate(name = recode(name,'mean_rain' = "rainfall" ,  "mean_tmax" =  "max temp"))
         , aes(x = yyyy, y = value, fill=name))+
  geom_bar(stat="identity", position="identity", fill=c(colVecTmax,colVecRain))+
  labs(x="Year", y=expression("Rain in cm, temperature in ("*~degree *C*")"))+
  geom_smooth(colour="black", lwd=0.5,se=F)+
  scale_y_continuous(breaks = seq(-30, 30 , 5))+
  scale_x_continuous(breaks = seq(1990, 2025, 5))+
  guides(fill= guide_legend(title=NULL))+
  scale_fill_discrete(labels=c("Max temperature", "Rainfall"))+
  guides(fill=guide_legend(reverse=T), res=96)

3qpi33ja

3qpi33ja1#

使用ggplot2有更容易和更少错误的方法来分配颜色。(您基本上已经完成了此操作)并使用手动比例分配所需的颜色,例如scale_fill_manual。当你想突出显示一些值时,同样的方法也能很好地工作。为此,你可以创建额外的类别,例如,在下面的代码中,我将"_max"添加到name中,以获得具有最高温度或降雨量的观测值,并为这些类别分配所需的"blue"颜色。因为这样做会添加额外的类别,所以我使用scale_fill_manualbreaks参数,这样这些最大类别就不会出现在图例中。
使用一些伪造的随机示例数据:

# Create example data
set.seed(123)
df.long <- data.frame(
  name = rep(c("mean_rain", "mean_tmax"), each = 30),
  place = "sheffield",
  yyyy = rep(1991:2020, 2),
  value = c(runif(30, 40, 100), runif(30, 12, 16))
)

library(ggplot2)
library(dplyr)

df_plot <- df.long %>%
  filter(name %in% c("mean_rain", "mean_tmax")) |>
  filter(place == "sheffield") %>%
  mutate(value = case_when(
    name == "mean_rain" ~ -value / 10,
    TRUE ~ value
  )) |>
  # Maximum values
  group_by(name) |>
  mutate(name = ifelse(abs(value) >= max(abs(value)), paste(name, "max", sep = "_"), name))

ggplot(df_plot, aes(x = yyyy, y = value, fill = name)) +
  geom_col(position = "identity") +
  geom_smooth(colour = "black", lwd = 0.5, se = F) +
  scale_y_continuous(breaks = seq(-30, 30, 5), labels = abs) +
  scale_x_continuous(breaks = seq(1990, 2025, 5)) +
  scale_fill_manual(
    values = c(
      mean_rain = "orange", mean_tmax = "grey",
      mean_rain_max = "blue", mean_tmax_max = "blue"
    ),
    labels = c(mean_tmax = "Max temperature", mean_rain = "Rainfall"),
    breaks = c("mean_rain", "mean_tmax")
  ) +
  labs(x = "Year", y = expression("Rain in cm, temperature in (" * ~ degree * C * ")"), fill = NULL) +
  guides(fill = guide_legend(reverse = TRUE))

相关问题