如何使用ggplot2绘制漂亮的统计图形(Part1)

如何使用ggplot2绘制漂亮的统计图形(Part1)

  • 本次翻译国外的一篇 优质ggplot2教程 ,翻译过程中修改了原文的bug、去掉了废话;
  • 超级长, 分成多篇 发出,欢迎指出错误。



本文目录

1、ggplot2简介
2、本教程数据集
3、 快速开始使用ggplot2
3.1、定义画板
3.2、添加几何对象 (geom)
3.3、个性化几何对象
3.4、修改ggplot2默认主题
4、坐标轴 (Axes)设置
4.1、添加坐标轴标题(axis.title)
4.2、坐标轴标题上标
4.3、坐标轴与轴标题(axis.title)间距
4.4、修改坐标轴标题(axis.title)外观
4.5、修改轴刻度标签(axis.text)外观
4.6、轴刻度标签(axis.text)角度设置
4.7、刻度标签(axis.text) 、刻度值(axis.ticks)关闭
4.8、关闭轴标题
4.9、设置轴刻度范围
4.10、强制ggplot2从(0,0)开始绘图
4.11、使x轴和y轴的刻度比例保持一致 
4.12、通过函数设置刻度标签(axis.text)
5、标题 (Titles)设置 
5.1、添加标题
5.2、标题加粗
5.3、标题位置
5.4、为标题指定字体
5.5、修改多行文本之间的间距
6、图例设置
6.1、图例关闭
6.2、删除图例标题
6.3、设置图例位置
6.4、设置图例方向 
6.5、设置图例标题字体外观
6.6、设置图例标题
6.7、设置图例关键字顺序
6.8、自定义图例关键字
6.9、设置图例框的填充色
6.10、设置图例符号大小
6.11、图例叠加 
6.12、手动添加图例
6.13、使用更多图例风格

1、ggplot2简介

ggplot2是基于 图层图形语法 (the Grammar of Graphics),绘图时会反复提到以下几个概念,

  • 数据集 (data): 绘图数据集。
  • 几何对象 (geom): 数据展示的形状,譬如折线图 (geom_line)、柱状图 (geom_bar)等,是以geom_打头的函数。
  • 图像属性 (aes): geom对象的颜色、大小、形状等,是以aes_打头的函数。
  • 标度 (scale):将数据取值映射到图形空间,使用颜色,形状,大小表示不同取值,使用图例,网格线展示标度,是以scale_打头的函数。
  • 统计变换 (stat): 对数据的汇总,是以stat_打头的函数。
  • 坐标系 (coord): 描述数据如何映射到图形,同时包含坐标轴和网格线axes, gridlines,是以coord_开头的函数。
  • 分面(facet): 将数据拆分为小子集,对各子集作图并联合展示,也成条件作图或网格图,是以facet_打头的函数。
  • 绘图主题 (theme): 主题涉及图形更细的方面,如背景色,字体大小等,是以theme_打头的函数。

ggplot2详细介绍 《ggplot2:数据分析与图形艺术》最新版中文笔记


2、本教程数据集

library(readr)
chic <- read_csv("https://raw.githubusercontent.com/z3tt/ggplot-courses/master/data/chicago-nmmaps.csv", show_col_types = FALSE)
head(chic)

3、 快速开始使用ggplot2

两种方法可导入ggplot2,

#方法1
library(ggplot2)
library(tidyverse) #通过tidyverse导入ggplot2,tidyverse包含了ggplot2、dplyr、tidyr等R包

3.1、定义画板

指定数据集 (data),图像属性 (aes),

g <- ggplot(data=chic, aes(x = date, y = temp))

3.2、添加几何对象 (geom)

g + geom_point() #添加散点
g + geom_line()#添加折线
g + geom_line() + geom_point()#联合使用折线、散点

3.3、个性化几何对象

#修改散点的颜色、形状、大小
g + geom_point(color = "firebrick", shape = "diamond", size = 2)


每个几何对象的属性是独立的,可分别设置

g + geom_point(color = "firebrick", shape = "diamond", size = 2) + #修改散点的颜色、形状、大小
    geom_line(color = "firebrick", linetype = "dotted", size = .3) #修改折线的颜色、形状、大小

3.4、修改ggplot2默认主题

theme_set(theme_bw()) #修改ggplot2默认主题
g + geom_point(color = "firebrick")

4、坐标轴 (Axes)设置

4.1、添加坐标轴标题(axis.title)

方法1 、使用使用labs()函数,

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") #labs分别为x,y轴添加标题

方法2 、使用_ xlab和``ylab()函数 _

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  xlab("Year") +
  ylab("Temperature (°F)")

4.2、坐标轴标题上标

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = expression(paste("Temperature (", degree ~ F, ")"^"(Hey, why should we use metric units?!)")))

4.3、坐标轴与轴标题(axis.title)间距

方法1 、通过theme()函数、axis.title、element_text、vjust

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title.x = element_text(vjust = 0, size = 10), #vjust设置间距、size标题大小
        axis.title.y = element_text(vjust = 3, size = 13))


方法2 、通过theme()函数、axis.title、element_text、marginmargin中包含四个参数margin(t, r, b, l) ,t、b可调节x轴标题上下移动,r、l可调节y轴标题左右移动,

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title.x = element_text(margin = margin(t = 10), size = 15),
        axis.title.y = element_text(margin = margin(r = 10), size = 15))

4.4、修改坐标轴标题(axis.title)外观

通过theme()函数、axis.title、element_text、修改标题的大小,颜色和字体

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title = element_text(size = 15, color = "firebrick",
                                  face = "italic"))#同时修改修改坐标轴标题大小、颜色、字体
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  #分别修改x、y轴标题颜色、大小 
  theme(axis.title.x = element_text(color = "sienna", size = 15),
        axis.title.y = element_text(color = "orangered", size = 15))


axis.title、axis.title.x、axis.title.y混用:同时修改部分共同特性,个性化部分特性,

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title = element_text(color = "sienna", size = 15),#同时修改共性
        axis.title.y = element_text(color = "orangered", size = 15))#个性化y轴特性

4.5、修改轴刻度标签(axis.text)外观

通过theme()函数、axis.text、element_text修改轴刻度标签颜色、字体、大小等

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.text = element_text(color = "dodgerblue", size = 12),#同时修改x、y轴标签颜色、大小
        axis.text.x = element_text(face = "italic"))#单独修改x轴标签字体

4.6、轴刻度标签(axis.text)角度设置

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  #angle设置
  theme(axis.text.x = element_text(angle = 50, vjust = 1, hjust = 1, size = 12))

4.7、刻度标签(axis.text) 、刻度值(axis.ticks)关闭

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.ticks.y = element_blank(),#element_blank关闭刻度值
        axis.text.y = element_blank())#element_blank关闭刻度标签

4.8、关闭轴标题

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = NULL, y = "") #NULL同时去掉x轴标题及其空间,""将y轴标题去掉保留空间

4.9、设置轴刻度范围

#方法1
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  ylim(c(0, 50))#y轴刻度范围设置为0~50
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  scale_y_continuous(limits = c(0, 50))

4.10、强制ggplot2从(0,0)开始绘图

ggplot(chic_high, aes(x = temp, y = o3)) +
  geom_point(color = "darkcyan") +
  labs(x = "Temperature higher than 25°F",
       y = "Ozone higher than 20 ppb") +
  expand_limits(x = 0, y = 0) +
  scale_x_continuous(expand = c(0, 0)) +
  scale_y_continuous(expand = c(0, 0)) +
  coord_cartesian(clip = "off") # clip = "off" 允许在面板区域之外绘制,保留c(0,0)处的刻度

4.11、使x轴和y轴的刻度比例保持一致

ggplot(chic, aes(x = temp, y = temp + rnorm(nrow(chic), sd = 20))) +
  geom_point(color = "sienna") +
  labs(x = "Temperature (°F)", y = "Temperature (°F) + random noise") +
  xlim(c(0, 100)) + ylim(c(0, 150)) +
  coord_fixed(ratio = 1)

4.12、通过函数设置刻度标签(axis.text)

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = NULL) +
  scale_y_continuous(label = function(x) {return(paste(x, "Degrees Fahrenheit"))})

5、标题 (Titles)设置

5.1、添加标题

方法1 、通过ggtitle()函数

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  ggtitle("Temperatures in Chicago")# ggtitle添加标题


方法2 、通过labs()添加各类标题

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)",
       title = "Temperatures in Chicago", #添加主标题
       subtitle = "Seasonal pattern of daily temperatures from 1997 to 2001", #添加次标题
       caption = "Data: NMMAPS",#下备注
       tag = "Fig. 1") #上备注

5.2、标题加粗

通过theme()中的plot.title设置,其它如plot.subtitle plot.caption plot.caption legend.title legend.text ,、 axis.title、 axis.text设置类似。

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)",
       title = "Temperatures in Chicago") +
  theme(plot.title = element_text(face = "bold",#加粗
                                  margin = margin(10, 0, 10, 0),#标题上下左右位置
                                  size = 14))

5.3、标题位置

方法1 、hjust,vjust设置标题与坐标轴对齐

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = NULL,
       title = "Temperatures in Chicago",
       caption = "Data: NMMAPS") +
  theme(plot.title = element_text(hjust = 1, size = 16, face = "bold.italic"))
#hjust调整水品位置,vjust垂直位置


方法2 、使用 plot.title.position plot.caption.position ,此时,标题或备注与刻度标签对齐

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = NULL,
       title = "Temperatures in Chicago",
       caption = "Data: NMMAPS") + theme(
          plot.title.position = "plot", #标题对齐
          plot.caption.position = "plot")#备注对齐

5.4、为标题指定字体

library(showtext)
showtext.auto(enable=TRUE)
font_path = "/System/Library/Fonts/Supplemental/Songti.ttc" #linux下可使用fc-list列出可用字体
#字体加载到R中
font_name = tools::file_path_sans_ext(basename(font_path))
font_add(font_name, font_path)
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)",
       title = "Temperatures in Chicago",
       subtitle = "Daily temperatures in °F from 1997 to 2001") +
  theme(plot.title = element_text(family = font_name, hjust = .5, size = 15),#使用字体
        plot.subtitle = element_text(family = font_name, hjust = .5, size = 5))

5.5、修改多行文本之间的间距

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  ggtitle("Temperatures in Chicago\nfrom 1997 to 2001") +
  theme(plot.title = element_text(lineheight = .8, size = 16))#使用lineheight

6、图例设置

6.1、图例关闭

默认图利是开启的

ggplot(chic,
       aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)")
ggplot(chic,
       aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.position = "none") #关闭图例

使用guides(color = "none") 或者 scale_color_discrete(guide = "none") 删除部分图例,例如,删除颜色图例,保留形状图例

ggplot(chic,
       aes(x = date, y = temp,
           color = season, shape = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  guides(color = "none")#删除颜色图例

6.2、删除图例标题

#方法1
ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.title = element_blank())#element_blank()
ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  labs(color = NULL)
ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  scale_color_discrete(name = NULL)

6.3、设置图例位置

方法1 、legend.position控制图例位置于上下左右

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.position = "top")#“top”, “right”,“bottom”和“left”可选


方法2 、让图例放置于图中任意位置为legend.position传入位置坐标c(x,y)即可,其中x, y范围为0~1,

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)",
       color = NULL) +
  theme(legend.position = c(.85, .65),#c(.85, .65)0.85对应x轴方向位置,0.65对应y轴方向位置
        legend.background = element_rect(fill = "transparent"))

6.4、设置图例方向

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.position = c(.5, .97),
        legend.background = element_rect(fill = "transparent")) +
  guides(color = guide_legend(direction = "horizontal"))#默认为垂直方向,此处修改为水平方向

6.5、设置图例标题字体外观

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.title = element_text(family = "Playfair", #设置图例标题字体
                                    color = "chocolate", #设置图例标题颜色
                                    size = 14, face = "bold"))#设置图例标题大小、是否加粗

6.6、设置图例标题

三种方法可实现

#方法1、labs
ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)",
       color = "Seasons\nindicated\nby colors:") + #图例标题分行显示
  theme(legend.title = element_text(family = "Playfair",
                                    color = "chocolate",
                                    size = 14, face = "bold"))
#方法2、scale_color_discrete(name = "title")
ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.title = element_text(family = "Playfair",
                                    color = "chocolate",
                                    size = 14, face = "bold")) +
  scale_color_discrete(name = "Seasons\nindicated\nby colors:")
#方法3、guides(color = guide_legend("title"))
ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.title = element_text(family = "Playfair",
                                    color = "chocolate",
                                    size = 14, face = "bold")) +
  guides(color = guide_legend("Seasons\nindicated\nby colors:"))

6.7、设置图例关键字顺序

chic$season <- factor(chic$season, levels = c("Winter", "Spring", "Summer", "Autumn")) #定义顺序
ggplot(chic, aes(x = date, y = temp, color = season)) + 
geom_point() + labs(x = "Year", y = "Temperature (°F)")

6.8、自定义图例关键字

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  scale_color_discrete(
    name = "Seasons:", 
    labels = c("Mar—May", "Jun—Aug", "Sep—Nov", "Dec—Feb") #自定义图例关键字
  theme(legend.title = element_text(
    family = "Playfair", color = "chocolate", size = 14, face = 2

6.9、设置图例框的填充色

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.key = element_rect(fill = "darkgoldenrod1"),#设置填充色,fill = NA 或者 fill = "transparent"关闭填充
        legend.title = element_text(family = "Playfair",
                                    color = "chocolate",
                                    size = 14, face = 2)) +
  scale_color_discrete("Seasons:")

6.10、设置图例符号大小

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(legend.key = element_rect(fill = NA),
        legend.title = element_text(color = "chocolate",
                                    size = 14, face = 2)) +
  scale_color_discrete("Seasons:") +
  guides(color = guide_legend(override.aes = list(size = 6)))#通过guides实现

6.11、图例叠加

将多个geom对象图例叠加,如geom_point和geom_rug叠加

ggplot(chic, aes(x = date, y = temp, color = season)) +
  geom_point() +#geom_point图层
  labs(x = "Year", y = "Temperature (°F)") +
  geom_rug()#geom_rug图层,geom_rug(show.legend = FALSE)可关闭rug图例

6.12、手动添加图例

ggplot(chic, aes(x = date, y = o3)) +
  geom_line(aes(color = "line")) +
  geom_point(aes(color = "points")) +
  labs(x = "Year", y = "Ozone") +
  scale_color_manual(name = NULL,
                     guide = "legend",
                     values = c("points" = "darkorange2",
                                "line" = "gray")) + #使用 scale_color_manual() 函数
  guides(color = guide_legend(override.aes = list(linetype = c(1, 0),
                                                  shape = c(NA, 16))))

6.13、使用更多图例风格

连续变量 使用 guide_colorbar() 或者 guide_colourbar()

ggplot(chic,
       aes(x = date, y = temp, color = temp)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)", color = "Temperature (°F)") +
  guides(color = guide_colorbar()) #guide_colorbar()


连续变量强制 使用guide_legend()展示离散的颜色

ggplot(chic,
       aes(x = date, y = temp, color = temp)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)", color = "Temperature (°F)") +
  guides(color = guide_legend())#guide_legend()


guide_bins()分区间

ggplot(chic,
       aes(x = date, y = temp, color = temp)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)", color = "Temperature (°F)") +
  guides(color = guide_bins())#guide_bins()