You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R coefplot::multiplot如何分别生成形状与颜色独立图例

错误原因

  1. 直接将外部定义的Time_span、Model因子传入multiplot的color、shape参数无效,multiplot默认会把输入的24个模型识别为24个独立分组,因此你指定的8个颜色、3个形状无法匹配24个分组,才会抛出「需要24个值但仅提供8个」的报错。
  2. multiplot内部已经自动生成了color和shape的默认标度,后续叠加的手动标度会触发替换提示,又因为分组数量不匹配最终运行失败。

解决方案

推荐两种可行的调整方式:

方案1:修改multiplot返回的ggplot对象

先给模型指定组合名称,再修改底层数据拆分出分组字段,重新映射美学:

# 构造按顺序对应的模型名称
model_names <- paste(Time_span, Model, sep = "_")

# 生成基础multiplot对象
p <- coefplot::multiplot(string0,string01,string02,
                          string1,string11,string12,
                          string2,string21,string22,
                          string3,string31,string32,
                          string4,string41,string42,
                          string5,string51,string52,
                          string6,string61,string62,
                          string7,string71,string72,
                  intercept = FALSE, 
                  numberAngle=0, 
                  coefficients = "wvs_risk", 
                  title= NULL,
                  ylab = NULL,
                  xlab = "Stringency",
                  zeroColor = "black", 
                  zeroLWD = 1, 
                  zeroType = 1,
                  names = model_names) # 传入自定义模型名

# 拆分底层数据的分组字段
library(tidyr)
library(dplyr)
p$data <- p$data %>%
  separate(Model, into = c("Time_span", "Model"), sep = "_", remove = FALSE) %>%
  mutate(Time_span = factor(Time_span, levels = c("Day+0","Day+3","Day+7","Day+14","Day+21","Day+30","Day+60","Day+90")),
         Model = factor(Model, levels = c("Without controls","With controls 1","With controls 2")))

# 重新映射美学并调整样式
p <- p +
  aes(color = Time_span, shape = Model) +
  coord_flip()+
  theme_light() +
  theme(legend.position = "left") +
  scale_colour_manual(values = c("#e49205","#a15439","#e11e47","#e72eb6","#2b63e1",
                                 "#32cdaf","#74bb81","#93e424"),
                      name = "Time span") +
  scale_shape_manual(values = c(0,16,25),
                     name = "Model") +
  guides(colour = guide_legend(order = 2), shape = guide_legend(order = 1)) + 
  scale_y_discrete(labels=c("Risk taking"))

# 输出图表
p

方案2:手动提取系数用原生ggplot绘制(灵活度更高,不易踩包的内置规则坑)

用broom包提取所有模型的系数后直接绘图,完全自定义映射规则:

library(broom)
library(purrr)
library(ggplot2)

# 把所有模型按输入顺序存入列表
model_list <- list(string0,string01,string02,
                   string1,string11,string12,
                   string2,string21,string22,
                   string3,string31,string32,
                   string4,string41,string42,
                   string5,string51,string52,
                   string6,string61,string62,
                   string7,string71,string72)

# 批量提取目标系数,绑定分组标签
coef_df <- map2_dfr(model_list, 1:length(model_list), function(mod, idx){
  tidy(mod, conf.int = TRUE) %>%
    filter(term == "wvs_risk") %>%
    mutate(Time_span = Time_span[idx],
           Model = Model[idx])
})

# 直接绘制系数图
ggplot(coef_df, aes(y = term, x = estimate, xmin = conf.low, xmax = conf.high)) +
  geom_vline(xintercept = 0, color = "black", linewidth = 1, linetype = 1) +
  geom_point(aes(color = Time_span, shape = Model), size = 3, position = position_dodge(width = 0.5)) +
  geom_errorbar(aes(color = Time_span), width = 0.2, position = position_dodge(width = 0.5)) +
  theme_light() +
  labs(y = "Risk taking", x = "Stringency") +
  theme(legend.position = "left") +
  scale_colour_manual(values = c("#e49205","#a15439","#e11e47","#e72eb6","#2b63e1",
                                 "#32cdaf","#74bb81","#93e424"),
                      name = "Time span") +
  scale_shape_manual(values = c(0,16,25),
                     name = "Model") +
  guides(colour = guide_legend(order = 2), shape = guide_legend(order = 1))

内容的提问来源于stack exchange,提问作者Martina Dattilo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 00:54:03