使用图例 ggplot2 上的线条更改形状

时间:2021-03-24 20:21:41

标签: r ggplot2 plot

我是 R 新手,我正在尝试绘制带有一些图例的图形,问题是我无法将“形状线”图标更改为另一种形状,它只会制作另一个图例,正确的图标应该是“三角线”和“方线”

library(lubridate)
library(ggplot2)
library(tidyverse)
ano <- c(1999:2019)
comeco <- mdy("01-01-1999")
fim <- mdy("01-01-2019")
por <- "1 year"

x <- seq(comeco, fim, by = por)
ano <- x
inferior <- c(6, 4, 2, 1.5, 1.5, 3, 2, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3, 3, 2.75)
superior <- c(10, 8, 6, 5.5, 6.5, 8, 7, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5, 6, 6, 5.75)
meta <- c(8, 6, 4, 3.5, 4, 5.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.25)
inflacao <- c(8.94, 5.97, 7.67, 12.53, 9.3, 7.6, 5.69, 3.14, 4.46, 5.9, 4.31, 5.91, 6.5, 5.84, 5.91, 6.41, 10.67, 6.29, 2.95, 3.75, 4.31)

df1 <- data.frame(ano, inferior, superior, inflacao, meta)

df1 %>% 
  ggplot(aes(ano, inflacao)) +
  theme(text = element_text(family = "serif")) +
  theme(axis.text = element_text(size = 8)) +
  theme(legend.title = element_blank()) +
  labs(
    x = "Anos",
    y = "Taxa (%)"
  ) +
  scale_x_date(date_labels = "%Y", breaks = df1$ano) + 
  theme(axis.text.x = element_text(vjust = 0)) +
  theme(axis.title.x = element_text(vjust = -1)) +
  theme(legend.position = "top") +
  
  geom_line(aes(x = ano, y = meta, linetype = "Meta de Inflação")) +
  geom_line(aes(x = ano, y = inflacao, linetype = "Inflação Efetiva"), size = 0.5) +
  
  geom_point(aes(x = ano, y = superior, color = "Limite Superior", shape = "Limite Superior"), size = 2) +
  geom_line(aes(x = ano, y = superior, color = "Limite Superior"), size = 0.5) +
  
  geom_point(aes(x = ano, y = inferior, color = "Limite Inferior", shape = "Limite Inferior"), size = 2) +
  geom_line(aes(x = ano, y = inferior, color = "Limite Inferior"), size = 0.5) +
  
  scale_color_manual(values = c("Meta de Inflação" = "black", "Inflação Efetiva" = "black", 
                                "Limite Superior" = "blue", "Limite Inferior" = "black")) +
  scale_linetype_manual(values = c("Meta de Inflação" = "solid", "Inflação Efetiva" = "dashed",
                                   "Limite Superior" = "solid", "Limite Inferior" = "solid")) +
  scale_shape_manual(values = c("Limite Superior" = 17, "Limite Inferior" = 15))

enter image description here

1 个答案:

答案 0 :(得分:2)

我强烈建议您查看 this vignette on Tidy Data,这是一种组织数据集以便于绘制和分析的概念性方法。这是“tidyverse”的基础,它包括 ggplot2 之类的包。虽然我可以根据您现有的数据集 df1 帮助您组合您的图例,但如果我们将您的数据框重塑为“整洁”然后使用它会容易得多。我将在这里向您展示这种方法。

整理您的数据

整理数据的一般原则是,当数据显示相同类型的值时,不应将数据“分散”到多列上。在您的情况下,您有 ano,它显示日期并且很好。其余的列都填充了“分类群”的值,每一列代表您识别特定“分类群”的不同方式。因此,我们需要首先将这些其他列收集在一起,以便您的数据集现在读取 3 列:ano | type | taxa。总体而言,这意味着您的数据框“更长”(更多观察/行)。您可以通过多种方式执行此操作,但我在这里展示的是我通常使用的一种方式,即使用 gather() 包中的 dplyr 函数。不过,这都是 tidyverse 包的一部分:

df1 <- df1 %>% gather(key='type', value='taxa', -c(ano))

您应该能够理解这一点,但基本上我们告诉 gather() 忽略 ano 列,对于其余部分,将列名称推入新列({{1} }) 称为 key=,并将这些单元格中的值放入名为 "type" 的新列 (value=) 中。

绘制您的数据

对于情节,它变得简单了很多。每个 "taxa" 调用只需要一行,我们将分配形状、颜色和值。在此之前,我将创建一个命名向量,以便更轻松地指定我们希望图例标签对于 geom 中的任何值的外观:

df1$type

对于情节代码,我将向您展示代码和情节,然后解释一下它的工作原理:

my_labels <- c(
  'superior'='Limite Superior',
  'inferior'='Limite Inferior',
  'meta'='Meta de Inflação',
  'inflacao'='Inflação Efetiva'
)

enter image description here

我喜欢将我的情节代码组织成专门用于情节主要部分的特定部分。

绘制地图和几何图形

这部分是我们指定如何将数据框转换为特定几何体的地方。请注意,由于我们有一个漂亮整洁的数据框,我们需要做的就是指定一个 df1 %>% # plot mapping and geoms ggplot(aes(ano, taxa)) + geom_line(aes(linetype = type, color = type), size = 0.5) + geom_point(aes(color = type, shape = type), size = 2) + # scale functions scale_x_date(date_labels = "%Y", breaks = df1$ano) + scale_color_manual(values = c( "meta" = "black", "inflacao" = "black", "superior" = "blue", "inferior" = "black"), labels=my_labels) + scale_linetype_manual(values = c( "meta" = "solid", "inflacao" = "dashed", "superior" = "solid", "inferior" = "solid"), labels=my_labels) + scale_shape_manual(values = c( "meta"=NA, "inflacao"=NA, "superior"=17, "inferior"=15), labels=my_labels) + # labeling and theme elements labs( x = "Anos", y = "Taxa (%)" ) + theme( text = element_text(family = "serif"), axis.text = element_text(size = 8), legend.title = element_blank(), axis.text.x = element_text(vjust = 0), axis.title.x = element_text(vjust = -1), legend.position = "top" ) 美学(y),并使用 taxa 作为映射到 {{1} }、typeshape。然后,我们将在 color 函数中指定与映射关联的首选值。请注意,我们希望在图例中区分的所有美学都包含在 linetype 中。

尺度函数

这部分代码是我们为我们在绘图代码的第一部分中映射的所有美学提供值和指定颜色的地方。您也可以在此处指定 scale_。我本可以通过在绘图之前先将 aes() 转换为一个因子来更改 labels,但我更喜欢在这里这样做,因为它具有如此多的特定映射更简单一些。这就是我们首先创建 label 命名向量的原因。请注意,您需要为每个 df1$type 函数指定相同的标签。如果没有或者标题不同,您将强制 my_labels 将图例分开,您将得到与开始时显示的内容类似的内容。

为了不显示两条 scale_ 行的点,我将这两个 ggplot2 值的 type 值指定为 shape。所以在最后的图中,点实际上是为所有东西绘制的,但是对于这些点,它们是用 NA 绘制的……换句话说,它们是不可见的。 :)

主题元素和标签

情节的最后一部分是我放置所有主题和概括情节标签的地方。您会注意到,将所有主题元素组合到一个对 type 的调用中是一种很好的做法。