求助:ggplot绘制两条线间红蓝异常区域仅显示蓝色问题
问题分析
你现在的代码只处理了uv1920 <= uv01_19时的蓝色填充区域,完全没覆盖uv1920 > uv01_19的红色区域;另外scale_fill_manual没生效,是因为你没有把fill作为美学映射(aes)的一部分,而是直接在geom_ribbon里固定了颜色,和手动颜色设置没有关联。
解决方法
方法1:新增geom_ribbon处理反向情况
直接针对两种条件分别绘制对应区域,给每个区域指定不同填充色:
library(RCurl) library(ggplot2) t <- getURL("https://raw.githubusercontent.com/vladamihaesei/weather_covid/master/Tab/UVanomaly.csv") t <- read.csv(text = t) # 把字符型的data列转成日期格式,否则scale_x_date会失效 t$data <- as.Date(t$data) ggplot(t, aes(x = data)) + # 简化线条的aes写法,避免重复指定x geom_line(aes(y = uv1920), color = "black") + geom_line(aes(y = uv01_19), color = "gray") + # 绘制uv1920低于uv01_19的蓝色区域 geom_ribbon(data = subset(t, uv1920 <= uv01_19), aes(ymin = uv1920, ymax = uv01_19), fill = "blue", alpha = 0.3) + # 绘制uv1920高于uv01_19的红色区域 geom_ribbon(data = subset(t, uv1920 > uv01_19), aes(ymin = uv01_19, ymax = uv1920), fill = "red", alpha = 0.3) + scale_x_date(date_breaks = "2 weeks", date_labels = "%d%b")
方法2:重构数据,用美学映射统一控制颜色(更符合ggplot语法)
先创建变量区分异常类型,通过fill映射统一设置颜色,逻辑更清晰:
library(RCurl) library(ggplot2) library(dplyr) t <- getURL("https://raw.githubusercontent.com/vladamihaesei/weather_covid/master/Tab/UVanomaly.csv") t <- read.csv(text = t) %>% mutate( data = as.Date(data), # 标记异常类型 anomaly_type = case_when( uv1920 <= uv01_19 ~ "低于均值", uv1920 > uv01_19 ~ "高于均值" ), # 统一计算上下边界,避免重复写条件 ymin = pmin(uv1920, uv01_19), ymax = pmax(uv1920, uv01_19) ) ggplot(t, aes(x = data)) + geom_line(aes(y = uv1920), color = "black") + geom_line(aes(y = uv01_19), color = "gray") + # 将fill映射到异常类型变量 geom_ribbon(aes(ymin = ymin, ymax = ymax, fill = anomaly_type), alpha = 0.3) + scale_x_date(date_breaks = "2 weeks", date_labels = "%d%b") + # 手动设置对应颜色 scale_fill_manual(values = c("高于均值" = "red", "低于均值" = "blue")) + # 可选:修改图例标题 labs(fill = "UV异常类型")
额外提示
- 必须把
data列转换成日期格式,原数据里它是字符型,不转换的话scale_x_date会报错; - 添加
alpha参数让填充区域更透明,能避免遮挡下方的线条,视觉效果更好。
内容的提问来源于stack exchange,提问作者Alex.V
相关产品推荐
相关产品推荐

