【问题标题】:Adding Legends in Graphs without tidy data在没有整洁数据的图表中添加图例
【发布时间】:2021-06-17 05:06:29
【问题描述】:
#Plot the in sample forecasts against the actual values
#Build the confidence interval

Upper95 <- fcast1 + 1.96*sqrt(Var1)

Lower95 <- fcast1 - 1.96*sqrt(Var1)

Upper80 <- fcast1 + 1.28*sqrt(Var1)

Lower80 <- fcast1 - 1.28*sqrt(Var1)
#Create a data frame

dfb <- data.frame(TeslaWeeklyPrices$Date,fcast1,TeslaWeeklyPrices$TeslaPrices,Upper95,Lower95,Upper80,Lower80)
#Make the Plot

Plot1 <- ggplot(dfb, aes(x=TeslaWeeklyPrices.Date, y=TeslaWeeklyPrices.TeslaPrices))+ 
  geom_ribbon(data=dfb,aes(ymin=Upper95,ymax=Lower95),fill = "slategray2")+ 

  geom_ribbon(data=dfb,aes(ymin=Upper80,ymax=Lower80),fill = "bisque")+ 

  geom_line(data=dfb, aes(x=TeslaWeeklyPrices.Date, y=fcast1),size=1, color="red1")+

  geom_point(shape = 19,  fill = "white", colour = "blue" ,size = 1)+ 

  theme_light(base_size = 11) +

  ylab("Tesla Stock price ($)") + xlab("Date (weeks)")

Plot1  

这是我的图表代码。

看起来就是这样。我想在我的图表中添加图例,而不必整理我的数据。因为那样我就不能按照我的意愿格式化我的图表了。

在我得到有用的评论之后。

Upper95

Lower95

Upper80

Lower80

dfb

Plot1

geom_ribbon(aes(ymin=Upper95, ymax=Lower95, fill='95% 预测水平')) +

geom_ribbon(aes(ymin=Upper80, ymax=Lower80, fill='80% 预测水平')) +

geom_line(data=dfb, aes(x=TeslaWeeklyPrices.Date, y=fcast1, color="预测值"),size=1)+

geom_point(shape = 19, aes(color = "Observed Values"), 填充 = "白色", 大小 = 1 ,)+

scale_fill_manual(values=c('95% 预测水平'='slategray2', '80% 预测水平'="bisque"), breaks=c('95% 预测水平', '80% 预测水平') ) +

scale_color_manual(values=c("Predicted Values"="red","Observed Values"= "blue"), breaks=c('Predicted Values', 'Observed Values'))+ 指南(color=guide_legend(title=NULL),fill=guide_legend(title=NULL)) +

主题(legend.margin = margin(b=0, t=-1000))+

theme_light(base_size = 12)

情节1

这是我的新代码。

那么我的蓝点怎么会看起来像图例中的点而不是一条线。以及如何将我的 2 个图例之间的边距设为 0?

我可以设置它的背景颜色,使它看起来像一个独立的部分而不是图形的一部分吗?

这是我在一篇论文中看到的一个例子。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    首先,我确实对评论有点问题:

    我想在我的图表中添加图例,而不必整理我的数据。 因为那样我就不能按照我的意愿格式化我的图表了。

    整理您的数据通常是做到这一点的最佳解决方案(根据需要格式化图表),但我同意在这种情况下,将图例“蛮力”到位可能更直接。我会告诉你怎么做。

    由于我没有你的数据,所以我自己编造了你分享的镜像:

    set.seed(1234)
    
    time <- 1:50
    Var1 <- unlist(lapply(time, function(x) rnorm(1, 1, 0.01)))
    fcast1 <- unlist(lapply(time, function(x) { x * rnorm(1, 0.1, 0.01)}))
    Upper95 <- fcast1 + 1.96*sqrt(Var1)
    Lower95 <- fcast1 - 1.96*sqrt(Var1)
    Upper80 <- fcast1 + 1.28*sqrt(Var1)
    Lower80 <- fcast1 - 1.28*sqrt(Var1)
    
    dfb <- data.frame(time, fcast1, Upper95, Lower95, Upper80, Lower80)
    

    还有剧情:

    ggplot(dfb, aes(time, fcast1)) +
      geom_ribbon(aes(ymin=Upper95, ymax=Lower95), fill='slategray2') +
      geom_ribbon(aes(ymin=Upper80, ymax=Lower80), fill='bisque') +
      geom_line(size=1, color='red1') +
      theme_light()
    

    要创建图例 没有 Tidy 数据,您需要逐个制作图例,但仍然使用 ggplot 来完成。图例是为不属于ggplot2 中坐标系的美学而创建的,它们位于aes() 内部。因此,要使图例出现,只需将美学修饰符fillcolor 放在每个geom_*() 函数的aes() 部分内即可。

    虽然不是那么简单,但是一旦您了解了它的工作原理,它就会变得更加清晰。您在aes() 中分配给fill=color= 的值将用于图例中的标签,而不是颜色。您必须使用 scale_*() 函数指定颜色。

    ggplot(dfb, aes(time, fcast1)) +
      geom_ribbon(aes(ymin=Upper95, ymax=Lower95, fill='Upper')) +
      geom_ribbon(aes(ymin=Upper80, ymax=Lower80, fill='Lower')) +
      geom_line(size=1, aes(color="Forecast")) +
      scale_fill_manual(values=c('Upper'='slategray2', 'Lower'='bisque'), breaks=c('Upper', 'Lower')) +
      scale_color_manual(values='red1') +
      theme_light()
    

    看起来更像,但并不完美。也许您希望图例中的线条和填充框改为“一个”图例框?如果是这种情况,你就不能真正做到这一点(因为它们跨越了两个不同的美学修饰符,fillcolor);但是,如果我们做一些事情,我们可以达到同样的效果:

    1. 删除颜色图例的标题
    2. 更改填充图例的标题
    3. 使用 theme 元素和边距将图例靠得更近,看起来像一个

    在这里你可以看到你可以如何做到这一点:

    p + # this is the code from above
      guides(
        color=guide_legend(title=NULL),
        fill=guide_legend(title='Legend')
      ) +
      theme(legend.margin = margin(b=0, t=-13))
    

    编辑:

    OP 询问这些点是否也可以出现在图表上。他们当然可以,而且你必须使用类似的方法来做到这一点。您可以像以前一样将color= 添加到aes() 中以获得geom_point()

    ggplot(dfb, aes(time, fcast1)) +
      geom_ribbon(aes(ymin=Upper95, ymax=Lower95, fill='Upper')) +
      geom_ribbon(aes(ymin=Upper80, ymax=Lower80, fill='Lower')) +
      geom_line(size=1, aes(color="Forecast")) +
      geom_point(size=1, aes(color='Actual Values'), shape=19) +
      scale_fill_manual(values=c('Upper'='slategray2', 'Lower'='bisque'), breaks=c('Upper', 'Lower')) +
      scale_color_manual(values=c('Forecast'='red1', 'Actual Values'='blue')) +
      theme_light() +
      guides(
        color=guide_legend(title=NULL),
        fill=guide_legend(title='Legend')
      ) +
      theme(legend.margin = margin(b=0, t=-13))
    

    有一个小问题...您会注意到“实际值”和“预测”旁边的图标(称为“字形”)是一条线 + 一个点。我认为您更愿意将点作为点的字形,将线作为线的字形。我们不能在同一个图例中这样做(它们都是color 图例的一部分)......所以我们可以通过将“实际值”分成另一个图例来解决这个问题。在这种情况下,我们将只使用 shape 美学修饰符并拥有第三个同样没有标题的图例。

    ggplot(dfb, aes(time, fcast1)) +
      geom_ribbon(aes(ymin=Upper95, ymax=Lower95, fill='Upper')) +
      geom_ribbon(aes(ymin=Upper80, ymax=Lower80, fill='Lower')) +
      geom_line(size=1, aes(color="Forecast")) +
      geom_point(size=1, aes(shape='Actual Values'), color='blue') +
      scale_fill_manual(values=c('Upper'='slategray2', 'Lower'='bisque'), breaks=c('Upper', 'Lower')) +
      scale_color_manual(values=c('Forecast'='red1')) +
      scale_shape_manual(values=19) +
      theme_light() +
      guides(
        color=guide_legend(title=NULL),
        shape=guide_legend(title=NULL),
        fill=guide_legend(title='Legend')
      ) +
      theme(legend.margin = margin(b=0, t=-13))
    

    现在您拥有成为ggplot 大师所需的所有信息:)。

    【讨论】:

    • 感谢您的回答。这是一个非常有见地的。我唯一担心的是我也有这些点,它们是实际值。因此,我想问一下我的实际值的点是否可以显示在图例上。
    • 你是最棒的
    • 有一点我忘了解释:scale_fill_manual() 中的参数breaks= 可以作为按“上”和“下”顺序排列的方式。默认情况下,ggplot 在此处恢复为按字母顺序组织这些内容,但设置 breaks= 会按照我为向量指定的方式设置顺序。
    猜你喜欢
    • 2021-05-26
    • 1970-01-01
    • 2023-02-15
    • 2016-06-17
    • 1970-01-01
    • 2014-04-12
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多