【问题标题】:make the width scale of y axis proper size in R在R中使y轴的宽度比例适当大小
【发布时间】:2021-03-15 13:32:28
【问题描述】:

如何校正 y 轴的跨度,因为第一个图表的范围较大,但最后一个图表的范围较小。

我尝试使用 expand_limit() ,但我必须定义限制。我想要的是根据平均值 +- 10% 指定我的限制

Data
structure(list(height = structure(1:21, .Label = c("_150_5_", 
"_150_4_", "01_150_3_", "01_150_2_", "_150_1_", 
"01_130_5_", "01_130_4_", "01_130_3_", "01_130_2_", 
"L01_130_1_", "01_100_5_", "01_100_4_", "01_100_3_", 
"01_100_2_", "01_100_1_", "01_60_5_", "01_60_4_", 
"01_60_3_", "01_60_2_", "01_60_1_", "01_30_5_"
), class = "factor"), max = c(153.502609757564, 153.803890640307, 
154.030628562627, 153.502609757564, 153.577819267489, 133.497584806195, 
133.440753139611, 133.896765965376, 134.068575331457, 133.725396384362, 
102.872441458794, 103.347289523556, 103.279185873129, 101.048462000305, 
102.035263387027, 60.852713866229, 60.8645299271739, 60.9236791302129, 
60.8763505777715, 61.0542129187662, 30.8972231764362), mean = c(152.038047221229, 
151.858031107105, 152.211206935181, 151.759867764584, 150.344389742043, 
131.874101333396, 131.706179220053, 131.043612919162, 132.264362261993, 
130.599623937693, 101.774080628225, 102.110144624754, 102.239940146821, 
100.053415273797, 100.577556727676, 60.299452319695, 60.3004949199648, 
60.3066081777292, 60.3048844335163, 60.3267015589117, 30.347932670538
), min = c(150.120847282062, 148.344689600069, 148.767123457497, 
148.20441093378, 146.06352708525, 129.15217516479, 129.258692422658, 
127.367870428665, 129.418798152331, 127.006616339119, 99.7938010585627, 
100.401130405172, 101.081047766832, 98.2917306757434, 99.1623945349401, 
59.7507299132569, 59.7507299132569, 59.8077330900488, 59.7507299132569, 
59.8191467795698, 29.7732075536612), sd = c(0.384120348675233, 
0.996143559832467, 0.892389162104352, 0.668245088780541, 1.26871400480022, 
0.717796939735463, 0.841062860547558, 1.09283360068465, 0.801961749792679, 
1.40866403449516, 0.370811042540416, 0.387499052903713, 0.273143219592094, 
0.372612511324188, 0.448178158096896, 0.141781338201885, 0.143328065432486, 
0.140326202644008, 0.141854728955873, 0.139981570704421, 0.155319872754675
)), class = "data.frame", row.names = c(NA, -21L))

我尝试过的代码

    ii=1
 k=0
 plot_list_stat=list()
 par(mfcol = c(5, 1))
 for (i in 1:4 ){
   k=k+1
 plot_list_stat[[ii]]=ggplot(stat.std_w[k:(k+4),],aes(x=height,y=mean,group=1))+
   geom_ribbon(aes(x=height,ymax=max,ymin=min,color="min-max"
   ),alpha=0.6,fill= "skyblue",show.legend=TRUE)+ 
   scale_fill_manual("",values ="skyblue", guide = FALSE)+
   geom_line()+ylab("")+
   geom_point()+
   theme(axis.text.x = element_text(angle = 90))+
   geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd,color="mean±sd"
   ), width=.2,position=position_dodge(0.05))+theme(legend.position = "none")
 print(ii); #plot_list_stat[[ii]]
 ii=ii+1;k=k+4;)

 library("cowplot")
pgrid=plot_grid(plotlist=plot_list_stat,nrow=1)
library(ggpubr)
pgrid=ggarrange(pgrid,common.legend = T)
annotate_figure(pgrid,
                top = text_grob("statistic ", size = 14),
                left = text_grob(" mean",rot = 90))

【问题讨论】:

  • 请分享您尝试使用dput(data) 绘制图表的数据样本以及您迄今为止尝试制作您分享的图表的代码。
  • 我已添加代码

标签: r ggplot2


【解决方案1】:

默认情况下,绘图区域会从数据中的极值扩大一小部分。有许多机制可以根据您的需要手动覆盖此行为。一般来说,它们在分面图中实现起来要困难得多,但您所追求的视觉效果确实需要分面,所以下面我将展示一个使用 geom_blank() 的解决方案,该解决方案适用于本示例。

library(tidyverse)

# parse text in 'height' variable to be sortable
df2 <- df %>% 
  separate(col = height, into = c("sub_grp", "grp", "order"), remove = F, fill = "left") %>% 
  mutate(grp = fct_rev(factor(as.numeric(grp))),
         order = fct_rev(factor(as.numeric(order)))) 
#> Warning: Expected 3 pieces. Additional pieces discarded in 21 rows [1, 2, 3, 4,
#> 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].

# set fraction to expand plot by
# these are based on the requested +/- 10% in the question
fract_up <- 1.1
fract_down <- 0.9

# extract table of limits to expand plot by
df3 <- df2 %>% 
  group_by(grp) %>% 
  summarise(grp_mean = mean(mean), grp_order = mean(as.numeric(order))) %>% 
  mutate(grp_top = fract_up * grp_mean, grp_bot = fract_down * grp_mean, .keep = "unused") %>% 
  pivot_longer(-c(grp, grp_order), names_to = "type", names_prefix = "grp_")

# plot it all together
df2 %>% 
  ggplot(aes(x = order, y = mean, group = grp)) +
  geom_ribbon(
    aes(
      ymax = max,
      ymin = min,
      color = "min-max",
      group = grp
    ),
    alpha = 0.6,
    fill = "skyblue"
  ) +
  geom_line() + 
  geom_point() +
  geom_errorbar(
    aes(
      ymin = mean - sd,
      ymax = mean + sd,
      color = "mean±sd"
    ),
    width = .2,
    position = position_dodge(0.05)
  ) + 
  geom_blank(data = df3, aes(x = grp_order, y = value)) +
  facet_wrap(facets = vars(grp),
             scales = "free",
             nrow = 1) +
  scale_x_discrete(NULL, labels = df2$height) +
  ggtitle("Standard statistic") +
  ylab("Mean") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5), 
        plot.title = element_text(hjust = 0.5))
#> geom_path: Each group consists of only one observation. Do you need to adjust
#> the group aesthetic?

reprex package (v1.0.0) 于 2021-03-15 创建

【讨论】:

    【解决方案2】:

    我会改用构面。有了这个 for 循环,你的生活就会变得非常复杂。

    library(tidyverse)
    
    df %>% 
      # makes new variables
      separate(height, into = c("x", "height", "index")) %>%
    ggplot(aes(x = index, y = mean, group = 1)) +
      geom_ribbon(aes(x = index, ymax = max, ymin = min, color = "min-max"), alpha = 0.6, fill = "skyblue", show.legend = TRUE) +
      geom_line() +
      geom_point() +
      geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd, color = "mean±sd"), width = .2, position = position_dodge(0.05)) +
      scale_fill_manual(values = "skyblue", guide = FALSE) +
      labs(y = NULL) + # use NULL, not "" !!
      facet_grid(~height) +
      theme(axis.text.x = element_text(angle = 90), legend.position = "none")
    #> Warning: Expected 3 pieces. Additional pieces discarded in 21 rows [1, 2, 3, 4,
    #> 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
    #> geom_path: Each group consists of only one observation. Do you need to adjust
    #> the group aesthetic?
    

    reprex package (v1.0.0) 于 2021-03-15 创建

    我个人更喜欢在这种情况下使用相同的比例,但如果您想要灵活的 y 比例,请改用facet_wrap

    df %>% 
      # makes new variables
      separate(height, into = c("x", "height", "index")) %>%
      ggplot(aes(x = index, y = mean, group = 1)) +
      geom_ribbon(aes(x = index, ymax = max, ymin = min, color = "min-max"), alpha = 0.6, fill = "skyblue", show.legend = TRUE) +
      geom_line() +
      geom_point() +
      geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd, color = "mean±sd"), width = .2, position = position_dodge(0.05)) +
      scale_fill_manual(values = "skyblue", guide = FALSE) +
      labs(y = NULL) +
      facet_wrap(~height, scales = "free_y", nrow = 1) +
      theme(axis.text.x = element_text(angle = 90), legend.position = "none")
    
    

    【讨论】:

    • 我应该使用 scale y 吗?我只想绘制另一个 y 轴比例,我的意思是 60 的应该比 150 的更薄。谢谢建议我使用 facet_wrap
    • @Peter_pan_pinter 单独设置每个比例,检查stackoverflow.com/a/51736379/7941188
    • @Peter_pan_pinter - 我刚刚更新了我的答案,将每个面板分别调整为该面板平均值的 +/- 10%。我想这就是你所追求的?如果不是,请说明用于确定地块面积调整的计算。
    猜你喜欢
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    相关资源
    最近更新 更多