用 R 与 ggplot2 可视化数据分布:直方图与密度图实战(Data-Science-For-Beginners 第 10 课)
发布时间:2026/9/13 10:27:03来源:尧图网络
用 R 与 ggplot2 可视化数据分布直方图与密度图实战Data-Science-For-Beginners 第 10 课【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners本课基于 Data-Science-For-Beginners 课程第 4 部分「数据可视化」的第 10 讲使用明尼苏达州鸟类数据集data/birds.csv讲解如何用 R 语言与ggplot2分析单变量与多变量的数据分布。你将掌握三类核心图表直方图Histogram、二维直方图2D Histogram与密度图Density Plot并学会对文本型分类变量进行编码后参与分布分析最终能够独立用这些手段从任意数据集里提取「数据如何沿坐标轴展开」的洞察。课程上下文与数据准备在上一课 09-visualization-quantities 用 ggplot2 可视化数量 中我们已经通过折线图与散点图发现数据集中存在异常值——白头海雕Bald Eagle与草原隼Prairie Falcon的最大翼展被多录入了一个 0并据此过滤掉了这些错误数据。本课在此基础上进一步深入不再只关心某个数值本身而是关心整个数值沿坐标轴的展开形态即数据的分布distribution。在 R 控制台中依次执行以下代码加载ggplot2、读取鸟类数据、并沿用上一课的方式去除离群值。library(ggplot2) birds - read.csv(../../data/birds.csv, fileEncodingUTF-8-BOM) birds_filtered - subset(birds, MaxWingspan 500) head(birds_filtered)说明data/birds.csv位于仓库根目录的 data/ 文件夹下第一行带有 UTF-8 BOM 标记因此读取时必须指定fileEncodingUTF-8-BOM否则第一列列名会出现乱码。数据集共包含 442 条鸟类记录含表头共 443 行涵盖名称、学名、分类目/科/属、保护状态以及体长、体重、翼展的最小/最大值等 13 个字段。过滤后前 5 行数据如下NameScientificNameCategoryOrderFamilyGenusConservationStatusMinLengthMaxLengthMinBodyMassMaxBodyMassMinWingspanMaxWingspan0Black-bellied whistling-duckDendrocygna autumnalisDucks/Geese/WaterfowlAnseriformesAnatidaeDendrocygnaLC4756652102076941Fulvous whistling-duckDendrocygna bicolorDucks/Geese/WaterfowlAnseriformesAnatidaeDendrocygnaLC4553712105085932Snow gooseAnser caerulescensDucks/Geese/WaterfowlAnseriformesAnatidaeAnserLC6479205040501351653Rosss gooseAnser rossiiDucks/Geese/WaterfowlAnseriformesAnatidaeAnserLC57.364106615671131164Greater white-fronted gooseAnser albifronsDucks/Geese/WaterfowlAnseriformesAnatidaeAnserLC648119303310130165用散点图快速预览分布为什么它不够用在正式使用直方图之前可以先用上一课掌握的散点图快速「扫一眼」数据沿坐标轴的展开情况。例如按鸟的目Order查看最大体长MaxLength的分布ggplot(databirds_filtered, aes(xOrder, yMaxLength, group1)) geom_point() ggtitle(Max Length per order) coord_flip()这张图能够给出每个鸟目内体长大致的散布范围但它存在明显局限点的密度与数值区间无法精确对应我们只能凭直觉判断「哪个目的鸟更长」却很难说出「长度集中在什么区间、有多少只」。因此它适合作为探索的起点而不是展示真实分布的最佳手段——这个任务通常交给直方图Histogram来完成。直方图基础bins 参数如何决定分布粒度ggplot2提供了非常完善的直方图可视化能力。直方图在形式上类似条形图但条形的高低反映的是数据在某个数值区间内的频数把数值轴划分成若干连续的区间bin统计落入每个区间的数据点个数柱高即频数。构建直方图的先决条件是数值型数据。下面把MaxBodyMass最大体重的分布画出来通过bins10将整个数值范围划分为 10 个区间ggplot(data birds_filtered, aes(x MaxBodyMass)) geom_histogram(bins10) ylab(Frequency)可以看到数据集中 400 多只鸟的 Max Body Mass 绝大多数集中在 2000 以下只有极少数个体达到更高体重——这是一个典型的右偏分布主体集中在低体重区间长尾拖向高体重一侧。这正是直方图的价值它把「多数 / 少数」的对比用柱高直观量化出来。想要观察更细的粒度把bins参数提高到 30ggplot(data birds_filtered, aes(x MaxBodyMass)) geom_histogram(bins30) ylab(Frequency)bins是直方图最核心的调参对象它直接决定柱子的疏密程度。bins越小柱子越粗分布形态越概略bins越大柱子越细能暴露出更多局部细节但也可能因过度细分而显得嘈杂。实际使用中建议像这里一样从bins10起步再逐步加大到 30 甚至更多观察哪些区间开始出现次峰或空档。过滤数据消除左偏聚焦目标区间上面的直方图整体向左低值方向偏斜长尾把大部分细节挤压在了一侧。为了让分布形态更清晰可以先用subset()裁剪数据范围只保留体重在 1 到 60 之间的鸟类再绘制 30 个 bin 的直方图birds_filtered_1 - subset(birds_filtered, MaxBodyMass 1 MaxBodyMass 60) ggplot(data birds_filtered_1, aes(x MaxBodyMass)) geom_histogram(bins30) ylab(Frequency)此时分布不再严重偏斜柱形的起伏能够更细致地呈现。这个「先过滤、再分组」的模式在实际分析中非常常见分布分析的第一步往往是确定你真正关心的数值区间用subset()这类筛选手段排除干扰后再画图。✅ 试试更换过滤条件与其他字段如 MaxLength、MinWingspan。想看全量分布时去掉体重过滤条件即可必要时为柱子添加标签。二维直方图同时观察两个分布及其收敛关系直方图默认只处理一个数值变量但ggplot2提供了内置的二维直方图geom_bin2d()它把平面划分成网格状的小格子用格子的明暗颜色亮度表示该格子内数据点的多少。下面比较MaxBodyMass与MaxLength两个分布的关系ggplot(databirds_filtered_1, aes(xMaxBodyMass, yMaxLength)) geom_bin2d() scale_fill_continuous(type viridis)从结果看体重与体长之间存在可预期的正相关关系并且沿某个轴线存在一个特别强的收敛点——即大量鸟类同时落在某个体重与体长的交汇区间。scale_fill_continuous(type viridis)使用了色觉友好且明暗梯度清晰的 viridis 色带颜色越亮黄绿色表示频数越高越暗紫蓝色表示频数越低。这种二维方式非常适合在一张图里回答「两个分布之间是否存在关联、关联集中在何处」。文本数据的分布保护状态编码与叠加直方图直方图默认面向数值数据。如果变量是文本型分类数据该怎么办本数据集中恰好包含这类信息鸟的保护状态ConservationStatus。这些状态缩写来自 IUCN 红色名录分类体系CR: Critically Endangered极度濒危EN: Endangered濒危EX: Extinct灭绝LC: Least Concern无危NT: Near Threatened近危VU: Vulnerable易危要在直方图中使用文本型变量需要先做一次转换transform把每个分类编码为有序的数字型代理值。下面将birds_filtered_1中的保护状态依次映射为x1~x6再以MinWingspan为数值轴、保护状态为填充色绘制叠加直方图birds_filtered_1$ConservationStatus[birds_filtered_1$ConservationStatus EX] - x1 birds_filtered_1$ConservationStatus[birds_filtered_1$ConservationStatus CR] - x2 birds_filtered_1$ConservationStatus[birds_filtered_1$ConservationStatus EN] - x3 birds_filtered_1$ConservationStatus[birds_filtered_1$ConservationStatus NT] - x4 birds_filtered_1$ConservationStatus[birds_filtered_1$ConservationStatus VU] - x5 birds_filtered_1$ConservationStatus[birds_filtered_1$ConservationStatus LC] - x6 ggplot(databirds_filtered_1, aes(x MinWingspan, fill ConservationStatus)) geom_histogram(position identity, alpha 0.4, bins 20) scale_fill_manual(nameConservation Status, valuesc(red,green,blue,pink), labelsc(Endangered,Near Threathened,Vulnerable,Least Concern))这段代码的关键点有三处position identity让不同保护状态的柱子原位叠加而不是堆叠起来配合半透明设置alpha 0.4才能看清各分类的重叠关系bins 20数值轴MinWingspan划分成 20 个区间scale_fill_manual()手工指定图例名称、填充色与标签文本把x1~x6还原为可读的保护状态名称。从图中可以观察到无危Least Concern物种数量最多且集中在较低翼展区间濒危、近危、易危物种数量较少整体上最小翼展与保护状态之间没有呈现强相关性。这种「先编码、再叠加、最后手工校准图例」的方法可以推广到数据集中任意分类字段——试试按 Category、Genus 或 Order 重复这个过程看看能否发现其他相关性。密度图让分布曲线平滑起来细看前面的直方图会发现柱子之间存在明显的「阶梯感」stepped曲线并不平滑。如果想要一条平滑的分布曲线可以使用密度图density plot。密度图通过核密度估计把频数分布拟合成连续的弧线纵轴表示概率密度而不是频数因此不同数据集之间的形态可以直接比较。对birds_filtered_1的最小翼展绘制密度图ggplot(data birds_filtered_1, aes(x MinWingspan)) geom_density()这条曲线与前面的直方图形态一致峰值位置、偏态方向相同但轮廓平滑得多。前面第二张直方图MaxBodyMassbins30中那条锯齿状的曲线也可以用密度图平滑地重现ggplot(data birds_filtered_1, aes(x MaxBodyMass)) geom_density()geom_density()的平滑程度由adjust参数控制它是核密度估计带宽的缩放系数数值越大曲线越平滑数值越小曲线越贴近原始数据、越「毛糙」。想要一条平滑但不过分圆润的曲线可以调小adjustggplot(data birds_filtered_1, aes(x MaxBodyMass)) geom_density(adjust 1/5)密度图特别适合做多分类对比只需在aes()中指定fill并配合半透明alpha就能用少数几行代码展示按鸟目Order分组的最大体重密度曲线ggplot(databirds_filtered_1, aes(x MaxBodyMass, fill Order)) geom_density(alpha0.5)不同目的曲线呈现出清晰的差异有的目如 Apodiformes 雨燕目体重高度集中在低值区间、曲线窄而陡有的目如 Columbiformes 鸽形目、Charadriiformes 鸻形目体重分布较宽且相互重叠。这种「一张图、多条平滑曲线、直接目测分组差异」的表达力是阶梯状直方图难以企及的。✅ 查阅geom_density()的完整参数列表如bw、kernel、trim动手实验它们对曲线形态的影响。进阶自修二维密度图本课已经掌握了geom_histogram()、geom_bin2d()与geom_density()三类核心工具。若要更进一步可以研究geom_density_2d()它在二维平面上生成一条或多条「连续概率密度等高线」相当于把二维直方图geom_bin2d的离散格子平滑为连续的等高线层次能够同时呈现两个变量的联合分布形态与密集区域。它结合了本课两方面的能力密度估计与双变量分布分析适合作为课后自修的下一站。挑战与实战练习直方图比基础的散点图、条形图、折线图更为进阶。可以围绕以下方向开展研究式练习应用场景调研在公开资料中寻找真实世界中直方图的应用案例——它在哪些领域如质量控制、生态学、人口统计、医学检验被使用揭示了什么信息换个数据集实战课程配套作业要求将本课技巧迁移到新数据集上例如 assignment.md 中建议的数据源编写一个 R 脚本用至少 5 个直方图讲述该数据集的故事并在脚本中详细标注数据来源与每一步分析的意图评分标准覆盖注释完整度、直方图数量与洞察质量。对照学习本课还有对应的 Python/Matplotlib 版本见 10-visualization-distributionsPython 版对照阅读可以更直观地理解ggplot2的语法层ggplot()geom_*()与 Matplotlib 命令式绘图之间的设计差异。小结通过本课你已经能够在 R 环境中用ggplot2完成一整套「分布分析」流程数据准备read.csv()加fileEncodingUTF-8-BOM正确读取数据subset()去除离群值并裁剪目标区间单变量分布用geom_histogram(bins…)观察频数分布与偏态用geom_density(adjust…)获得平滑的密度曲线双变量分布用geom_bin2d()加 viridis 色带观察两个数值分布的相关性与收敛区域文本变量处理将分类值编码为数字代理值配合positionidentity、alpha与scale_fill_manual()绘制叠加直方图。本课配套的完整讲义含原始英文版与练习位于 translations/en/3-Data-Visualization/R/10-visualization-distributions/README.md同目录下还提供了历史数据文件 data/birds.csv 供随时复现上一课 09-visualization-quantities 则提供了本课前置的散点图与数据清洗基础。【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网