如何调整图例属性以显示 2 个特征?

Posted

技术标签:

【中文标题】如何调整图例属性以显示 2 个特征?【英文标题】:How to adjust legend properties to display 2 characteristics? 【发布时间】:2017-04-25 07:56:30 【问题描述】:

我在同一个图中绘制了两个变量,每个变量都按年份分组。我的图例按年份显示颜色差异,但我不知道如何将线型添加到图例中。理想情况下,图例中有 4 行:粉色=2015,蓝色=2016,虚线=Var1,实线=Var2

这是我的示例 df:

year <- c(2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2015,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016)
month <-c(1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12)
Var1 <- sample(30:60, 24, rep=TRUE)
Var2 <- sample(70:90, 24, rep=TRUE)
df <- data.frame(year,month,Var1, Var2)

还有情节:

plot <- ggplot(df)+
  geom_line(aes(x=as.factor(month), y=Var1, 
            group=as.factor(year), color=as.factor(year)), linetype=2, size=0.9)+
  geom_point(aes(x=as.factor(month), y=Var1, group=as.factor(year)))+
  geom_line(aes(x=as.factor(month), y=Var2, 
            group=as.factor(year), color=as.factor(year)), linetype=1, size=0.9)+
  geom_point(aes(x=as.factor(month), y=Var2, group=as.factor(year)))+
  theme_tufte()+
  theme(legend.title=element_blank())+
  labs(x=NULL,y="",title="Var1 vs. Var2")+
  scale_x_discrete(expand=c(0,0.2),
               labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
plot

我已尝试更改 geom_line 中的 aes,以及添加和配置一些 scale_xxx_yyyy,包括 scale_linetype_manual。到目前为止都没有成功。理想情况下,我不必单独绘制我的图例,但可以从 ggplot 中引导它。

【问题讨论】:

【参考方案1】:

为此,我们将不得不稍微更改您的数据集。首先,我们将(从 tidyr 包中)收集您的 var1 和 var2,以便我们有两个新变量,一个名为 var 的变量将具有值“var1”和“var2”,另一个名为 n 的变量将具有值 var1 和 var2有。

df <- data.frame(year,month,Var1,Var2) %>%
        gather("var", "n", 3:4)

然后对于 "year" X "var" 的每个组合,我们将创建一个分段变量,指示我们将绘制哪条线。

1 代表年份 == 2015 & var == var1 2 代表年份 == 2016 & var == var1 3 for year == 2015 & var == var2 4 年 == 2016 & var == var2

就这样偷懒做

df$segment <- rep(1:4, each = 12)

现在的目标是根据线段一一画线。这将通过以下循环完成

gg <- ggplot()
for (i in 1:4) gg <- gg + 
  geom_line(data = subset(df, segment == i), 
            aes(x = as.factor(month), y = n, linetype = var,
                group = as.factor(year), color = as.factor(year))) +
  geom_point(data = subset(df, segment == i), 
            aes(x = as.factor(month), y = n, group = as.factor(year)))

请注意,这与您的区别在于 geom_line 有一个根据分段的子集数据集(我们只需要我们正在绘制的线的数据)。 y = n 根据我们之前所做的收集,现在我们设置了一个新的美学,这就是我们的 var。这样循环了4次,和段数一样。

最后添加其他主题和实验室

gg <- gg + theme(legend.title = element_blank())+
    labs(x = NULL,y = "", title = "Var1 vs. Var2")+
    scale_x_discrete(expand = c(0,0.2),
                     labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
gg

我们得到了结果

【讨论】:

但是如果加上图例上的蓝色和红色虚线会更好,不是吗? 对于这个例子,无论哪种方式都没有关系,因为你会得到 4 个图例元素(粉红色,粉红色点,蓝色全,蓝色点),但一般来说我们想要分组每种美学本身。 看起来不错,但我还没有开始,因为我收到一个错误:找不到函数“%>%”。那是在我需要调用的特定包中吗? 哦,对不起,我忘了指出,它来自 dplyr 包。 有没有办法创建一个响应数据本身的段变量?例如,如果我的数据发生变化并且我需要绘制 3 年而不是 2 年,我希望代码仍然可以工作。有了这个答案, df$segment 必须在每次更改时间范围时手动更改。【参考方案2】:
year <-   c(2015,2015,2015,2015,2015,2015,2015,2015,2015,
2015,2015,2015,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016,2016)
month <-c(1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12)
Var1 <- sample(30:60, 24, rep=TRUE)
Var2 <- sample(70:90, 24, rep=TRUE)
df <- data.frame(year,month,Var1, Var2)

如果您稍微修改一下 data.frame 的格式,并使用交互将 ggplot2 中的 2 个变量分组。干得好。我正在使用data.table,因为我不再知道如何将 data.frame 转换为 long。

library(data.table)
library (ggplot2)
ggplot(melt(as.data.table(df),id.vars=c("year","month")))+   
geom_line(aes(x=as.factor(month), 
y=value, group=interaction(variable,  as.factor(year)),
color=as.factor(year),linetype=variable), size=0.9) + 
labs(x = NULL,y = "", title = "Var1 vs. Var2")+
 scale_x_discrete(expand = c(0,0.2),
                  labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))

【讨论】:

以上是关于如何调整图例属性以显示 2 个特征?的主要内容,如果未能解决你的问题,请参考以下文章

图表形状样式怎么设置

matlab调整legend方框大小

如何在ggpubr中调整图例的大小

如何修改散点图图例以显示相同类型句柄的不同格式?

D3 如何以文本或使用图例显示我的数据集

sns.pairplot 中的图例未完全显示