什么是直方图?
直方图是一种展示连续(数值)变量频率分布的可视化。它能让我们看到数据中观测值在连续变量所覆盖范围内各区间的计数。
开始使用 ggplot2
要跟随本教程,您需要安装 R 以及以下包:ggplot2、readr 和 dplyr。下一节的代码会在尚未安装的情况下进行安装。
安装包
我们首先需要使用 library 函数导入 ggplot2 库。这将引入 ggplot2 中所有可用的内置函数。如果您尚未安装 ggplot2,需要运行 install.packages() 进行安装。对于可读取 CSV 文件的 readr 库和便于处理数据的 dplyr,我们也将执行相同操作。
install.packages("ggplot2")
install.packages("readr")
install.packages("dplyr")
library(ggplot2)
library(readr)
library(dplyr)
加载数据集
本教程将使用这个房屋数据集,其中包含不同房源的详细信息,包括房屋面积、房间数量、价格和位置信息。
我们可以使用 read_csv() 函数读取数据。可直接从 URL 读取,或将 CSV 文件下载到本地目录后再从本地读取。read_csv() 的第一个参数是数据位置,col_select 参数可让我们选择感兴趣的列。
home_data <- read_csv(
"https://raw.githubusercontent.com/rashida048/Datasets/master/home_data.csv",
col_select = c(price, condition)
)
随后我们可以使用 head() 函数查看前几行数据:
head(home_data)

如何用 ggplot2 绘制直方图
现在我们来创建直方图。无论在 ggplot2 中绘制何种图形,我们总是从 ggplot() 函数开始,它会创建一个用于叠加图形元素的画布。它接收两个参数。
-
第一个参数是数据框。这里我们使用
home_data。 -
第二个参数是数据框列到图形美学属性的映射。该映射需要调用
aes()函数。这里我们将 price 列映射到 x 轴。
到目前为止,代码如下:
ggplot(data = home_data, aes(x = price))
这段代码本身不会绘制出有用的内容。要使其成为直方图,我们需添加直方图几何图层 geom_histogram()。
ggplot(data = home_data, aes(x = price)) +
geom_histogram()

使用 geom_vline() 为直方图添加描述性统计
我们可以使用 geom_vline() 函数为图表添加描述性统计信息。它会在图中添加一条垂直线。
首先,使用 dplyr 的 summarize() 计算一项描述性统计,这里以均价为例。
price_stats <- home_data |>
summarize(mean_price = mean(price))
price_stats
# A tibble: 1 × 1
mean_price
<dbl>
1 540088.
该函数接收 xintercept 参数,以及可选的 color 与 linewidth 参数分别自定义线条颜色和粗细。我们将像上一节一样用加号添加一条均值线。
ggplot(home_data, aes(x = price)) +
geom_histogram() +
geom_vline(aes(xintercept = mean_price), price_stats, color = "red", linewidth = 2)
请注意,在 geom_ 函数中,mapping 与 data 参数的顺序与 ggplot() 相比是对调的。

绘制定概率密度而非计数
要在直方图上添加概率密度曲线,我们首先将 y 轴改为密度刻度。在 aes() 函数中,将 y 设为 after_stat(density)。
随后使用 geom_density() 为图表添加密度图层。这里我们将 color 设为绿色,linewidth 设为 2。
ggplot(home_data, aes(x = price, y = after_stat(density))) +
geom_histogram() +
geom_vline(aes(xintercept = mean_price), price_stats, color = "red", linewidth = 2) +
geom_density(color = "green", linewidth = 2)

请注意 y 轴的数值已经改变。
再观察一下,每一层都遵循相同的模式:一个 + 号、一个函数调用,以及可选参数。您可以自由添加 geom_ 函数、统计和主题,而无需为每种组合重新学习语法。
使用 bins 更新分箱
我们可以用 bin 属性更新 ggplot2 直方图的分箱。将 bin 属性设置为希望在图上显示的箱数,可帮助我们在直方图中查看更多或更少的粒度。
ggplot(data = home_data, aes(x = price)) +
geom_histogram(bins = 100)

我们也可以使用 geom_histogram() 的 binwidth 属性手动设置箱宽。
ggplot(data = home_data, aes(x = price)) +
geom_histogram(binwidth = 50000)

最后,您可以使用 center 或 boundary 属性对齐箱边界。如果希望箱的边界落在特定的倍数上,可以使用这些属性(一次只能使用一个)。例如要确保箱边界落在整数上,将该属性设为 1。
ggplot(data = home_data, aes(x = price)) +
geom_histogram(boundary = 1)

自定义直方图颜色
本节我们将更改直方图的颜色。可使用 color 属性自定义每个柱形的边框颜色,使用 geom_histogram() 的 fill 属性更改柱形填充颜色。我们将以蓝色填充柱形,并将边框颜色改为白色。
ggplot(data = home_data, aes(x = price)) +
geom_histogram(color = "white", fill = "blue")

按分组自定义 ggplot2 直方图颜色
您可以自定义直方图柱形的颜色。
在 aes() 内更改 fill 美学映射,可根据数据集中某个变量的取值改变柱形的填充颜色。该变量应为分类变量(因子)而非整数,因此我们可以用 factor() 函数进行转换。本例中,我们查看 condition 变量,该值范围为 1(状况差)到 5(状况佳)。
home_data <- home_data |>
mutate(condition = factor(condition))
ggplot(data = home_data, aes(x = price, fill = condition)) +
geom_histogram()

使用 abs() 添加标签和标题
接下来,我们使用 labs() 函数为图表添加标题和标签。将 x、y 和 title 属性设置为所需文本。
ggplot(data = home_data, aes(x = price)) +
geom_histogram() +
labs(x ='Price (USD)', y='Number of Listings', title = 'Housing Price Distributions')

使用 xlim() 设置 x 轴范围
我们可以使用 xlim() 函数设置图表的 x 轴范围,以便聚焦于感兴趣的数据。例如,有时聚焦分布的中心部分会比我们当前看到的长尾更有帮助。
也可以更改 y 轴范围(使用 ylim()),但对直方图来说,这通常不太有用,因为自动计算的取值几乎总是理想的。
我们将把价格范围缩放到 0 至 200 万美元。
ggplot(home_data, aes(x = price)) +
geom_histogram(bins = 100) +
xlim(0, 2000000)

更改图例位置
如果我们希望移动图例位置,例如在用不同颜色展示 condition 时,可以使用 theme() 函数与 legend.position 属性。legend.position 的取值可为 “bottom”、“top”、“left” 或 “right”。您也可以通过传入 c(x, y) 坐标来指定图例位置。
ggplot(home_data, aes(x = price, fill = condition)) +
geom_histogram() +
theme(legend.position = "bottom")
在 ggplot2 中使用分面
最后,我们可以通过分面在不同的小图中展示各分组数据。这会针对每个类别拆分出若干子图。可使用 facet_grid() 实现。下面我们按不同的 condition 值可视化价格分布。
ggplot(home_data, aes(x = price)) +
geom_histogram() + facet_grid(vars(condition))
有关分面的更多内容,请参阅R 中的 ggplot 分面教程。

总结
在 ggplot2 中创建直方图的流程是:用 ggplot() 搭建基础,传入数据框与 aes() 映射,然后添加 geom_histogram()。在此基础上,叠加自定义层:用 labs() 设置坐标轴标题,xlim() 缩放 x 轴范围,theme() 重定位图例或调整视觉样式。
ggplot2 在 R 数据可视化技能路径中有深入讲解,从使用 ggplot2 入门数据可视化开始。您还可以在R 的 Tidyverse 基础技能路径中学习将 ggplot2 与其他 tidyverse 工具结合使用。
若想了解直方图之外的更多 ggplot2 图形类型,请参阅我们的ggplot2 图形教程,并下载一份ggplot2 备忘单以便随时查阅。
数据科学作者|Wayfair 高级技术营销分析师|宾夕法尼亚大学数据科学硕士(MSE)
直方图能让您一眼看出数据分布的形状。在本教程中,我将带您使用 ggplot2(R 中最常用的绘图库,也是 tidyverse 生态的核心组成部分)来创建和自定义直方图。ggplot2 遵循“图形语法”,通过分层叠加图形元素来构建复杂可视化。若想使用 base R 的方法,请参阅我们的base R 直方图教程。
要点速览
在
ggplot()调用中使用geom_histogram()绘制直方图在
geom_histogram()中用bins控制箱数,或用binwidth控制箱宽使用
color(边框)和fill(填充)参数自定义柱形颜色将
y = after_stat(density)设定后,使用geom_density()叠加密度曲线在
aes()中用fill = 变量按类别着色,或使用facet_grid()分面显示