查看原文
其他

使用ggplot2画一个五颜六色条形图

阿越就是我 医学和生信笔记 2023-02-25


条形图是最常见的图表类型,在使用ggplot2画条形图时常常需要把数据标签也画出来,这样可以增加条形图的可读性。把条形按照每组数据的多少排列好,可以使得读者更加关注想要的结果。

加载R包

library(tidyverse)
## -- Attaching packages ----------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5     v purrr   0.3.4
## v tibble  3.1.6     v dplyr   1.0.7
## v tidyr   1.1.3     v stringr 1.4.0
## v readr   2.0.1     v forcats 0.5.1
## -- Conflicts -------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

我们使用自带的mpg数据集作为本次演示数据集。

mpg_sum <- mpg %>% 
  filter(year == 2008) %>% 
  mutate(manufacturer = stringr::str_to_title(manufacturer), # 首字母大写
         manufacturer = forcats::fct_lump(manufacturer, n = 10)) %>% # 把个数最多的10个留下,剩下的归为一类
  count(manufacturer, sort = T) %>% 
  mutate(manufacturer = forcats::fct_rev(forcats::fct_inorder(manufacturer)), # 翻转顺序
         manufacturer = forcats::fct_relevel(manufacturer, "Other", after = 0)) # 把other放在第一位

mpg_sum
## # A tibble: 11 x 2
##    manufacturer     n
##    <fct>        <int>
##  1 Dodge           21
##  2 Toyota          14
##  3 Chevrolet       12
##  4 Volkswagen      11
##  5 Other           11
##  6 Ford            10
##  7 Audi             9
##  8 Hyundai          8
##  9 Subaru           8
## 10 Nissan           7
## 11 Jeep             6

检查因子水平:

levels(mpg_sum$manufacturer)
##  [1] "Other"      "Jeep"       "Nissan"     "Subaru"     "Hyundai"   
##  [6] "Audi"       "Ford"       "Volkswagen" "Chevrolet"  "Toyota"    
## [11] "Dodge"

使用ggplot2画图

首先画一个基础的条形图:

ggplot(mpg_sum, aes(x = n, y = manufacturer)) +
  geom_col(fill = "grey70") +
  theme_minimal()

计算百分比

可以先计算好然后再画图,也可以在画图中计算,这里选择第一种方法,稳妥方便调整。

变为百分比形式可以使用sprintf或者使用scales

mpg_sum %>% 
  mutate(perc = paste0(sprintf("%4.1f", n / sum(n) * 100), "%"))
## # A tibble: 11 x 3
##    manufacturer     n perc   
##    <fct>        <int> <chr>  
##  1 Dodge           21 "17.9%"
##  2 Toyota          14 "12.0%"
##  3 Chevrolet       12 "10.3%"
##  4 Volkswagen      11 " 9.4%"
##  5 Other           11 " 9.4%"
##  6 Ford            10 " 8.5%"
##  7 Audi             9 " 7.7%"
##  8 Hyundai          8 " 6.8%"
##  9 Subaru           8 " 6.8%"
## 10 Nissan           7 " 6.0%"
## 11 Jeep             6 " 5.1%"
mpg_sum <- mpg_sum %>% 
  dplyr::mutate(perc = scales::percent(n / sum(n), accuracy = .1, trim = FALSE))

mpg_sum
## # A tibble: 11 x 3
##    manufacturer     n perc   
##    <fct>        <int> <chr>  
##  1 Dodge           21 "17.9%"
##  2 Toyota          14 "12.0%"
##  3 Chevrolet       12 "10.3%"
##  4 Volkswagen      11 " 9.4%"
##  5 Other           11 " 9.4%"
##  6 Ford            10 " 8.5%"
##  7 Audi             9 " 7.7%"
##  8 Hyundai          8 " 6.8%"
##  9 Subaru           8 " 6.8%"
## 10 Nissan           7 " 6.0%"
## 11 Jeep             6 " 5.1%"

使用geom_text添加标签:

ggplot(mpg_sum, aes(n, manufacturer)) +
  geom_col(fill = "grey70") +
  geom_text(aes(label = perc)) +
  theme_minimal()

假如你想对某些标签添加更多描述,可以使用ifelse

mpg_sum <- mpg_sum %>% 
  mutate(
    perc = scales::percent(n / sum(n), accuracy = .1, trim = F),
    perc = ifelse(row_number() == 1, paste(perc, "of all car models"), perc)
  )


ggplot(mpg_sum, aes(n, manufacturer)) +
  geom_col(fill = "grey70") +
  geom_text(aes(label = perc)) +
  scale_x_continuous(limits = c(NA,25)) +
  theme_minimal()

调整标签位置

geom_text有4个参数可以调节位置:

  • hjust/vjust
  • nudge_x/nudge_y

把标签放在条形的里面,可以设置hjust = 1,并设置nudge_x = -0.5增加边距:

ggplot(mpg_sum, aes(n, manufacturer)) +
  geom_col(fill = "grey70") +
  geom_text(aes(label = perc), hjust = 1, nudge_x = -0.5) +
  theme_minimal()

给条形添加不同的颜色

有非常多的方法可以给条形图上不同的颜色,最直观的一种是直接创建一个颜色变量,画图时直接使用即可:

pal <- c(
  "gray85",
  rep("gray70", length(mpg_sum$manufacturer) - 4), 
  "coral2""mediumpurple1""goldenrod1"
)

接下来只要把这个变量传递给scale_fill_manual()即可:

ggplot(mpg_sum, aes(n, manufacturer, fill = manufacturer))+
  geom_col()+
  geom_text(aes(label = perc), hjust = 1, nudge_x = -0.5)+
  scale_fill_manual(values = pal, guide = "none")+
  theme_minimal()

或者可以在原数据的基础上新建一列颜色变量,然后使用scale_fill_identity()

mpg_sum <- mpg_sum %>% 
  mutate(
    color = case_when(
      row_number() == 1 ~ "goldenrod1",
      row_number() == 2 ~ "mediumpurple1",
      row_number() == 3 ~ "coral2",
      TRUE ~ "grey70"
    )
  )

ggplot(mpg_sum, aes(n, manufacturer, fill = color))+
  geom_col()+
  geom_text(aes(label = perc), hjust = 1, nudge_x = -0.5)+
  scale_fill_identity(guide = "none")+
  theme_minimal()

这种方法更简单直接,根据你的变量进行上色,且不容易出错。

调整坐标轴刻度标签的颜色

如果想要纵坐标的标签颜色和条形的颜色一样,也可以采用同样的方法。

label_pal <- c(rep("black"8),"coral2""mediumpurple1""goldenrod1")

ggplot(mpg_sum, aes(n, manufacturer, fill = color))+
  geom_col()+
  geom_text(aes(label = perc), hjust = 1, nudge_x = -0.5)+
  scale_fill_identity(guide = "none")+
  theme_minimal()+
  theme(axis.text.y = element_text(size = 14, hjust = 1, family = "Fira Sans"
                                   color = label_pal))

调整图形外观

调整字体大小和外观,调整网格线,调整坐标轴标签距离坐标轴的距离,修改坐标轴标题等。

如果想要在标题内使用不同的颜色,那就要通过ggtext包或者mdthemes包来实现了。

library(ggtext)

ggplot(mpg_sum, aes(n, manufacturer, fill = color))+
  geom_col()+
  geom_text(aes(label = perc), hjust =1, nudge_x = -0.5
            size = 4, fontface = "bold", family = "Fira Sans")+
  scale_x_continuous(expand = c(0.01,0.01))+
  scale_fill_identity(guide = "none")+
  theme_void()+
  labs(title = "A ggplot <span style='color:#D20F26'>Bar plot</span> with <span style='color:#D20F26'>differnt colors</span>")+
  theme(axis.text.y = element_text(size = 14, hjust = 1, family = "Fira Sans"
                                   color = label_pal),
        plot.title = element_markdown(hjust = 0.5, vjust = 0.5, size = 20, margin = margin(t = 1, b = 12)),
        plot.margin = margin(rep(154)))
ggsave("数据标签.png",dpi = 300,width = 7,height = 4)



以上就是今天的内容,希望对你有帮助哦!欢迎点赞、在看、关注、转发

欢迎在评论区留言或直接添加我的微信!




欢迎关注我的公众号:医学和生信笔记

医学和生信笔记 公众号主要分享:1.医学小知识、肛肠科小知识;2.R语言和Python相关的数据分析、可视化、机器学习等;3.生物信息学学习资料和自己的学习笔记!


往期精彩内容:

让你的ggplot2支持markdown语法


让你的ggplot2主题支持markdown和css


让OneNote支持Markdown:oneMark,重新定义OneNote


R语言缺失值插补之simputation包


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存