ggplot2:为stat_summary内部的平滑几何图形添加填充美学

And*_*ach 1 plot r ggplot2

我有什么是使用stat_summary生成均值和置信带如何在ggplot2 stat_summary图中设置多种颜色时删除数据点的版本并且也可能与此错误报告有关,该错误报告与SE参数https://github.com/tidyverse/ggplot2/issues/1546有关,但我似乎无法弄清楚自己在做什么错。

我有每周数据,并试图绘制当前年份,上一年,5年平均值和5年范围。我可以获得图和所需的所有元素,但无法获得与scale_fill命令相关的范围内的填充。

绘制样本

这是我正在使用的代码:

library(plyr)
require(dplyr)
require(tidyr)
library(ggplot2)
library(lubridate)
library(zoo) 
library(viridis)

  ggplot(df1,aes(week,value)) +
  geom_point(data=subset(df1,year(date)==year(Sys.Date()) ),size=1.7,aes(colour="1"))+ 
  geom_line(data=subset(df1,year(date)==year(Sys.Date()) ),size=1.7,aes(colour="1"))+ 
  geom_line(data=subset(df1,year(date)==year(Sys.Date())-1 ),size=1.7,aes(colour="2"))+
  geom_point(data=subset(df1,year(date)==year(Sys.Date())-1 ),size=1.7,aes(colour="2"))+ 
  #stat_summary(data=subset(df1,year(date)<year(Sys.Date()) &year(date)>year(Sys.Date())-6),geom = 'smooth', alpha = 0.2,size=1.7,
  #             fun.data = median_hilow,aes(colour=c("1","2","3"),fill="range"))+
  stat_summary(data=subset(df1,year(date)<year(Sys.Date()) &year(date)>year(Sys.Date())-6),geom="smooth",fun.y = mean, fun.ymin = min, fun.ymax = max,size=1.7,aes(colour="c",fill="b"))+
  #stat_summary(fun.data=mean_cl_normal, geom='smooth', color='black')+
  scale_color_viridis("",discrete=TRUE,option="C",labels=c(year(Sys.Date()), year(Sys.Date())-1,paste(year(Sys.Date())-6,"-",year(Sys.Date())-1,"\naverage",sep ="")))+
  scale_fill_viridis("",discrete=TRUE,option="C",labels=paste(year(Sys.Date())-6,"-",year(Sys.Date())-1,"\nrange",sep =""))+     
  #scale_fill_continuous()+
  scale_x_continuous(limits=c(min(df1$week),max(df1$week)),expand=c(0,0))+
  theme_minimal()+theme(
    legend.position = "bottom",
    legend.margin=margin(c(0,0,0,0),unit="cm"),
    legend.text = element_text(colour="black", size = 12),
    plot.caption = element_text(size = 14, face = "italic"),
    plot.title = element_text(face = "bold"),
    plot.subtitle = element_text(size = 14, face = "italic"),
    #panel.grid.minor = element_blank(),
    text = element_text(size = 14,face = "bold"),
    axis.text.y =element_text(size = 14,face = "bold", colour="black"),
    axis.text.x=element_text(size = 14,face = "bold", colour="black",angle=90, hjust=1),
  )+
  labs(y="Crude Oil Imports \n(Weekly, Thousands of Barrels per Day)",x="Week",
       title=paste("US Imports of Crude Oil",sep=""),
       caption="Source: EIA API, graph by Andrew Leach.")
Run Code Online (Sandbox Code Playgroud)

我在这里放置了带有df1数据框的test.Rdata文件:https ://drive.google.com/file/d/1aMt4WQaOi1vFJcMlgXFY7dzF_kjbgBiU/view?usp=sharing

理想情况下,我希望有一个看起来像这样的填充图例项,并且只包含图形中的文本: 在此处输入图片说明

任何帮助将非常感激。

jdo*_*res 5

简短的答案是,您似乎误解了ggplot的scale_xx_xx命令是如何使用的(这使很多人感到困惑)。尽可能将美学(aes()大多数几何图形内部的位)映射到scale函数。例如,以下代码将年份映射到行颜色:

plot.simple <- ggplot(data = df1, aes(x = week, y = value, color = as.factor(year(date)))) +
  geom_line()
print(plot.simple)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

由于我们指定应使用年份(转换为因子)来定义线条颜色,因此ggplot默认使用scale_color_hue。我们可以使用不同的比例:

plot.gray <- ggplot(data = df1, aes(x = week, y = value, color = as.factor(year(date)))) +
  geom_line() +
  scale_color_grey()
print(plot.gray)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如果我们不想将诸如颜色或填充之类的美学与数据中的值联系起来,我们可以在对的调用之外指定它们aes()。通常,只有在没有多个美学价值的情况下,您才这样

plot.simple <- ggplot(data = df1, aes(x = week, y = value, color = as.factor(year(date)))) +
  geom_line(alpha = 0.2)
print(plot.simple)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

但是,您处于同时需要这两个条件的令人羡慕的地位。对于2017年和2018年的线条,颜色是有意义的。对于摘要功能区及其关联的线,颜色仅是装饰性的。在这种情况下,我通常避免使用ggplot的内置摘要功能,因为它们通常可以以令人困惑或麻烦的方式“提供帮助”。

我建议创建两个数据集,一个包含2017年和2018年,另一个包含功能区的摘要统计信息:

df.years <- df1 %>% 
  mutate(year = year(date)) %>% 
  filter(year >= year(Sys.Date()) - 1)

df.year.range <- df1 %>% 
  mutate(year = year(date)) %>% 
  filter(year >= year(Sys.Date()) - 6 & year <= year(Sys.Date()) - 1) %>% 
  group_by(week) %>% 
  summarize(mean = mean(value), min = min(value), max = max(value))
Run Code Online (Sandbox Code Playgroud)

然后,通过将内部aes的fill设置为预期的字符串,我们可以欺骗ggplot在图例上填充一个漂亮的标题。由于设置了填充aes(),我们用scale_fill_manual

the.plot <- ggplot() +
  geom_ribbon(data = df.year.range, aes(x = week, ymin = min, ymax = max, fill = 'Previous 5 Year Range\nof Weekly Exports')) +
  geom_line(data = df.year.range, aes(x = week, y = mean), color = 'purple') +
  geom_line(data = df.years, aes(x = week, y = value, color = as.factor(year))) +
  geom_point(data = filter(df.years, year == year(Sys.Date())), aes(x = week, y = value, color = as.factor(year))) +
  scale_fill_manual(values = '#ffccff')
print(the.plot)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这仍然很麻烦,因为您有很多不同的元素与各种不同的数据源相关联(某些年份的行,另一些年份的点,摘要的功能区等)。但这可以完成工作!