想象你要装修一套毛坯房。拿到房子的第一件事不是冲进家具城,而是看户型图,决定哪里是客厅、哪里是卧室,再定好整体装修风格。接下来你才去添置沙发、书架、窗帘,调节灯光色调,给每个房间挂上门牌,最后请专业摄影师拍一组高清照片,整套房子才算是“可以住人了”。 ggplot2就是帮你完成这套“从毛坯到美宅”全流程的装修施工队。它把画图拆成一道道工序:先用 ggplot() 拿到户型图(数据),用 aes() 标好每面墙的用途(美学映射),再用 geom_*() 一件件添置家具(几何对象),用 scale_*() 调节灯光(标度),用 theme_*() 统一风格(主题),用 facet_*() 给大空间做隔断(分面),用 labs() 挂上门牌(标签),最后用 ggsave() 拍出出版级高清大片(导出)。整个过程中你最常用的操作只有一个——加号 +,它像装修验收清单上的一个勾,每写一次,就有一层新东西被装进图里。 本文就用这套“装修比喻”带你走完 ggplot2 的全部核心流程,让零基础的你也能画出能投稿、能汇报、能发朋友圈的漂亮图表。

岗位关联

对 AI 从业者来说,数据可视化是把模型结果讲清楚的第一步。ggplot2 的图层语法能让你把任何分析结论变成一张出版级图表,是写论文、做报告、展示 AI 效果的必备硬技能。

目录
  1. 可视化演示
  2. 图层语法
  3. 几何对象
  4. 标度系统
  5. 主题美化
  6. 分面技术
  7. 标签注释
  8. 配色方案
  9. 高清导出
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

对比五种常见时间复杂度O(1)、O(log n)、O(n)、O(n log n)、O(n^2)随输入规模n的增长曲线。

本节配有交互动效(进入视口后自动加载,约 3KB)。

时间复杂度对比 — n=1 O(1)常数:不随n变化 O(log n)对数:增长极慢 n=1 O(n^2)与O(1)差距随n增大急剧扩大

图层语法

装修一套房子,第一步绝不是冲进家具城搬沙发,而是先拿到户型图,定好“哪里是客厅、哪里是卧室、厨房卫生间各占多大”。ggplot2 的第一步也如此温柔:它让你先把数据框(户型图)和美学映射(设计方案)交给 ggplot(),这时画布上一片空白,但整张图的结构已经悄悄定好。

在 R 中,ggplot(data = df, aes(x = 变量1, y = 变量2)) 创建画布,aes() 把数据列映射到视觉通道——x 轴、y 轴、颜色、大小。这一步不画任何图形,就像设计师还没贴墙纸,但已经在图纸上标好了每面墙的颜色和功能分区。

ggplot2 的灵魂是“图层语法”(Grammar of Graphics):一张图表由一层层组件叠加而成,每一层用 + 连接。数据层、映射层、几何层、标度层、主题层,层层递进。这种设计让画图像搭积木一样,想加什么就加什么,想改哪层就改哪层。

验证清单上的每一项都是“打勾叠加”。ggplot2 的加号就是你手中的验收笔——每写一个 +,装好的那件东西就永远留在图纸上,直到最后整间“图表之屋”竣工入住。这种可拆分、可叠加的语法,正是 ggplot2 能画出出版级图表的最大底气。

Plot=Data⏟数据+aes(⋅)⏟映射+geom(⋅)⏟几何+scale+theme+⋯\text{Plot} = \underbrace{\text{Data}}_{\text{数据}} + \underbrace{\text{aes}(\cdot)}_{\text{映射}} + \underbrace{\text{geom}(\cdot)}_{\text{几何}} + \text{scale} + \text{theme} + \cdots
这张图就是“装修总公式”:最终成品等于所有工序的叠加,加号(+)是连接每一道工序的胶水。
  1. Plot最终生成的图表对象,是整间“装修好的房子”。
    Plot\text{Plot}
  2. Data输入的数据框,是一切绘图的原材料,相当于户型图。
    Data\text{Data}
  3. aes(·)美学映射函数,把数据列翻译成 x、y、颜色等视觉通道。
    aes(⋅)\text{aes}(\cdot)
  4. geom(·)几何对象函数,决定数据用点、线还是柱来画。
    geom(⋅)\text{geom}(\cdot)
  5. 加号(+)连接符,每加一层,就往图中“装配”一个新部件。
    Layer1+Layer2+⋯\text{Layer}_1 + \text{Layer}_2 + \cdots

几何对象

客厅不能只有一张户型图。你得摆沙发、装搁板、挂窗帘——几何对象就是 ggplot2 的“家具”。同样是客厅,放中式红木沙发还是北欧布艺沙发,气质完全不同;同样一份数据,用散点还是用柱状,表达的信息也截然不同。

geom_point() 是散点图,适合看两个变量的相关关系,像茶几上的装饰盘,每盘对应一个观测值;geom_line() 是折线图,适合看时间趋势,像窗帘的波浪线条,把一个个点串成流动的方向;geom_col() 是柱状图,柱高表示数值大小,像书架每层的高度,一眼就能比出谁高谁低;geom_boxplot() 是箱线图,展示数据分布的“五数概括”,像收纳盒里整理好的物件,告诉你中位数在哪、离群值藏在哪。

每种几何对象都有自己默认的美学属性。point 需要 x、y;line 需要 x、y;col 需要 x 和 y(或权重)。几何层可以同时叠加多个,只要映射用得对。

家具可以混搭:客厅里沙发配茶几再加一盆绿植,ggplot2 里 geom_point() + geom_line() 一起上,散点给出每个观测的精确位置,折线串出整体趋势。但千万别把仓库里所有家具都搬进一个房间——图表也一样,信息过载到每个角落都堆满形状,读者就什么也看不出来了。

geom∈{point, line, col, boxplot, histogram, ⋯ }\text{geom} \in \{ \text{point},\ \text{line},\ \text{col},\ \text{boxplot},\ \text{histogram},\ \cdots \}
几何对象是“家具库”:散点、折线、柱状、箱线等不同图形,用哪种取决于你想让读者看到数据哪一面的故事。
  1. geom几何对象,决定数据以什么“长相”出现。
    geom\text{geom}
  2. ∈属于符号,表示几何对象是下面集合中的一个。
    ∈\in
  3. point散点,每个观测画一个点,适合看两变量关系。
    point\text{point}
  4. line折线,按顺序连接各点,适合看趋势变化。
    line\text{line}
  5. col柱状,柱高代表数值,适合类别间比较大小。
    col\text{col}

标度系统

同样的家具,在暖黄灯光下温馨,在冷白灯光下清爽——灯光决定了房间的“气质”。标度(scale)就是 ggplot2 里的灯光师,它控制坐标轴刻度怎么分、颜色从深到浅怎么变、点的大小范围多大,把数据的真实数值翻译成画布上协调的位置和色彩。

scale_x_continuous() 可以自定义 x 轴刻度与范围;scale_color_viridis() 控制颜色映射;scale_size() 控制点的大小。最常用也最关键的是对数变换:当数据从几十跨到几千万,横跨好几个数量级时,直接用原始值画图,小值全挤在一条线附近。scale_y_log10() 登场后,刻度变得均匀,小细节也看得清了。

灯光调得好,房间的层次感自然出来;标度调得好,数据的分布规律一目了然。尤其是画收入、流量这类“长尾数据”时,一个 scale_y_log10() 就能让你的图从“一团乱麻”变成“条理清晰”,这也是出版级图表和随手涂鸦的分水岭之一。

x′=log⁡10(x)x' = \log_{10}(x)
对数变换就像把一间塞满大小杂物的房间,按“每十倍为一格”重新整理,让每个量级都拥有属于自己的展示空间。
  1. x原始数据值,比如收入从 1000 到 10000000,跨越四个数量级。
    xx
  2. log₁₀以 10 为底的对数,把“相差十倍”变成“相差一格”。
    log⁡10\log_{10}
  3. x′变换后的坐标值,用于映射到坐标轴的刻度位置。
    x′x'

主题美化

毛坯房装完家具,还是“现代混搭”得有点杂乱。装修公司这时会递上一本风格画册:现代简约、日式原木、复古欧式,任选一套就能让全屋风格统一。ggplot2 的主题(theme)就是这本画册。

theme_minimal() 一键去掉默认的灰色背景和网格线,只留下清爽的白底;theme_classic() 回归传统学术风格,适合论文插图;theme_bw() 黑白主题,适合印刷。如果这些还不够,theme() 函数允许你微调每一个细节:element_text() 改字体族和字号,element_rect() 改背景与边框,element_line() 改网格线粗细和颜色,legend.position 控制图例放哪。

出版级图表通常不只是套用一个主题,而是“基础主题 + 一屏微调”:去掉多余网格线、把字体放大到 12 号以上、加粗主标题、图例移到底部或隐藏。

装修最后要统一柜子把手、门框颜色,主题就是那个“让每一处细节都协调”的总设计师。一个 theme_minimal() 能让你的图表立刻从“学生作业”升级成“咨询报告”;再花两分钟微调字体和网格线,投稿、汇报都镇得住场子。

theme: style↦{font, background, grid, legend}\text{theme}:\ \text{style} \mapsto \{ \text{font},\ \text{background},\ \text{grid},\ \text{legend} \}
主题函数把一种风格映射为一整套外观设定:字体、背景、网格线、图例,一键全换。
  1. theme主题函数,整体改变图表外观。
    theme\text{theme}
  2. style风格名,如 minimal、classic、bw。
    style\text{style}
  3. ↦映射符号,表示“把风格转换成一系列外观参数”。
    ↦\mapsto
  4. font字体与字号。
    font\text{font}
  5. background背景色与边框样式。
    background\text{background}
  6. grid网格线的有无与样式。
    grid\text{grid}
  7. legend图例的位置与外观。
    legend\text{legend}

分面技术

一个大客厅想同时给老人、孩子、客人三种人用怎么办?推拉门一拉,一个空间分成三个互不打扰的小空间。分面(facet)就是 ggplot2 的推拉门——按某个类别变量,把一张大图拆成多张并排的小图。

facet_wrap(~城市) 把一个分类变量的小图按顺序排列,放不下就自动换行,适合维度较少、想快速浏览每个类别的场景。facet_grid(行变量 ~ 列变量) 则生成一个二维矩阵,适合同时按两个变量分组,比如行放“性别”、列放“年龄段”。每个小图共享坐标轴,方便横向对比;如果数据各自量级差异太大,加上 scales = "free" 或 scales = "free_y",每个子图就能拥有自己的刻度范围。

推拉门拉开前,所有数据挤在一张图里是一团浆糊;拉开后,每个子集的规律清清楚楚。分面是“多类别对比”的终极武器:论文里按实验组/对照组分面,汇报里按门店/区域分面,一眼就能看出哪组表现好、哪组在恶化。

y^=f(x)for each level of z\hat{y} = f(x) \quad \text{for each level of } z
分面的含义是:对 z 的每个取值,各画一张以 x 预测 y 的小图。相当于“按楼层分区装修,每层独立设计但风格统一”。
  1. f(x)每个子图内的图形关系,比如折线趋势。
    f(x)f(x)
  2. z分面变量,比如“城市”或“门店”,每个取值生成一个小图。
    zz
  3. for each level of z遍历 z 的每一个水平,逐个绘制。
    for each level of z\text{for each level of } z

标签注释

房门上挂名牌、墙上贴便利贴、地板画箭头——访客才知道每个房间是什么、重点该看哪里。ggplot2 里,labs() 和 annotate() 就是干这活的两双手。

labs(title = "主标题", subtitle = "副标题", x = "X轴名", y = "Y轴名", caption = "脚注") 一次性搞定所有“门牌”。主标题通常是图表想表达的核心结论,副标题补充范围和数据口径,脚注标注数据来源。annotate("text", x = 值, y = 值, label = "文字") 则在图内任意坐标写下注释;配合 annotate("segment", ...) 加 arrow() 可以画出带箭头的指向线,直接戳中那个“峰值点”或“异常值”。

一幅出版级图表的标签要克制:标题一句话讲清楚结论,正文里的标注只留给最重要的两三个点,脚注诚实交代数据来源。每一个字都要回答读者“这是什么、看哪、为什么”。

再美的房间,没有门牌和说明,访客也会迷路;图表没有标签,读者就不知道横轴是“月份”还是“收入”,更不知道那个箭头指的是什么。给图表起个好标题,比给它多撞十个图层更能提升专业感——审稿人和老板最先看的就是标题。

T={title, subtitle, xlab, ylab, caption}T = \{ \text{title},\ \text{subtitle},\ \text{xlab},\ \text{ylab},\ \text{caption} \}
标签集合由五个部分组成:主标题、副标题、x 轴名、y 轴名、脚注。它们共同构成图表的“说明书”。
  1. T所有标签文本的集合。
    TT
  2. title主标题,表达核心结论或图名。
    title\text{title}
  3. subtitle副标题,补充说明范围与口径。
    subtitle\text{subtitle}
  4. xlabx 轴名称。
    xlab\text{xlab}
  5. ylaby 轴名称。
    ylab\text{ylab}
  6. caption脚注,标注数据来源与时间。
    caption\text{caption}

配色方案

装修选软装时,设计师会拿出一本“色卡”,保证沙发、窗帘、抱枕颜色之间有呼应。ggplot2 的配色方案就是现成的色卡库,拿过来直接用,永远比随手点的红黄蓝绿协调。

RColorBrewer 是最经典的选择:scale_fill_brewer(palette = "Set2") 提供分类色,适合离散类别;"Blues" 这类序列色,由浅到深表达数值递增,适合热力图;"RdBu" 这类发散色,中间浅两头深,适合表达正负偏离。近几年,viridis 色板异军突起,它基于感知均匀的色彩空间设计,颜色之间有相同的视觉距离,而且对色盲友好——scale_color_viridis_d() 一行代码就搞定。

选择配色有一条黄金法则:先想清楚数据是“分类”还是“连续”,再决定用分类色、序列色还是发散色。分类数据用五颜六色的分类色会显得杂乱,连续数据用彩虹色会误导对比。

调色盘选得好,家具之间有了呼应,房间自带高级感;配色选得好,数据分组一眼就能区分,连续变化清晰可感。一个团队如果统一用 viridis 或固定几套 RColorBrewer 色板,整套报告都会显得专业、整洁,这就是“出版级”的隐形门槛。

palette∈{qualitative, sequential, diverging}\text{palette} \in \{ \text{qualitative},\ \text{sequential},\ \text{diverging} \}
调色板分为三大类:分类色、序列色、发散色。选错类型就像装修时把暖色冷色乱搭,视觉上会打架。
  1. palette调色板,一组预先设计好的颜色集合。
    palette\text{palette}
  2. qualitative分类色,类别之间差异明显、无顺序感。
    qualitative\text{qualitative}
  3. sequential序列色,由浅到深表示数值从小到大。
    sequential\text{sequential}
  4. diverging发散色,中间浅、两端深,表示偏离中点的程度。
    diverging\text{diverging}

高清导出

装修得再漂亮,最终也要拍一组“房源上线照”。用手机随便一拍,再好的设计也显得廉价;用单反在自然光下拍 300dpi 高清大片,马上身价翻倍。ggsave() 就是 ggplot2 的专业相机。

ggsave("output.png", plot = p, width = 8, height = 6, dpi = 300) 是标准用法:文件名决定格式(.png 为位图,.pdf 为矢量),width 和 height 控制物理尺寸,dpi 决定每英寸多少像素。投稿论文至少 300dpi,PPT 展示 150dpi 够用,屏幕预览 96dpi 就行。如果图表要放进论文或书籍排版,强烈建议导出 PDF 矢量格式——矢量图由数学曲线组成,放大一万倍都不会出现锯齿和马赛克。

装修得再好,照片拍糊了也白搭;图表做得再漂亮,导出分辨率太低,放进论文里就是一团马赛克,审稿人直接打回。记住这条公式,导出前先算一算够不够清晰,再决定用 PNG 还是 PDF——这是“出版级”的最后一公里。

px=inch×dpi\text{px} = \text{inch} \times \text{dpi}
图片像素数 = 物理尺寸(英寸)× 分辨率(dpi)。同样一张 8 英寸宽的图,300dpi 是 2400 像素,96dpi 只有 768 像素,清晰度天差地别。
  1. px最终图片的像素尺寸。
    px\text{px}
  2. inch图片物理宽度(英寸),8 英寸约等于 20.3 厘米。
    inch\text{inch}
  3. dpi每英寸像素点数,印刷标准 300,屏幕标准 96。
    dpi\text{dpi}

AI 应用场景

学术论文配图

阶段:实验结果可视化与交付

解决的问题:论文审稿人要求图表达到出版级清晰度。用 Excel 随手截图的图表分辨率不足、配色凌乱,反复被要求重做。

具体案例:某医学影像 AI 研究团队用 ggplot2 绘制模型评估图:geom_boxplot() 展示各算法在五个数据集上的 AUC 分布,facet_grid(数据集 ~ 模型类型) 分面排列,viridis 色板区分算法类别,最后 ggsave(..., dpi = 300) 导出 TIFF 与 PDF 双版本用于投稿。图上每个子集的差异一目了然,审稿意见中“图表质量差”的评论从此消失。

电商运营分析报告

阶段:业务数据分析与洞察呈现

解决的问题:每周经营分析会上,图表信息混杂、重点不突出,管理者在几十个维度里找不到关键变化。

具体案例:某电商平台的数据分析师用 geom_col() + geom_line() 组合展示“日 GMV 与订单量”双视角,用 annotate("segment") 加箭头标注“双11大促”和“大促后回落”两个关键节点,labs() 把标题写成结论式“大促后三天 GMV 回落 32%,需关注复购”,再用 theme_minimal() 统一风格。原本需要 10 分钟口头解释的数据,变成一张图讲 30 秒。

城市交通可视化大屏

阶段:数据洞察展示

解决的问题:交通数据量大、维度多,单张图信息过载,大屏上小流量路段被大数值淹没。

具体案例:某智能交通公司数据团队用 facet_wrap(~时段, scales = "free_y") 把全城路况按“早高峰/平峰/晚高峰/夜间”拆成四张子图,scale_y_log10() 处理从几百到几十万的车流量跨度,scale_color_viridis_d() 区分快速路、主干道和支路。四张子图在大屏轮播,值班人员一眼定位异常拥堵区域,再结合 AI 预测模型提前调流。

Python 演示

python37 行
import pandas as pdimport numpy as npfrom plotnine import (    ggplot, aes, geom_point, geom_line,    labs, theme_minimal, facet_wrap,    scale_color_viridis_d, ggsave) np.random.seed(2024)n_per_store = 20stores = ["A店", "B店", "C店"]df_list = []for i, store in enumerate(stores):    base = 50 + i * 25    trend = np.cumsum(np.random.normal(loc=1.5, scale=4.0, size=n_per_store))    df_list.append(pd.DataFrame({        "month": range(1, n_per_store + 1),        "sales": base + trend,        "store": store,    }))df = pd.concat(df_list, ignore_index=True) p = (    ggplot(df, aes(x="month", y="sales", color="store"))    + geom_point(size=2, alpha=0.7)    + geom_line()    + facet_wrap("~store", scales="free_y")    + labs(title="三家门店月度销售额趋势",           subtitle="模拟数据演示 ggplot2 图层语法",           x="月份", y="销售额(万元)",           caption="数据来源: 模拟数据集")    + theme_minimal()    + scale_color_viridis_d())print(p)ggsave(p, "sales_trend.png", width=8, height=6, dpi=300)print("已导出 sales_trend.png (300dpi)")
目的:用 Python 的 plotnine 包复刻 ggplot2 完整绘图流程,生成一张出版级门店销售额趋势图并导出 300dpi 高清文件。
  1. from plotnine import (...)导入 ggplot2 的 Python 移植版,函数名与 R 保持一致,学一遍两边通用。
  2. np.random.seed(2024)固定随机种子,保证每次运行生成的数据相同,便于复现和调试。
  3. np.cumsum(np.random.normal(...))生成带随机波动的累计趋势,模拟真实门店销售额的涨涨跌跌。
  4. ggplot(df, aes(x="month", y="sales", color="store"))创建画布并映射美学:月份上 x 轴、销售额上 y 轴、门店按颜色区分。
  5. + geom_point(size=2, alpha=0.7)叠加散点层,半透明点避免重叠遮挡。
  6. + geom_line()叠加折线层,串出趋势方向。
  7. + facet_wrap("~store", scales="free_y")按门店拆成三张子图,且各自拥有独立的 y 轴刻度。
  8. + labs(...)添加主标题、副标题、轴名和脚注,图表的“门牌”全部挂好。
  9. + theme_minimal()一键极简主题,去掉默认灰底和网格线,立刻有出版级质感。
  10. + scale_color_viridis_d()使用色盲友好的 viridis 配色,让三条折线既好看又易区分。
  11. ggsave(p, "sales_trend.png", width=8, height=6, dpi=300)以 300dpi 导出 8×6 英寸高清图,论文印刷级清晰度。

常见误区

误区“我明明在 ggplot() 里传了数据,为什么还要在 geom_point() 里再写一遍 x 和 y?能不能直接在 geom_point(x = 列1, y = 列2) 里指定?”

正解不能。数据列必须通过 aes() 声明映射,告诉 ggplot“哪一列对应 x、哪一列对应 y、哪一列对应颜色”。aes() 是设计蓝图,geom 只是施工队——施工队只负责按蓝图搬家具,不负责自己决定每个房间的功能。如果要在某个 geom 里单独指定映射,也必须写在 aes() 里。

为何常见:初学者习惯了 Excel 选两列直接出图的交互逻辑,不习惯 ggplot2“先映射、后绘制”的声明式思维,所以总想绕过 aes() 走捷径。

误区“ggplot2 里的 `+` 不就是 R 的加法运算符吗?为什么我把 ggsave() 也加进去就一直报错?”

正解在 ggplot 对象语境下,+ 被重载为“图层叠加符”,作用是在图表上增加一个组件或修改一个设置。它不像算术加法那样计算数值,而是像装修清单上的勾选:每写一个 +,就多一道工序。ggsave() 是拍照动作,不是装修工序,所以不能放进 + 链里。

为何常见:R 语言里 + 太常见了,很容易忘记它在面向对象绘图环境中被赋予了全新的语法意义。

误区“geom_point() 能画点,geom_line() 能连线,geom_col() 能画柱,我都画上去,读者肯定觉得信息量巨大、非常专业。”

正解图表不是信息仓库。散点+折线是经典组合,但散点+折线+柱状+箱线叠在一起,只会让画面像堆满所有家具的房间,转身都难。出版级图表的黄金法则是“一个图层突出一个重点”:趋势用折线,分布用箱线,比较用柱状,混搭只限于少数互补组合(如散点+趋势线)。

为何常见:新手觉得“画得越满越用心”,忽略了可视化的本质是降低读者的认知负担。

误区“我画出来的图灰底格纹、字小色杂,别人用 ggplot2 画得那么高级,是不是我下载的包有问题?”

正解默认主题确实不够好看,但这不是工具的错。出版级图表是“数据映射 + 几何选择 + 主题微调 + 配色方案 + 高分辨率导出”五步组合的产物。先套 theme_minimal() 或 theme_classic() 打底,再改字号、删网格线、换 viridis 色板,最后 300dpi 导出——每一步都做到,图不可能丑。

为何常见:默认设置和高级成品之间的差距需要经验补足,新手容易把“不会用”误判为“工具不行”。

误区“我截了 4K 屏幕的图放进论文还是模糊,是不是该换台更好的显示器?”

正解屏幕截图分辨率再高也是 96dpi 左右,而印刷需要 300dpi。直接用 ggsave(..., dpi = 300) 生成图片,或者导出 PDF 矢量格式,才符合出版要求。记住公式“像素 = 英寸 × dpi”:8 英寸宽的图,96dpi 只有 768 像素,300dpi 有 2400 像素,清晰度差两倍以上。

为何常见:屏幕显示清晰和纸面印刷清晰是两套标准,许多人从来不知道 dpi 这个概念,只能靠截图“硬扛”。

面试题

Q1. ggplot2 绘图的基本起点是什么?

单选题 · easy

  • A.直接调用 geom_point() 画点
  • B.ggplot(data, aes()) 建画布← 正确答案
  • C.theme_minimal() 设置主题
  • D.ggsave() 导出图片文件

答案:B。ggplot2 的一切从 ggplot(data, aes()) 开始,它创建画布并声明数据与美学映射;几何对象、主题、导出都是在这张画布上叠加的后置步骤。就像装修必须先拿到户型图才能摆家具。

Q2. ggplot2 中 aes() 函数的核心作用是什么?

单选题 · easy

  • A.添加标题与副标题文本
  • B.把数据列映射到视觉通道← 正确答案
  • C.改变图表的背景颜色
  • D.将图片保存到指定路径

答案:B。aes() 是“美学映射”,把数据框里的列翻译成 x 轴、y 轴、颜色、大小等视觉通道。它相当于装修方案里“这面墙刷什么色”的标注;标题、背景、导出分别由 labs()、theme()、ggsave() 负责。

Q3. 下列哪个是绘制柱状图的几何对象?

单选题 · easy

  • A.geom_point()
  • B.geom_line()
  • C.geom_col()← 正确答案
  • D.geom_boxplot()

答案:C。geom_col() 用柱高代表数值,适合类别间比较;point 是散点、line 是折线、boxplot 是箱线图。选择几何对象就像选择家具种类,先想清楚要表达什么故事再决定。

Q4. 数据范围从 100 到 10000000 跨四个数量级,最佳做法是?

单选题 · mid

  • A.对 y 轴做对数变换 scale_y_log10()← 正确答案
  • B.删除掉所有最大值所在的行
  • C.把所有数据统一除以 1000000
  • D.改用饼图展示占比关系

答案:A。scale_y_log10() 把“每十倍”压成等距刻度,小值不再挤成一条线。删数据、缩放数据都会扭曲信息,饼图更不适合连续变量。这就像把塞满大小杂物的房间按量级重新整理,每个尺寸都得到展示空间。

Q5. 想把一张大图按“城市”拆成多个并排小图,应使用?

单选题 · mid

  • A.theme_classic() 经典主题
  • B.facet_wrap(~城市)← 正确答案
  • C.scale_color_manual() 手动配色
  • D.annotate("text", ……) 文字标注

答案:B。分面函数负责“隔断”:facet_wrap(~城市) 按城市的每个取值各画一张子图并自动排列。主题、配色、标注都改变不了图的结构,只有 facet 系列能拆图。

Q6. ggsave 中 dpi=300 表示什么含义?

单选题 · mid

  • A.图片文件的体积大小
  • B.每英寸包含的像素点数← 正确答案
  • C.图片物理宽度的计量单位
  • D.颜色通道的位深数值

答案:B。dpi 是 Dots Per Inch,每英寸像素点。按公式“像素 = 英寸 × dpi”,300dpi 是印刷标准,96dpi 是屏幕标准。同样尺寸的图,dpi 越高细节越密,放大后越清晰。

Q7. 想让分面后的每个子图拥有独立坐标轴刻度,应如何设置?

单选题 · hard

  • A.labs(scales = "free")
  • B.theme(scales = "free")
  • C.facet_wrap(……, scales = "free")← 正确答案
  • D.ggsave(……, scales = "free")

答案:C。scales 是分面函数的专属参数,scales = "free" 表示每个子图根据自身数据范围独立定刻度,"free_y" 只放开 y 轴。其他函数不认识这个参数。就像每个独立小房间允许按自己的面积布置家具,不受大屋统一规格限制。

Q8. 要在图中画一条带箭头的线指向某个异常数据点,并配上文字,正确做法是?

单选题 · hard

  • A.只用 annotate("text", ……) 就够了
  • B.annotate("segment", ……) + arrow() 画箭头,再配 text 注释← 正确答案
  • C.用 labs() 参数直接添加指向箭头
  • D.用 theme() 的 legend.position 实现

答案:B。annotate("segment", ...) 画线段,配合 arrow() 加箭头,annotate("text", ...) 写文字,两者组合才能完成“箭头+文字”的指向标注。labs() 只添加标题类文本,theme() 只管外观,都无法画定向箭头。

Q9. 以下哪些做法能显著提升图表的“出版级”质感?

多选题 · mid

  • A.套用 theme_minimal() 后微调字体与网格线← 正确答案
  • B.使用 viridis 或 RColorBrewer 专业配色← 正确答案
  • C.叠加尽可能多的几何对象让信息铺满全图
  • D.导出时设置 dpi=300 或使用 PDF 矢量格式← 正确答案

答案:ABD。极简主题、专业配色、高清导出是出版级图表的三根支柱。而 C 恰恰相反——堆砌几何对象会造成信息过载,把图表变成“家具堆满的仓库”,读者反而抓不住重点。

Q10. 关于 ggplot2 的图层语法,下列说法正确的是?

多选题 · hard

  • A.用加号 + 逐层叠加各组件← 正确答案
  • B.aes() 只能在 ggplot() 中出现一次且不可覆盖
  • C.标度和主题都是可以叠加的独立图层← 正确答案
  • D.geom_point() 与 geom_line() 永远不能同时使用

答案:AC。+ 是图层叠加符,A 正确;aes() 可以在各 geom 中局部覆盖映射,B 错误;scale_* 和 theme_* 都以图层形式参与叠加,C 正确;散点+折线是经典组合,D 错误。就像装修清单上的每一道工序都可以独立追加,也都可以针对某个房间单独调整。