如何仅用ggplot实现预测模型与观测值的分离图例?
纯ggplot实现双变量分离图例方案
要实现你想要的分离图例可视化,无需借助其他绘图工具,以下两种纯ggplot方案可以达成目标:
方案一:整合数据格式生成分离图例
先把观测值和预测模型数据统一整理成长格式,通过区分color(映射预测模型)和shape/linetype(映射观测值)的美学映射,让ggplot自动生成两个独立图例:
library(dplyr) library(tidyr) library(ggplot2) n = 5 df = data.frame( time = c(1 : n), prediction_model1 = rnorm(n) %>% sort, prediction_model2 = rnorm(n) %>% sort, observed_values = rnorm(n) %>% sort ) # 将所有序列转成长格式,新增字段区分预测模型和观测值 df_plot = df %>% pivot_longer(cols = everything(), names_to = "series", values_to = "happyness") %>% mutate( group_type = case_when( grepl("prediction", series) ~ "预测模型", series == "observed_values" ~ "观测值" ), model_name = ifelse(group_type == "预测模型", sub("prediction_", "", series), NA) ) ggplot(df_plot) + # 绘制预测模型的点和线,用颜色区分模型 geom_point(aes(x = time, y = happyness, color = model_name), size = 2, data = . %>% filter(group_type == "预测模型")) + geom_line(aes(x = time, y = happyness, color = model_name), data = . %>% filter(group_type == "预测模型")) + # 绘制观测值的点和线,用形状和线型区分 geom_point(aes(x = time, y = happyness, shape = group_type), size = 4, data = . %>% filter(group_type == "观测值")) + geom_line(aes(x = time, y = happyness, linetype = group_type), data = . %>% filter(group_type == "观测值")) + # 配置图例标签与样式 labs(color = "预测模型", shape = "", linetype = "") + scale_shape_manual(values = c(5)) + scale_linetype_manual(values = c("solid")) + theme( legend.position = "bottom", legend.box = "vertical", legend.spacing.y = unit(0.2, "cm") )
方案二:用ggnewscale添加独立图例
如果不想调整原始数据结构,使用ggnewscale包可以为观测值单独创建一个图例,和预测模型的图例分开:
library(dplyr) library(tidyr) library(ggplot2) library(ggnewscale) n = 5 df = data.frame( time = c(1 : n), prediction_model1 = rnorm(n) %>% sort, prediction_model2 = rnorm(n) %>% sort, observed_values = rnorm(n) %>% sort ) df_plot = df %>% pivot_longer(cols = c(prediction_model1, prediction_model2), names_prefix = "prediction_", values_to = "happyness") ggplot(df_plot) + # 绘制预测模型的点和线,生成第一个颜色图例 geom_point(aes(x = time, y = happyness, color = name), size = 2) + geom_line(aes(x = time, y = happyness, color = name)) + labs(color = "预测模型") + # 启动新的图例上下文,用于观测值 new_scale("color") + new_scale("shape") + # 绘制观测值的点和线,生成第二个独立图例 geom_point(aes(x = time, y = observed_values, color = "观测值", shape = "观测值"), size = 4) + geom_line(aes(x = time, y = observed_values, color = "观测值")) + # 设置观测值的图例样式 scale_color_manual(name = "", values = c("观测值" = "black")) + scale_shape_manual(name = "", values = c("观测值" = 5)) + theme( legend.position = "bottom", legend.box = "vertical", legend.spacing.y = unit(0.2, "cm") )
两种方案都能实现目标图表的分离图例效果,可根据需求选择。
内容的提问来源于stack exchange,提问作者armandfavrot
相关产品推荐
相关产品推荐

