在ggplot2中的一个图形中自定义两个图例

时间:2017-11-30 15:41:40

标签: r ggplot2 legend

我想对以下疑问发表评论。

使用此代码:

Plot<-data.frame(Age=c(0,0,0,0,0),Density=c(0,0,0,0,0),Sensitivity=c(0,0,0,0,0),inf=c(0,0,0,0,0),sup=c(0,0,0,0,0),tde=c(0,0,0,0,0))    
Plot[1,]<-c(1,1,0.857,0.793,0.904,0.00209834)
Plot[2,]<-c(1,2,0.771   ,0.74,0.799,0.00348286)
Plot[3,]<-c(1,3,0.763   ,0.717,0.804,0.00577784) 
Plot[4,]<-c(1,4,0.724   ,0.653,0.785,0.00504161)
Plot[5,]<-c(2,1,0.906,0.866,0.934,0.00365742)
Plot[6,]<-c(2,2,0.785   ,0.754,0.813,0.00440399)
Plot[7,]<-c(2,3,0.660,0.593,0.722,0.00542849)
Plot[8,]<-c(2,4,0.544,0.425,0.658,0.00433052)

     names(Plot)<-c("Age","Mammographyc density","Sensitivity","inf","sup","tde")
    Plot$Age<-c("50-59","50-59","50-59","50-59","60-69","60-69","60-69","60-69")
    Plot$Density<-c("Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense","Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense")    
levels(Plot$Age)<-c("50-59","60-69")
levels(Plot$Density)<-c("Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense")
pd <- position_dodge(0.2) # 
    Plot$Density <- reorder(Plot$Density, 1-Plot$Sensitivity)

ggplot(Plot, aes(x = Density, y = 100*Sensitivity, colour=Age)) + 
  geom_errorbar(aes(ymin = 100*inf, ymax = 100*sup), width = .1, position = pd) +
  geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
  geom_point(position = pd, size = 4)+
  scale_y_continuous(expand = c(0, 0),name = 'Sensitivity (%)',sec.axis = sec_axis(~./5,   name  = 'Breast cancer detection rate (per 1000 mammograms)', breaks = c(0,5,10,15,20),
                                                              labels = c('0‰',"5‰", '10‰', '15‰', '20‰')), limits = c(0,100)) +
   geom_line(position = pd, aes(x = Density, y = tde * 5000, colour = Age, group = Age), linetype = c("dashed"), data = Plot) +
  geom_point(shape=18,aes(x = Density, y = tde * 5000, colour = Age, group = Age), position = pd, size = 4) +
  theme_light() + 
 scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
  theme(legend.position="bottom") + guides(colour = guide_legend(), size = guide_legend(),
                                         shape = guide_legend())

我制作了以下图表,

Graph

其中左边的轴是圆的刻度,右边的轴是钻石的刻度。事实是,我希望有一个类似的传奇:

Legend

但对我来说这是不可能的,我已经尝试了其他线程的建议,例如scale_shapeguides中的不同命令,但我没有成功。我只想弄清楚形状和颜色代表的区别。

有人会知道如何帮助我吗?

致以最诚挚的问候,

1 个答案:

答案 0 :(得分:2)

应该做的是一个面板图,以避免混淆双轴:

library(dplyr)
library(tidyr)
Plot %>% 
  gather(measure, Result, Sensitivity, tde) %>%
  ggplot(aes(x = Density, y = Result, colour=Age)) + 
  geom_errorbar(aes(ymin = inf, ymax = sup), width = .1, position = pd,
                data = . %>% filter(measure == "Sensitivity")) +
  geom_line(aes(group = Age), position = pd, linetype = "dashed") +
  geom_point(position = pd, size = 4)+
  # scale_y_continuous(expand = c(0, 0), limits = c(0, 1)) +
  scale_y_continuous(labels = scales::percent) +
  facet_wrap(~measure, ncol = 1, scales = "free_y") +
  theme_light() + 
  scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
  theme(legend.position="bottom")

enter image description here

但要做你所问的问题,你的问题是你只有1个非位置美学图,所以你不能得到多个传奇。要强制第二个图例,您需要添加第二个图例。它可以是无效的虚拟映射,如下面我们映射alpha但是然后手动将两个级别缩放到100%。此解决方案是不可取的因为,正如您在所需图例的示例中所做的那样,很容易混淆映射并通过错误标记哪些点是敏感性以及哪些是敏感来说明谎言检测率。

ggplot(Plot, aes(x = Density, y = 100*Sensitivity, colour=Age, alpha = Age)) + 
  geom_errorbar(aes(ymin = 100*inf, ymax = 100*sup), width = .1, position = pd) +
  geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
  geom_point(position = pd, size = 4)+
  scale_y_continuous(expand = c(0, 0),name = 'Sensitivity (%)',sec.axis = sec_axis(~./5,   name  = 'Breast cancer detection rate (per 1000 mammograms)', breaks = c(0,5,10,15,20),
                                                                                   labels = c('0‰',"5‰", '10‰', '15‰', '20‰')), limits = c(0,100)) +
  geom_line(position = pd, aes(x = Density, y = tde * 5000, colour = Age, group = Age), linetype = c("dashed"), data = Plot) +
  geom_point(shape=18,aes(x = Density, y = tde * 5000, colour = Age, group = Age), position = pd, size = 4) +
  theme_light() + 
  scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
  scale_alpha_manual(values = c(1, 1)) +
  guides(alpha = guide_legend("Sensitivity"),
         color = guide_legend("Detection Rate", override.aes = list(shape = 18))) +
  theme(legend.position="bottom")

enter image description here