摘要:
挖坑容易填坑难,但这次我带着
bb_bar、scales="free"和气泡图回来了!让 Base Plot 再次伟大(误)!
经常关注我的朋友可能还记得,2019年和2020年的时候,我写了两篇关于 plotbb 的文章(《可别再说base plot不能图形语法!》、《base plot的图形语法》)。当时也是一时兴起,觉得 R 语言的 base plot 虽然底层强大(毕竟是 R 的亲儿子),但写起来太过程式了,缺乏 ggplot2 那样优雅的“图形语法”支持。于是我就撸起袖子,写了一个叫 plotbb 的包——Brammar of Braphics,基于 base plot 的图形语法。
当时我也说了:“挖坑容易,填坑难。” 后来因为忙(主要是懒),这个包就一直停留在一个“能用但简陋”的状态。虽然核心的 bbplot()、bb_aes() 和主题系统都有了,但图层太少(只有点和线),scale 系统也比较弱。
最近,我又把这个坑刨出来了。看着这个半成品,我觉得还是得给它“穿上衣服”。于是,我带来了一波硬核更新,不仅补全了常用的图层,还扩展了 scale 系统,甚至连分面的自由度都给打通了。现在,新版已经正式上线 CRAN,大家可以直接通过 install.packages() 安装了!
install.packages("plotbb")1. 图层大补全:Bar, Line, Errorbar
以前大家吐槽最多的是:“只有点图(bb_point)能看,我想画个柱状图咋办?”
现在,bb_bar(柱状图)、bb_line(线图)、bb_segment(线段)、bb_errorbar(误差棒)全都有了!这意味着你可以用 plotbb 画出更多类型的统计图表,甚至是组合图。
来看个例子,我们用 mtcars 数据集,算一下不同气缸数的平均油耗,并画个“柱状图+误差棒+散点”的组合图。这种图在 base plot 里原生画起来可得写不少代码,但在 plotbb 里,就是搭积木:
library(plotbb)
library(dplyr)
# 准备数据:计算均值和标准差
df_sum <- group_by(mtcars, cyl) %>%
summarize(
mpg_mean = mean(mpg),
mpg_sd = sd(mpg)
)
# 画图
p <- bbplot(df_sum, bb_aes(x = cyl, y = mpg_mean)) +
# 柱状图层,设置宽度和颜色
bb_bar(stat = "identity", width = 0.5, col = "grey80") +
# 误差棒图层
bb_errorbar(bb_aes(ymin = mpg_mean - mpg_sd, ymax = mpg_mean + mpg_sd), width = 0.2) +
# 散点图层,高亮显示
bb_point(pch = 19, cex = 2, col = "red") +
bb_labs(title = "Bar + Errorbar + Point") +
bb_theme_expand()
print(p)
2. Scales & Legend 系统大升级:万物皆可映射
以前 plotbb 的 scale 系统比较简陋,主要支持颜色(col)。现在,我们将映射扩展到了形状(pch)、线型(lty)和大小(cex)。
更重要的是,图例(Legend)系统也做了大升级。bb_legend 现在不仅能自动识别颜色映射,还能通过 aesthetic 参数指定显示哪种映射的图例。而且,对于连续型变量的颜色映射,它还能自动画出 Color Bar!
2.1 气泡图与连续型大小映射
cex 不仅支持离散映射,还支持连续映射!我们可以轻松画出气泡图:
# 气泡图:x=mpg, y=disp, 大小映射wt, 颜色映射cyl
bbplot(mtcars, bb_aes(mpg, disp, cex = wt, col = factor(cyl))) +
bb_point(pch = 19) +
# 调整气泡大小范围
bb_scale_cex_continuous(range = c(1, 3)) +
# 自动生成图例,title自动提取,这里手动指定一下
bb_legend(title = "Cylinders") +
bb_labs(title = "Bubble Chart: Mpg vs Disp (Size = Wt)")
2.2 多重图例与 Color Bar
如果你在一个图中同时映射了多个属性(比如颜色代表重量,形状代表档位),你可以添加多个 bb_legend 来分别展示它们。对于连续变量的颜色映射,plotbb 会自动生成渐变色条。
# 多重图例展示
bbplot(mtcars, bb_aes(mpg, disp, col = wt, pch = factor(gear))) +
bb_point(cex = 2) +
# 设置渐变色
bb_scale_col_gradient(low = "blue", high = "red") +
# 添加颜色图例(自动变为Color Bar)
bb_legend(aesthetic = "col", title = "Weight (Continuous)", position = "bottomright") +
# 添加形状图例
bb_legend(aesthetic = "pch", title = "Gear (Discrete)", position = "bottomleft") +
bb_labs(title = "Multi-Legend & Color Bar")
3. 分面(Facet)的自由之路
bb_facet_wrap 之前虽然能分面,但坐标轴范围(scales)是全局固定的。这在很多时候(比如不同分组的数据量级差异很大)会很难看,甚至掩盖数据的特征。
这次更新,我给 bb_facet_wrap 加上了 scales 参数,完全对标 ggplot2,支持 "free", "free_x", "free_y"。
# 分面图,坐标轴自由
bbplot(mtcars, bb_aes(mpg, wt, col = factor(gear))) +
bb_point(pch = 19) +
bb_lm(bb_aes(group = gear), lwd = 2) +
# scales = "free" 让每个分面自动计算坐标轴范围
bb_facet_wrap(~gear, scales = "free") +
bb_labs(title = "Facet Wrap with Free Scales")
总结
现在的 plotbb,已经从一个“玩具”变成了一个真正可用的工具。虽然离 ggplot2 的大而全还有距离,但在 base plot 的生态位上,它绝对是目前最能打的图形语法实现。
如果你是 base plot 的死忠粉,又羡慕 ggplot2 的语法;或者你需要在一些不想引入繁重依赖(如 ggplot2 及其庞大的依赖树)的场景下画图,plotbb 绝对值得一试。它既有 base plot 的轻量和灵活性,又有图形语法的优雅。
快去试试吧!让你的 base plot 代码也飞起来!