【问题标题】:Misplaced subplot after removing of y label删除 y 标签后错误放置的子图
【发布时间】:2020-08-05 21:21:45
【问题描述】:

我有两个相似的条形图,grid.arrange 在两个列中,并排。 由于它们共享 y 轴的公共标签,因此我想删除右侧子图 y 轴上的标签。 我用以下方法做到这一点:

myplot2 <- arrangeGrob(q+
                         theme(axis.title.y = element_blank()), #....


这会导致两个子图的扭曲/错位。在我删除 y 标签之前,两个子图的比例完全相同,并且 x 轴处于同一水平。

问题
如何在不改变两个子图位置的情况下删除右侧图的 y 轴标签。

MRE

library(ggplot2)
library(ggthemes)
library(dplyr)
algorithm <- c(rep("0_DT",2),rep("1_RF",2),rep("2_MLP",2))
target <- rep(c("Some Data","Some Other Data"),3)
value <- runif(6,85,95) # Simulated Accuracies
data <- data.frame(target,algorithm,value)
p <- ggplot(data, aes(fill=algorithm, y=value, x=target)) + theme_classic()+
  geom_bar(position=position_dodge(0.75), stat="identity", width = 0.65,colour="black",size=0.1) + 
  scale_fill_manual("Algorithm",
                    values = alpha(c("0_DT" = "#20639B", "1_RF" = "#3CAEA3", "2_MLP" = "#F6D55C"),0.8),
                    labels=c("DT","RF","MLP"))+
  scale_y_continuous("Accuracy in %",limits = c(0,100),oob = rescale_none,
                     # breaks= sort(c(seq(0,90,10),h)),
                     breaks= seq(0,100,10),
                     expand = c(0,0)) +
  scale_x_discrete(expand=c(0.3,0.1))+
  theme(aspect.ratio =10/6)

# duplicate the plot for MRE
q <- p
myplot1 <- arrangeGrob(p,
                       top = textGrob("1", x = unit(0.05, "npc")
                                      , y   = unit(-0.5, "npc"), just=c("left","top"),
                                      gp=gpar(col="black", fontsize=18, fontfamily="Arial",fontface="bold")))
myplot2 <- arrangeGrob(q+
                         theme(axis.title.y =element_blank()),
                       top = textGrob("2", x = unit(0.05, "npc")
                                      , y   = unit(-0.5, "npc"), just=c("left","top"),
                                      gp=gpar(col="black", fontsize=18, fontfamily="Arial",fontface="bold")))

grid.arrange(myplot1,myplot2,ncol=2)

【问题讨论】:

  • 您能否验证您的代码,在尝试运行它时,我在生成数据帧(CI.Lower 不存在)、图形部分(oob = rescale_none)和使用arrange.grob。另外,合并您的数据框并使用 facet_wrap 显示两个图形怎么样?
  • 抱歉刚刚剪掉了 CI 以使其更短,错过了再次验证它。我编辑了 mre 以正常工作。我不太确定ob = rescale_non 似乎有什么问题,但评论它似乎并没有改变行为

标签: r ggplot2 plot bar-chart subplot


【解决方案1】:

如果您的数据集共享与您的示例类似的结构,则可能的解决方案是将它们绑定在一起,如下所示:

data <-  data.frame(target,algorithm,value)
data2 <- data.frame(target,algorithm,value)
data$dataset <- "Dataset1"
data2$dataset <- "Dataset2"

DF <- rbind(data, data2)

            target algorithm    value  dataset
1        Some Data      0_DT 87.33034 Dataset1
2  Some Other Data      0_DT 89.65962 Dataset1
3        Some Data      1_RF 87.65973 Dataset1
4  Some Other Data      1_RF 93.57828 Dataset1
5        Some Data     2_MLP 85.45831 Dataset1
6  Some Other Data     2_MLP 89.42200 Dataset1
7        Some Data      0_DT 87.33034 Dataset2
8  Some Other Data      0_DT 89.65962 Dataset2
9        Some Data      1_RF 87.65973 Dataset2
10 Some Other Data      1_RF 93.57828 Dataset2
11       Some Data     2_MLP 85.45831 Dataset2
12 Some Other Data     2_MLP 89.42200 Dataset2

然后,您可以简单地使用facet_wrap 来代替使用grid.arrange 来显示具有相同y 轴的两个图形:

labels = c(Dataset1 = "1",Dataset2 ="2")

library(ggplot2)
ggplot(DF, aes(x = target, y = value, fill = algorithm))+
  geom_col(position = position_dodge2())+
  facet_wrap(~dataset, scales = "free", labeller = labeller(dataset = labels))+ 
  scale_fill_manual("Algorithm",
                    values = alpha(c("0_DT" = "#20639B", "1_RF" = "#3CAEA3", "2_MLP" = "#F6D55C"),0.8),
                    labels=c("DT","RF","MLP"))+
  scale_y_continuous("Accuracy in %",limits = c(0,100),
                     breaks= seq(0,100,10),
                     expand = c(0,0)) +
  scale_x_discrete(expand=c(0.3,0.1))+
  theme_classic()+
  theme(aspect.ratio =10/6,
        strip.background = element_blank(),
        strip.text.x = element_text(size = 15, hjust = 0, face = "bold"))


编辑:更改两个方面之一的 x 顺序

根据您的 cmets,您希望仅操纵两个数据集之一的顺序。为此,一种可能的解决方案是创建 4 个 x 值,设置正确的顺序,显示它并使用 scale_x_discrete 中的参数 labels 修改它们的标签。

首先,生成完全不同的新 x 值。在这里,我通过以下方式为第二个数据集的 x 值添加一个后缀:

library(dplyr)
library(ggplot2)

DF %>% rowwise() %>% mutate(Suffix = ifelse(dataset == "Dataset2",".22","")) %>%
  mutate(Target = paste(target, Suffix, sep = "")) %>%
  mutate(Target = factor(Target, 
                         levels = c("Some Data","Some Other Data","Some Other Data.22","Some Data.22")))

Source: local data frame [12 x 6]
Groups: <by row>

# A tibble: 12 x 6
   target          algorithm value dataset  Suffix Target            
   <fct>           <fct>     <dbl> <chr>    <chr>  <fct>             
 1 Some Data       0_DT       87.3 Dataset1 ""     Some Data         
 2 Some Other Data 0_DT       89.7 Dataset1 ""     Some Other Data   
 3 Some Data       1_RF       87.7 Dataset1 ""     Some Data         
 4 Some Other Data 1_RF       93.6 Dataset1 ""     Some Other Data   
 5 Some Data       2_MLP      85.5 Dataset1 ""     Some Data         
 6 Some Other Data 2_MLP      89.4 Dataset1 ""     Some Other Data   
 7 Some Data       0_DT       87.3 Dataset2 ".22"  Some Data.22      
 8 Some Other Data 0_DT       89.7 Dataset2 ".22"  Some Other Data.22
 9 Some Data       1_RF       87.7 Dataset2 ".22"  Some Data.22      
10 Some Other Data 1_RF       93.6 Dataset2 ".22"  Some Other Data.22
11 Some Data       2_MLP      85.5 Dataset2 ".22"  Some Data.22      
12 Some Other Data 2_MLP      89.4 Dataset2 ".22"  Some Other Data.22

现在,您可以在ggplot2 中将这个新变量作为x 值传递,并使用scale_x_discretelabels 参数删除标签中的后缀,例如:

library(dplyr)
library(ggplot2)

DF %>% rowwise() %>% mutate(Suffix = ifelse(dataset == "Dataset2",".22","")) %>%
  mutate(Target = paste(target, Suffix, sep = "")) %>%
  mutate(Target = factor(Target, 
                         levels = c("Some Data","Some Other Data","Some Other Data.22","Some Data.22"))) %>%
  ggplot(aes(x = Target, y = value, fill = algorithm))+
  geom_col(position = position_dodge2())+
  facet_wrap(~dataset, scales = "free", labeller = labeller(dataset = labels))+ 
  scale_fill_manual("Algorithm",
                    values = alpha(c("0_DT" = "#20639B", "1_RF" = "#3CAEA3", "2_MLP" = "#F6D55C"),0.8),
                    labels=c("DT","RF","MLP"))+
  scale_y_continuous("Accuracy in %",limits = c(0,100),
                     breaks= seq(0,100,10),
                     expand = c(0,0)) +
  scale_x_discrete(expand=c(0.3,0.1), labels = function(x) sub("\\..*$","",x))+
  theme_classic()+
  theme(aspect.ratio =10/6,
        strip.background = element_blank(),
        strip.text.x = element_text(size = 15, hjust = 0, face = "bold"))

它回答了你的问题吗?

【讨论】:

  • 不知道facet_wrap(因为我通常用python绘制我的数据)。看起来很优雅,为你的努力点赞。需要一些时间来重构我的真实绘图,看看是否能解决它
  • 当然 ;) 不着急。也许有人会找到适合您需求的grid.arrange 解决方案。 facet_wrap 只是在您共享 y 轴和图例的特定情况下的替代方案。
  • 目前对结果非常满意。我遇到的小问题是,现在很难在正确的情节中交换组(即在正确的子情节中首先Some Data然后Some Other Data)这可能已经有资格作为一个新问题,我不想成为帮助吸血鬼。但是,如果您知道即兴的解决方案,我真的很感激
  • 什么意思?您想在正确的绘图上先显示“一些其他数据”,然后再显示“数据”?按这个顺序?
  • 没错,但左边应该保持原样。谢谢你的帮助。 facet_wrap 使 for 循环变得不必要,并大大提高了代码的可读性。我想这是值得接受的,因为它解决了我的问题:)
猜你喜欢
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
  • 2016-01-08
  • 2022-10-21
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多