news 2026/10/15 21:00:53

R语言散点图加边际分布:ggplot2与ggExtra实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
R语言散点图加边际分布:ggplot2与ggExtra实战指南

1. 散点图搭配边际分布图,到底解决了什么痛点

做过数据分析的人都有这种体会:手里攥着两个连续变量,想看看它们之间有没有关系,第一反应就是画个散点图。散点图确实直观,一个点代表一个样本,横轴纵轴各放一个变量,点的分布形态一眼就能看出正相关、负相关还是毫无规律。但问题也随之而来——当样本量大了,点会严重重叠,你根本看不清哪里密哪里疏;当样本量小了,你又很难判断每个变量各自的分布形态到底长什么样。

传统的做法是画完散点图,再单独画两个直方图或者密度曲线,分别看x和y的边缘分布。但这样有个麻烦:你得在脑子里把三张图拼起来,来回对照,效率低不说,还容易漏掉关键信息。比如x轴某个区间样本特别密集,同时y轴取值也集中,这种联合分布的特征在三张分离的图里很难快速捕捉到。

边际分布图(Marginal Distribution Plot)就是冲着这个痛点来的。它的核心思路很简单:在主散点图的顶部和右侧(或者左侧),各附加一个单变量的分布图,通常是直方图、密度曲线或者箱线图。这样一张图里,你既能看两个变量的联合关系,又能同时看到各自的边缘分布,信息密度直接翻倍。更妙的是,顶部和右侧的分布图会和主图的坐标轴严格对齐,哪个区间点密集,对应的边缘分布高峰在哪里,一目了然。

在R语言里,实现这种图的方式有好几种,最常用的组合是ggplot2加上ggExtra包,或者用cowplot、patchwork手动拼图,再或者用GGally包里的ggpairs做更复杂的多变量矩阵图。每种方案各有优劣,适合不同的场景。接下来我会从设计思路、核心细节、实操过程到问题排查,把这条路完整走一遍,让你看完就能直接上手,不用再到处翻文档。

这篇文章适合谁看?如果你已经会用R画基础的ggplot2图,但想让自己的探索性数据分析(EDA)输出更专业、信息更密集,那这篇就是为你准备的。如果你刚接触R,也没关系,我会把关键参数和逻辑都拆开讲清楚,你照着抄作业也能跑通。

2. 整体设计思路与方案选型

2.1 为什么首选ggplot2 + ggExtra组合

在R的可视化生态里,ggplot2是事实上的标准,它的图层语法让复杂图形的构建变得模块化。而ggExtra这个包,专门就是为了给ggplot2散点图加边际分布而生的。它的核心函数ggMarginal()可以直接接收一个已经画好的ggplot对象,然后在顶部和右侧自动添加指定类型的边际图。

这个方案的优势很明显:第一,代码量极少,基本上三行核心代码就能出图;第二,它完全兼容ggplot2的图层系统,你在主图上做的任何映射(颜色、大小、形状、分面)都能保留;第三,边际图的类型可以灵活选择,直方图、密度曲线、箱线图、小提琴图都支持,还能分别指定x轴和y轴用不同的类型。

相比之下,用cowplot或patchwork手动拼图虽然灵活性更高,但需要你自己计算坐标轴对齐、调整边距、处理图例位置,代码量至少翻三倍,而且很容易在拼图过程中出现对齐偏差。GGally的ggpairs更适合多变量矩阵图,如果你只有两个变量,用它有点杀鸡用牛刀的感觉,而且默认样式偏“矩阵”,不如ggExtra出来的图清爽。

所以我的建议很明确:两个变量的散点图加边际分布,无脑选ggplot2 + ggExtra。如果你需要更复杂的自定义布局,再考虑手动拼图。

2.2 边际图类型的选择逻辑

ggMarginal()支持几种边际图类型,每种都有适用的场景。选错了类型,图不仅不好看,还可能误导读者。

直方图(histogram)是最常见的选择,适合样本量中等(几百到几千)的情况。它能直观展示每个区间的频数,但缺点是 bin 的宽度需要手动调,调不好会显得很毛糙或者过度平滑。默认的 bin 数量在ggMarginal里是30,对于大多数场景够用,但如果你的数据范围特别大或者特别集中,就需要调整。

密度曲线(density)适合样本量较大(几千以上)的情况,它给出的是平滑的概率密度估计,看起来更优雅。但要注意,密度曲线的平滑带宽(bandwidth)会影响形态,带宽太小会过度拟合,出现很多毛刺;带宽太大又会把双峰抹成单峰。ggMarginal默认用的是ggplot2的geom_density,带宽由bw参数控制,通常用默认的“nrd0”规则就行,但如果你的数据有明显的多峰特征,可以手动调小一点。

箱线图(boxplot)适合你想快速看中位数、四分位数和异常值的情况。它的信息密度不如直方图和密度曲线,但胜在简洁,尤其适合在报告里展示。不过箱线图会隐藏分布的具体形态,如果数据是双峰的,箱线图完全看不出来,这时候就不如用密度曲线。

小提琴图(violin)是箱线图和密度曲线的结合,既能看分位数,又能看分布形态。但小提琴图在样本量小的时候会显得很怪异,因为核密度估计不稳定。一般来说,样本量低于100就不太建议用小提琴图。

我的经验是:探索阶段用直方图或密度曲线,看细节;展示阶段用箱线图或小提琴图,看概要。如果拿不准,就用密度曲线,它最不容易出错。

2.3 颜色与分组的处理策略

如果你的数据里有分组变量,比如不同实验条件、不同性别、不同地区,你肯定想在散点图里用颜色区分开。ggMarginal是支持这个的,但有个坑:默认情况下,边际图会把所有组混在一起画,颜色区分不明显。

解决办法是设置groupColour = TRUE和groupFill = TRUE,这样边际图也会按组着色。但要注意,如果组数太多(超过5组),边际图会变得非常花哨,反而看不清。这时候可以考虑用分面(facet)代替颜色分组,或者只对最重要的两组做颜色区分。

另外,边际图的透明度也很关键。默认的填充透明度是0.5左右,如果组间重叠严重,可以调低到0.3,让重叠区域的颜色叠加更明显。但太低又会让颜色发灰,看起来不干净。我一般用0.4到0.6之间的值,具体看数据密度。

3. 核心细节解析与实操要点

3.1 数据准备与预处理的关键步骤

在画图之前,数据清洗和预处理是绕不开的。散点图加边际分布对数据的要求其实不高,但有几个细节如果没处理好,图出来就会有问题。

第一,缺失值处理。ggplot2默认会忽略缺失值,但会在控制台给你一个警告。如果你的数据里缺失值很多,最好在画图前就用na.omit()或者tidyr::drop_na()明确去掉,避免警告信息干扰。更重要的是,你要清楚缺失值去掉后样本量还剩多少,如果去掉太多,边际分布的形态可能会严重失真。

第二,变量类型检查。散点图的x和y必须是连续变量,如果是因子或者字符,ggplot2会报错或者画出奇怪的东西。用str()或者class()确认一下,必要时用as.numeric()转换。但要注意,如果字符型数字转换后出现NA,说明里面有非数字字符,需要先清理。

第三,异常值处理。散点图对异常值非常敏感,一个极端的点会把整个坐标轴拉长,导致其他点挤在一起。边际分布也会因为异常值出现长长的拖尾。我的做法是先用箱线图或者summary()看一下变量的范围,如果发现明显偏离的异常值,可以考虑用filter()去掉,或者用scale_x_continuous(limits = c(...))限制坐标轴范围。但要注意,限制坐标轴范围只是视觉上截断,数据本身还在,边际分布的计算也会受影响。如果要去掉异常值,最好在数据层面操作。

第四,数据量控制。如果样本量超过几万,散点图会变得非常卡,边际分布的计算也会变慢。这时候可以考虑随机抽样,比如用sample_n(5000)抽5000个点画图。抽样不会改变分布形态,但能大幅提升绘图速度。如果不想抽样,可以用geom_point(alpha = 0.1)降低透明度,或者用geom_hex()做六边形分箱,但后者和ggMarginal的兼容性不太好。

3.2 ggMarginal核心参数详解

ggMarginal()的参数不多,但每个都很关键。我把最常用的几个列出来,配上解释和推荐值。

参数作用推荐值注意事项
p输入的ggplot对象必填必须是散点图,其他类型可能不兼容
type边际图类型"density"可选"histogram"、"boxplot"、"violin"
margins边际图位置"both"可选"x"或"y",只画一个
size主图与边际图的大小比例5默认5,数值越大主图占比越大
groupColour是否按组着色线条FALSE有分组时设为TRUE
groupFill是否按组填充FALSE有分组时设为TRUE
alpha填充透明度0.50.3到0.7之间比较合适
bins直方图bin数量30仅type="histogram"时有效
xparamsx轴边际图的额外参数list()可传fill、color等
yparamsy轴边际图的额外参数list()同上

这里重点说几个容易踩坑的地方。

size参数控制的是主图和边际图的比例。默认值5意味着主图占5份,边际图占1份。如果你觉得边际图太小看不清,可以调到3或者4。但太小了主图又会被压缩,一般3到7之间比较平衡。

xparams和yparams是列表,里面可以传ggplot2的图层参数。比如你想让x轴边际图的填充色是浅蓝色,可以写xparams = list(fill = "lightblue")。但要注意,如果同时设置了groupFill = TRUE,这里的fill会被覆盖,所以分组和自定义颜色不要同时用。

还有一个隐藏坑:ggMarginal默认会继承主图的主题,但边际图的坐标轴标签、刻度线有时候会显得很挤。你可以在xparams和yparams里传theme()来调整,比如xparams = list(theme(axis.text = element_blank()))把边际图的坐标轴文字去掉,让图更干净。

3.3 主题与配色的一致性处理

一张专业的图,配色和主题必须统一。ggMarginal生成的边际图默认用的是ggplot2的默认主题(灰色背景、白色网格线),如果你主图用了自定义主题,比如theme_minimal()或者theme_bw(),边际图会显得格格不入。

解决办法是在画主图的时候就定义好主题,ggMarginal会尽量继承。但有些主题元素(比如背景色)在边际图里可能不会完全一致,这时候就需要在xparams和yparams里手动补上。比如:

xparams = list(theme_minimal(), theme(axis.title = element_blank()))

配色方面,如果你在主图里用了scale_color_brewer()或者scale_fill_manual(),边际图的颜色不会自动跟随。你需要手动在xparams和yparams里指定相同的颜色。这确实有点麻烦,但为了图的一致性,值得花这几分钟。

我的习惯是:先定好一个配色方案,比如用RColorBrewer的"Set2"调色板,然后主图和边际图都用同一组颜色。如果组数少,直接手动指定十六进制色值,比如c("#66C2A5", "#FC8D62", "#8DA0CB"),这样最可控。

4. 完整实操流程与代码实现

4.1 环境准备与依赖安装

先把需要的包装好。ggplot2和ggExtra是核心,dplyr用来做数据处理,palmerpenguins提供一个干净的内置数据集用来演示。如果你不想用内置数据,换成自己的数据也行,但建议先用内置数据跑通流程,再换自己的数据。

# 安装包(如果还没装的话) install.packages(c("ggplot2", "ggExtra", "dplyr", "palmerpenguins")) # 加载包 library(ggplot2) library(ggExtra) library(dplyr) library(palmerpenguins)

palmerpenguins这个数据集很干净,有344个样本,包含企鹅的喙长、喙深、鳍长、体重和物种等信息。我们用它来演示,因为变量都是连续型的,而且有分组变量(物种),很适合展示分组边际分布的效果。

4.2 基础散点图加边际分布

先画一个最基础的版本,不加分组,只看两个变量的关系。用喙长(bill_length_mm)做x轴,喙深(bill_depth_mm)做y轴。

# 基础散点图 p <- ggplot(penguins, aes(x = bill_length_mm, y = bill_depth_mm)) + geom_point(alpha = 0.6, color = "#2c7fb8", size = 2) + theme_minimal() + labs(x = "喙长 (mm)", y = "喙深 (mm)") # 加边际密度图 p_marginal <- ggMarginal(p, type = "density", size = 5, alpha = 0.5, fill = "lightblue") # 显示 p_marginal

这段代码跑出来,你会看到主图是散点,顶部和右侧各有一条密度曲线。alpha = 0.5让填充半透明,fill = "lightblue"指定填充色。size = 5是默认比例,主图占5份,边际图占1份。

如果你觉得密度曲线太细看不清,可以加粗线条:

p_marginal <- ggMarginal(p, type = "density", size = 5, alpha = 0.5, fill = "lightblue", xparams = list(size = 1.2), yparams = list(size = 1.2))

size = 1.2控制的是密度曲线的线宽,默认是0.5,调到1以上会明显变粗。

4.3 分组边际分布的实现

现在加上物种分组,用颜色区分。这里有个关键点:ggMarginal默认不会按组着色边际图,需要显式设置groupColour = TRUE和groupFill = TRUE。

# 分组散点图 p_grouped <- ggplot(penguins, aes(x = bill_length_mm, y = bill_depth_mm, color = species)) + geom_point(alpha = 0.7, size = 2) + scale_color_brewer(palette = "Set2") + theme_minimal() + labs(x = "喙长 (mm)", y = "喙深 (mm)", color = "物种") # 分组边际密度图 p_grouped_marginal <- ggMarginal(p_grouped, type = "density", size = 5, alpha = 0.4, groupColour = TRUE, groupFill = TRUE) p_grouped_marginal

跑出来之后,边际图会按物种分成三条不同颜色的密度曲线,重叠区域的颜色会叠加。alpha = 0.4让叠加更明显,但又不至于太浑浊。

这里有个细节:scale_color_brewer(palette = "Set2")指定了主图的颜色,但边际图的颜色是ggMarginal自己处理的,它默认用的是ggplot2的默认色盘。如果你想让边际图也用"Set2"的颜色,需要在xparams和yparams里手动指定:

p_grouped_marginal <- ggMarginal(p_grouped, type = "density", size = 5, alpha = 0.4, groupColour = TRUE, groupFill = TRUE, xparams = list(fill = c("#66C2A5", "#FC8D62", "#8DA0CB")), yparams = list(fill = c("#66C2A5", "#FC8D62", "#8DA0CB")))

这样颜色就完全一致了。注意fill传的是一个向量,顺序要和因子水平的顺序一致。用levels(penguins$species)可以查看顺序。

4.4 直方图与箱线图边际图的切换

密度曲线看多了会腻,换个直方图试试。直方图的好处是能看出具体的频数分布,尤其是当数据有明确的区间聚集时。

# 直方图边际图 p_hist <- ggMarginal(p, type = "histogram", size = 5, bins = 25, fill = "steelblue", alpha = 0.6) p_hist

bins = 25控制直方图的柱子数量。这个值需要根据数据范围调,太少会太粗,太多会太碎。一般来说,样本量在300左右,20到30个bin比较合适。你可以多试几个值,看哪个最能反映分布形态。

箱线图边际图更适合展示概要信息:

# 箱线图边际图 p_box <- ggMarginal(p, type = "boxplot", size = 5, fill = "lightgreen", alpha = 0.7) p_box

箱线图边际图不会显示具体的分布形态,但中位数和四分位距一目了然。如果你的报告需要简洁,箱线图是很好的选择。

小提琴图是箱线图和密度曲线的结合:

# 小提琴图边际图 p_violin <- ggMarginal(p, type = "violin", size = 5, fill = "lightpink", alpha = 0.6) p_violin

小提琴图在样本量大于100时效果不错,但样本量小的时候核密度估计会不稳定,出现奇怪的形状。企鹅数据有344个样本,用小提琴图没问题。

4.5 自定义布局与导出高分辨率图片

ggMarginal生成的图默认是ggplot对象,可以用ggsave()导出。但要注意,ggMarginal返回的对象类型是ggExtraPlot,ggsave()是支持的,但有时候需要显式指定设备。

# 导出为PNG,300 DPI ggsave("marginal_plot.png", plot = p_grouped_marginal, width = 8, height = 6, dpi = 300) # 导出为PDF,矢量图 ggsave("marginal_plot.pdf", plot = p_grouped_marginal, width = 8, height = 6)

width和height的单位是英寸,dpi = 300是印刷级别的分辨率。如果是放在网页上,150 DPI就够了,文件会小很多。

如果你觉得默认的布局比例不合适,可以调size参数。比如想让边际图更大一点:

p_large_marginal <- ggMarginal(p_grouped, type = "density", size = 3, # 主图占3份,边际图占1份 alpha = 0.4, groupColour = TRUE, groupFill = TRUE)

size = 3意味着主图和边际图的比例是3:1,边际图会明显变大。但主图会被压缩,点会显得更挤。一般3到7之间比较平衡,具体看你的输出尺寸。

还有一个技巧:如果边际图的坐标轴标签和主图重叠,可以在xparams和yparams里去掉坐标轴文字:

p_clean <- ggMarginal(p_grouped, type = "density", size = 5, alpha = 0.4, groupColour = TRUE, groupFill = TRUE, xparams = list(theme(axis.text = element_blank(), axis.title = element_blank())), yparams = list(theme(axis.text = element_blank(), axis.title = element_blank())))

这样边际图就只有曲线,没有坐标轴文字,整体更干净。但要注意,去掉坐标轴文字后,读者可能无法准确读出边际图的数值,所以如果数值很重要,还是保留比较好。

5. 常见问题与排查技巧实录

5.1 边际图不显示或显示不全

这是最常见的问题。跑完ggMarginal()之后,图出来了,但边际图是空白的,或者只有一条线。原因通常有几个:

第一,数据里有缺失值。ggplot2画主图时会自动忽略缺失值,但ggMarginal计算边际分布时可能没有正确处理,导致边际图为空。解决办法是在画图前用drop_na()去掉缺失值:

penguins_clean <- penguins %>% drop_na(bill_length_mm, bill_depth_mm)

第二,变量类型不对。如果x或y是字符型或者因子,ggMarginal无法计算密度或直方图。用class()检查一下,必要时转换。

第三,type参数和数据类型不匹配。比如用type = "density"但数据只有几个点,核密度估计会失败。这时候换成type = "histogram"或者type = "boxplot"。

第四,size参数太小。如果size设成10以上,边际图会被压缩到几乎看不见。调回5左右试试。

5.2 分组颜色不一致或重叠混乱

分组边际图最常见的问题是颜色不一致:主图用了自定义色盘,边际图还是默认色盘。解决办法前面提过,在xparams和yparams里手动指定fill向量。

另一个问题是组间重叠太严重,边际图看起来一团糟。这时候可以:

  • 降低alpha到0.3,让重叠区域的颜色叠加更明显
  • 减少组数,只保留最重要的两组
  • 改用分面(facet)代替颜色分组

分面的做法是在主图里加facet_wrap(~ species),然后ggMarginal会对每个分面单独加边际图。但要注意,ggMarginal对分面的支持有限,有时候会出错。如果分面不行,就手动用cowplot拼图。

5.3 图形导出后模糊或比例失调

导出图片模糊,通常是dpi设低了。ggsave()默认的dpi是300,但如果你的输出尺寸很小,比如width = 4, height = 3,300 DPI出来也只有1200x900像素,放大看还是会糊。解决办法是增大输出尺寸,或者提高dpi到600。

比例失调通常是width和height的比例和图形本身的比例不匹配。ggMarginal生成的图,主图是正方形的比例比较好看,所以width和height最好接近1:1。如果你设成width = 10, height = 4,主图会被拉扁,边际图也会变形。

还有一个坑:ggsave()导出ggExtraPlot对象时,有时候会丢失边际图。这是因为ggsave()默认用的是ggplot2的导出方法,而ggExtraPlot是ggExtra的自定义对象。解决办法是用png()或pdf()设备手动导出:

png("marginal_plot.png", width = 8, height = 6, units = "in", res = 300) print(p_grouped_marginal) dev.off()

这样最稳妥,不会丢图层。

5.4 大数据量下的性能优化

样本量超过1万时,ggMarginal会明显变慢,因为密度估计和直方图计算都是O(n)的复杂度。优化方法有几个:

第一,随机抽样。用sample_n(5000)抽5000个点,分布形态基本不变,但速度会快很多。

第二,用geom_point(alpha = 0.1)降低透明度,减少渲染负担。但ggMarginal的边际图计算还是全量的,所以这个方法只对主图渲染有帮助。

第三,改用geom_hex()做六边形分箱,但ggMarginal不支持geom_hex,需要手动拼图。

第四,如果只是探索性分析,可以先用小样本跑通流程,确定参数后再用全量数据出最终图。

5.5 常见问题速查表

问题现象可能原因解决办法
边际图空白数据有缺失值用drop_na()清理
边际图只有一条线变量类型不对转换为numeric
分组颜色不一致未指定fill向量在xparams/yparams里传fill
导出后模糊dpi太低提高dpi到600或增大尺寸
导出后丢边际图ggsave兼容性问题用png()/pdf()手动导出
运行速度慢样本量太大随机抽样或降低透明度
边际图坐标轴重叠布局太挤去掉边际图坐标轴文字
密度曲线太毛糙带宽太小调大bw参数

6. 进阶技巧与个人实操心得

6.1 用patchwork手动拼图实现完全自定义

ggMarginal虽然方便,但灵活性有限。如果你想要完全自定义的布局,比如边际图放在左侧、或者主图和边际图之间加间距、或者边际图用不同的主题,那就需要手动拼图。

patchwork包是目前最优雅的拼图方案。核心思路是:分别画主散点图、x轴边际图、y轴边际图,然后用/和|操作符组合。

library(patchwork) # 主散点图(去掉x和y轴标签,因为边际图会提供) p_main <- ggplot(penguins, aes(x = bill_length_mm, y = bill_depth_mm, color = species)) + geom_point(alpha = 0.7, size = 2) + scale_color_brewer(palette = "Set2") + theme_minimal() + theme(axis.title.x = element_blank(), axis.title.y = element_blank(), legend.position = "none") # x轴边际密度图 p_x <- ggplot(penguins, aes(x = bill_length_mm, fill = species)) + geom_density(alpha = 0.4) + scale_fill_brewer(palette = "Set2") + theme_minimal() + theme(axis.title = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), legend.position = "none") # y轴边际密度图(注意coord_flip) p_y <- ggplot(penguins, aes(x = bill_depth_mm, fill = species)) + geom_density(alpha = 0.4) + scale_fill_brewer(palette = "Set2") + theme_minimal() + coord_flip() + theme(axis.title = element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank(), legend.position = "none") # 拼图:顶部是p_x,左侧是p_y,中间是p_main layout <- p_x + plot_spacer() + p_main + p_y + plot_layout(ncol = 2, widths = c(4, 1), heights = c(1, 4)) layout

这个方案的优点是每个部分都可以独立控制,主题、颜色、坐标轴都能精确调整。缺点是代码量大,而且需要手动处理坐标轴对齐。plot_spacer()用来占位,让布局正确。widths和heights控制比例,这里主图占4份,边际图占1份。

手动拼图还有一个好处:你可以用不同的几何对象。比如x轴边际图用直方图,y轴边际图用箱线图,ggMarginal虽然也支持分别指定,但手动拼图更灵活。

6.2 边际分布图的常见误用与避坑

边际分布图虽然好用,但有几个常见的误用场景,我踩过坑,这里分享一下。

误用一:用边际图代替联合分布分析。边际图展示的是单变量分布,它不能告诉你两个变量之间的条件关系。比如x和y的边际分布都是单峰,但联合分布可能是双峰(辛普森悖论的视觉版本)。所以边际图是补充,不是替代,主散点图才是核心。

误用二:分组太多导致边际图不可读。我见过有人把10个组的边际密度曲线叠在一起,结果就是一团彩色乱麻。如果组数超过5个,建议要么合并小组,要么用分面,要么只画总体边际图,分组信息在主图里用颜色表示就够了。

误用三:忽略样本量对密度估计的影响。样本量小于50时,密度曲线会非常不稳定,出现很多虚假的峰。这时候用直方图或者箱线图更诚实。样本量小于20时,甚至箱线图都不太可靠,最好直接看散点图。

误用四:坐标轴范围不一致。主图和边际图的坐标轴必须严格对齐,否则读者会误读。ggMarginal自动处理了对齐,但手动拼图时很容易出错。检查方法是看主图的x轴范围和边际图的x轴范围是否一致,如果不一致,用coord_cartesian()或者scale_x_continuous(limits = ...)统一。

6.3 个人实操心得:从探索到展示的完整工作流

我自己的习惯是分两步走:探索阶段和展示阶段。

探索阶段,我用ggMarginal快速出图,type = "density",alpha = 0.5,不加分组或者只加最重要的分组。目的是快速看数据形态,发现异常值和有趣的现象。这个阶段不追求美观,追求速度。

展示阶段,我会花时间调主题、配色、布局。如果ggMarginal能满足需求,就用它,代码简洁;如果需要更精细的控制,就用patchwork手动拼图。导出时用png()设备,res = 300,尺寸根据输出场景定。如果是论文插图,用PDF矢量图;如果是PPT,用PNG,150 DPI就够了。

还有一个心得:边际图的类型不要一成不变。如果数据有明显的偏态,密度曲线会显示长长的拖尾,这时候直方图可能更直观。如果数据有异常值,箱线图能直接标出来。多试几种类型,选最能说明问题的那一种。

最后分享一个小技巧:如果你的数据有时间维度,比如按月份分组,可以在边际图里用facet_wrap按月份分面,这样能看到分布随时间的变化。但ggMarginal对分面的支持不好,需要用patchwork手动拼图。具体做法是先用facet_wrap画主图,然后对每个分面单独提取数据画边际图,再用patchwork组合。这个稍微复杂一点,但效果很好,适合做时间序列的探索性分析。

这个内容后续还可以这样扩展:把边际分布图扩展到三维,用plotly做交互式散点图,鼠标悬停时显示边际分布;或者用gganimate做动画,展示分布随某个变量的变化过程。这些都是很有意思的方向,等有时间再折腾。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 21:00:49

美赛M奖论文实战:水资源分配赛题的建模、求解与写作全解析

简介&#xff1a;这份资源是2022年美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff09;B题M奖优秀论文的完整PDF&#xff0c;面向备战美赛的高校学生与建模爱好者&#xff0c;聚焦美国西部千年一遇干旱背景下的水资源公平分配难题。论文提出FHSD公平分层供需模型&#xff0…

作者头像 李华
网站建设 2026/10/15 21:00:27

HP-Socket:高并发TCP/UDP/HTTP通信框架实战与性能调优

做网络通信开发这些年&#xff0c;HP-Socket 是我反复拿来当底座的少数几个库之一。最早在某个物联网网关项目里需要同时维持上万条 TCP 长连接&#xff0c;还要做透传和协议解析&#xff0c;自己用 epoll 撸了一套&#xff0c;连接管理、粘包拆包、缓冲池全部手写&#xff0c;…

作者头像 李华
网站建设 2026/10/15 20:59:58

markdownlint 规则 MD021 深度解析:closed atx 标题内多余的井号间距

开发工具代码质量Lint静态分析 【免费下载链接】markdownlint A Node.js style checker and lint tool for Markdown/CommonMark files. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ma/markdownlint 点击查看 免费下载 本文围绕 markdownlint 仓库中的 MD021 规则文…

作者头像 李华
网站建设 2026/10/15 20:58:57

SAP库存调拨MB1B移动类型详解:从311/313到在途库存与转储订单

简介&#xff1a;一份系统讲解SAP MM模块库存调拨与发货流程的图文资料&#xff0c;面向SAP顾问、ERP实施人员及供应链相关从业者&#xff0c;帮助理解MB1B事务代码在库存地间、工厂间及状态转变场景中的实际用法。资料以单个Word文档形式提供&#xff0c;压缩包内共1个docx文件…

作者头像 李华
网站建设 2026/10/15 20:58:30

LeetCode 437路径总和III:前缀和与哈希表优化解法

1. 题目背景与核心问题LeetCode 437题"路径总和 III"是二叉树类问题中的经典题目&#xff0c;主要考察对树结构的遍历和路径统计能力。题目要求&#xff1a;给定一个二叉树的根节点和一个目标和&#xff0c;找出路径和等于给定值的路径数量。这里的路径不需要从根节点…

作者头像 李华