ggplot2错误地分配美学

时间:2019-07-04 07:27:56

标签: r ggplot2

我正在使用ggplot2创建图,由于某种原因,该函数的行为确实很奇怪。

我有一个数据框 df ,我想可视化几列。

任何数据框都可以正常工作。我已经生成了这个虚拟数据框。

df <- data.frame(Date = seq.Date(as.Date.character("2019-01-01"), by = 1, length.out = 10), 
                 Value = rnorm(10), 
                 Foo = rnorm(10))

所以我要做的是

  library(ggplot2)
  gg <- ggplot(df, aes(x = Date)) + geom_line(aes(y = Value, color = "Value", linetype = "Value"))
  gg <- gg + geom_line(aes(y = Foo, color = "SomeWord", linetype = "SomeWord"))
  gg <- gg + scale_color_manual(name="Legend", 
      breaks=c("Value", "SomeWord"), values=c("steelblue", "firebrick")) + 
    scale_linetype_manual(name="Legend", 
      breaks=c("Value", "SomeWord"), values=c("solid", "twodash"))
  gg

通常,ggplot2现在将为 Value 列正确分配颜色 steelblue 和线型 solid ,同时分配 firebrick twodash Foo 列,我为其指定了名称​​ SomeWord 。但是,根据我为名称选择的内容,ggplot会以错误的方式分配颜色和线型。例如,使用“ Test1”作为名称似乎很好,但是“ Einschritt”会使ggplot2将我的整个规则集扔出窗口。

我尝试使用谷歌搜索,但是没有找到关于为什么ggplot似乎不接受某些名称而另一些很好的线索。我还想在颜色和线型引用名称中使用连字符,我认为可能是个问题。

编辑:例如,我刚刚尝试将其复制到我的虚拟数据帧上。使用上面发布的代码,当我使用以下名称时,线型和颜色将错误匹配:

  • “值”用于“值”列,任何内容用于Foo列。
  • “值”列的“ Ein-Schritt-Prognose”,列Foo的任何内容。
  • “值”列的“ SomeWord”,Foo列的任何东西。

但是,当我切换到类似以下内容时:

  • “ ABD”代表“值”列,所有内容代表“ Foo”列。

然后正确匹配它们。

3 个答案:

答案 0 :(得分:1)

“ Ein-Schritt-Prognose”不能用作姓氏。请在您的问题下方查看我的评论。在ggplot2中,不使用colnames,因此在colname中使用连字符会使它看起来像Ein - Schritt - Prognose(一个表达式)。在R中请谨慎使用连字符。

答案 1 :(得分:1)

首先,为了清楚起见:连字符与此无关。

问题是breaks参数根本没有用于定义数据到美学的比例。 breaks仅控制哪些数据值显示在图例上以及显示顺序。没什么。

这是一个演示(仅简化为颜色;概念相同):

library(ggplot2)

set.seed(42)

mydf <- data.frame(
  Date = seq.Date(as.Date.character("2019-01-01"), by = 1, length.out = 10),
  Value = rnorm(10), Foo = rnorm(10)
)

p <- ggplot(mydf, aes(x = Date)) +
  geom_line(aes(y = Value, color = "Value")) +
  geom_line(aes(y = Foo, color = "SomeWord"))

p1 <- p + scale_color_manual(
  breaks = c("Value", "SomeWord"),
  values = c("steelblue", "firebrick")
)

p2 <- p + scale_color_manual(
  breaks = c("SomeWord", "Value"),
  values = c("steelblue", "firebrick")
)

egg::ggarrange(p1, p2)

如您所见,美学映射保持不变:"Value"仍然是红色,"SomeWord"仍然是蓝色;仅图例的顺序已更改。如果要控制数据到美学的映射,则有两个选择:

首先,正如@markus在注释中所提到的,您可以设置作为values参数给定的向量的名称:

p + scale_color_manual(
  values = c("Value" = "steelblue", "SomeWord" = "firebrick")
)

或者(尽管不推荐),您可以依靠以limits的顺序映射美学:

p + scale_color_manual(
  limits = c("Value", "SomeWord"),
  values = c("steelblue", "firebrick")
)

(请注意,图例的顺序也发生了变化:这是因为如果未给出,breaks会被设置为limits。)

默认情况下,限制按字母顺序排序,这是您看到的行为的原因:V排在S之后,这就是为什么(如果未设置limits){{1 }}与第二种颜色匹配,"Value"与第一种颜色匹配。

关于"SomeWord"limits的不同之处:breaks控制要映射的数据值。如果我们有limits中未包含的数据值,则映射的美观度将设置为limits

NA

如果您在p + scale_color_manual( limits = c("Value"), values = c("steelblue", "firebrick") ) #> Warning: Removed 10 rows containing missing values (geom_path). 中保留一个值,则所有数据仍会被映射,但是省略的值不会显示在图例上:

breaks

reprex package(v0.3.0)于2019-07-04创建

答案 2 :(得分:0)

正如@HongboZhu正确说的那样,问题在于连字符。现在,您真正的问题是您想在图例中使用连字符。有很多方法可以更改图例标签。一种方法是在scale_x_manual函数中。

请注意,我略微缩短了您的代码,并将数据框的名称更改为mydfdf是baseR函数,不建议(尽管经常使用)作为SO上的示例名称。

mydf <- data.frame(Date = seq.Date(as.Date.character("2019-01-01"), by = 1, length.out = 10),Value = rnorm(10), Foo = rnorm(10))

library(ggplot2)
ggplot(mydf, aes(x = Date)) + geom_line(aes(y = Value, color = "Value", linetype = "Value")) +
  geom_line(aes(y = Foo, color = "SomeWord", linetype = "SomeWord")) +
  scale_color_manual(breaks=c("Value", "SomeWord"), values=c("steelblue", "firebrick"), label = c('value','Ein-SChritt-Prognose')) + 
  scale_linetype_manual(name="Legend", breaks=c("Value", "SomeWord"), values=c("solid", "twodash"))

reprex package(v0.2.1)于2019-07-04创建