R语言 plotrix 包绘制双坐标轴图实战:从线图到帕累托图
在使用 R 语言进行数据分析时,`ggplot2` 虽然强大但不支持双 Y 轴(双坐标轴)图形。若需在同一图表中展示量纲不同的两组数据,可以使用 `plotrix` 包中的 twoord.plot() 和 twoord.stackplot() 函数。本文将通过具体案例,详解如何绘制双轴线图、混合条形线图、直方-核密度图以及帕累托图,并解决刻度、样式和图例等常见问题。
准备环境与核心函数
首先,需要安装并加载 plotrix 包。该包提供了专门用于绘制双坐标轴图形的工具,其中最常用的是 twoord.plot()。
install.packages("plotrix")
library(plotrix)
基本操作:绘制双轴线图
第1步:准备示例数据
为了演示双坐标轴的效果,我们创建包含时间序列、左侧数值(如会员人数)和右侧数值(如消费总额)的数据框。
Date <- seq(from = as.Date('2015-01-01'), to = as.Date('2015-12-01'), by = 'month')
Consumers <- c(100,80,120,153,200,188,220,322,300,321,282,304)
Amount <- c(1000,840,1458,1844,2045,2000,2548,5081,5000,5200,4800,4971)
df1 <- data.frame(Date = Date, Consumers=Consumers, Amount = Amount)
第2步:调用 twoord.plot 绘制基础图形
使用 twoord.plot() 函数,分别指定左轴(lx, ly)和右轴(rx, ry)的数据来源。默认情况下,左右轴均为线条类型。
twoord.plot(lx = df1$Date, ly = df1$Consumers,
rx = df1$Date, ry = df1$Amount,
main = '双轴的两条线图', xlab = '月份',
ylab = '会员人数', rylab = '总消费额',
type = c('line', 'line'))
此时生成的图形存在三个常见痛点:
- 横坐标轴的日期格式显示不正确(通常显示为数字)。
- 右坐标轴刻度标签过于密集。
- 图形缺乏视觉层次,如背景色或网格线缺失。
第3步:优化图形细节
通过调整关键参数解决上述问题:
- 格式化横坐标:使用
xtickpos指定刻度位置(转换为数值),并使用xticklab指定自定义标签文本。 - 调整右轴刻度:通过
rytickpos手动设定右侧刻度的间隔点。 - 添加背景与网格:利用
do.first参数在执行主要绘图前插入命令,可添加背景色 (plot_bg) 和网格线 (grid)。
twoord.plot(lx = df1$Date, ly = df1$Consumers,
rx = df1$Date, ry = df1$Amount,
main = '双轴的两条线图', xlab = '月份',
ylab = '会员人数', rylab = '总消费额',
type = c('line', 'line'),
xtickpos = as.numeric(df1$Date),
xticklab = as.character(df1$Date),
rytickpos = seq(500, 5000, by = 1500),
do.first = "plot_bg(col = 'gray'); grid(col='white', lty = 2)")
进阶技巧:混合图形类型
有时需要结合两种图形类型,例如左侧用条形图表示数量,右侧用折线图表示趋势。只需修改 type 参数即可。
第4步:绘制条形图与折线图组合
将 type 设置为 c('bar', 'line')。默认情况下,条形图可能过窄,可通过 halfwidth 参数调整宽度。
twoord.plot(lx = df1$Date, ly = df1$Consumers,
rx = df1$Date, ry = df1$Amount,
lcol = 'steelblue', main = '双轴混合图',
xlab = '月份', ylab = '会员人数', rylab = '总消费额',
type = c('bar', 'line'),
xtickpos = as.numeric(df1$Date),
xticklab = as.character(df1$Date),
rytickpos = seq(500, 5000, by = 1500),
halfwidth = 8,
do.first = "plot_bg(col = 'gray'); grid(col='white', lty = 2)")
特殊场景:直方图与核密度图双轴
在概率分布分析中,常需同时展示频次(直方图)和概率密度(核密度曲线)。由于两者量纲不同(频次可能为数百,密度值通常为0~1之间),必须使用双坐标轴。
第5步:生成基础分布数据
注意:绘制直方图和核密度线时,直方图需设置 freq = FALSE 以返回密度而非频次,但在双轴图中,我们通常希望左轴显示原始频次,右轴显示密度,因此需要分别提取数据。
x <- rnorm(1000, 10, 3)
h <- hist(x, breaks = 50)
第6步:提取数据并绘制双轴图
左轴使用直方图的计数 (h$counts),右轴使用正态分布密度函数计算的密度值 (dnorm)。
x1 <- h$mids
y1 <- h$counts
x2 <- seq(min(x), max(x), by = 0.01)
y2 <- dnorm(seq(min(x), max(x), by = 0.01), 10, 3)
twoord.plot(lx = x1, ly = y1, rx = x2, ry = y2,
type = c('bar', 'l'),
lcol = 'steelblue', rcol = 'red',
ylab = 'Counts', rylab = 'Density',
main = 'Histogram and density curve',
halfwidth = 0.2,
lylim = c(0, max(y1) + 1),
rylim = c(0, 0.2),
lwd = 2)
应用场景:帕累托图 (Pareto Chart)
帕累托图结合了条形图和累积百分比折线图,用于识别主要因素。左轴为绝对数值,右轴为累计百分比(0-1)。
type_label <- 1:7
absolute <- c(12, 15, 20, 28, 11, 5, 7)
cum_per <- cumsum(absolute) / sum(absolute)
twoord.plot(lx = type_label, ly = absolute,
rx = type_label, ry = cum_per,
type = c('bar', 'l'),
lcol = 'steelblue', rcol = 'red',
ylab = '总数', rylab = '累计百分比%',
main = '帕累托图',
xtickpos = type_label,
xticklab = c('A','B','C','D','E','F','G'))
扩展功能:堆叠图与图例添加
如果需要展示多个类别的堆叠效果,可使用 twoord.stackplot() 函数。以下案例展示新老会员人数堆叠柱状图及新客比例折线图。
第7步:绘制堆叠双轴图
set.seed(1111)
Date <- 1:12
Old <- round(runif(12, 100, 300))
New <- round(runif(12, 50, 120))
Ratio <- New / (New + Old)
twoord.stackplot(lx = Date, rx = Date,
ldata = cbind(Old, New), rdata = Ratio,
lcol = c('steelblue', 'orange'), rcol = 'red',
ltype = 'bar', rtype = 'l',
border = 'grey80',
ylab = '人数', rylab = '新客比例',
xlab = '月份', main = '新老客占比',
incrylim = 0.1)
twoord.stackplot 默认不显示图例。为了实现完美的视觉效果,可以通过叠加图层的方式手动添加图例。
第8步:手动添加图例层
使用 par(new=TRUE) 在当前图形上覆盖新图形,绘制一个空白画布后添加图例,最后恢复默认设置。
# 允许绘图区域外绘制
par(xpd = TRUE)
# 开启新图层
par(new = TRUE)
# 绘制空白坐标系占位
plot(0:1, 0:1, type = "n", xlab = "", ylab = "", axes = FALSE)
# 添加左轴图例(老客、新客)
legend(0, 1.5, legend = c('老客', '新客'),
fill = c('steelblue', 'orange'), bty = 'n')
# 添加右轴图例(新客比例)
legend(-0.03, 1.25, legend = '新客比例', col = 'red', lty = 1, bty = 'n')
# 重置绘图参数
par(xpd = FALSE, new = FALSE)
通过以上步骤,您可以灵活掌握 R 语言中 plotrix 包的双坐标轴绘图技巧,满足不同维度的数据可视化需求。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









