如何在ggplot2中让负主轴对应的次轴条形图向上显示
解决ggplot2双轴图表中条形图向上显示的问题
我想用ggplot2创建双轴图表:主y轴为代表Log Odds的折线图(数值范围0至-8),次y轴为代表Weighted Count的条形图。当前条形图因主轴为负值向下显示,我需要它向上呈现——折线已正确从0向下到-8递减,但条形图需从主轴的-8刻度(对应次轴的0)开始,随计数增加向上延伸,二者共享同一基线。
我已尝试通过转换因子对齐两个刻度,将次轴数据基于主轴范围归一化并添加转换因子,但条形图仍从绘图区域顶部向下延伸,未达到预期效果。尝试的代码如下:
library(ggplot2) # Sample data set.seed(123) bucket_label <- seq(0, 2.5, by=0.5) log_odds <- seq(-1, -8, length.out=length(bucket_label)) Count <- sample(100:1000, length(bucket_label), replace = TRUE) BucketedData_nonmat <- data.frame(bucket_label, log_odds) Count.1 <- data.frame(bucket_label, Count) # Current plot code fit_range <- range(BucketedData_nonmat$log_odds, na.rm = TRUE) freq_range <- range(Count.1$Count, na.rm = TRUE) transformation_factor <- (freq_range[2] / fit_range[2]) /8 ggplot() + geom_bar(data = Count.1, aes(x = bucket_label, y = Count / transformation_factor), stat = "identity", fill = "grey", color = "grey", alpha = 0.2) + geom_line(data = BucketedData_nonmat, aes(x = bucket_label, y = log_odds), size = 1) + scale_y_continuous( name = "Log Odds", sec.axis = sec_axis(~ . * transformation_factor, name = "Weighted Count") )
解决方案
核心是将条形图的y值映射到主轴的[-8, 0]区间,让次轴的0对应主轴的-8,具体修正代码如下:
library(ggplot2) # 样本数据 set.seed(123) bucket_label <- seq(0, 2.5, by=0.5) log_odds <- seq(-1, -8, length.out=length(bucket_label)) Count <- sample(100:1000, length(bucket_label), replace = TRUE) BucketedData_nonmat <- data.frame(bucket_label, log_odds) Count.1 <- data.frame(bucket_label, Count) # 定义轴范围和转换因子 log_min <- -8 # 主轴基线,对应次轴计数0 log_max <- 0 # 主轴上限 count_max <- max(Count.1$Count) # 转换因子:将计数映射到主轴的[-8,0]区间 trans_factor <- (log_max - log_min) / count_max ggplot() + # 条形图:y值为基线(-8)加上计数对应的主轴偏移量 geom_col(data = Count.1, aes(x = bucket_label, y = log_min + Count * trans_factor), fill = "grey", color = "grey", alpha = 0.2) + # 折线图保持原数据 geom_line(data = BucketedData_nonmat, aes(x = bucket_label, y = log_odds), size = 1) + scale_y_continuous( name = "Log Odds", # 设置主轴范围为0到-8,确保显示完整区间 limits = c(log_min, log_max), sec.axis = sec_axis( # 次轴反向转换:从主轴y值得到计数 ~ (. - log_min) / trans_factor, name = "Weighted Count" ) ) + xlab("Bucket Label")
关键说明
geom_col的y值计算:log_min + Count * trans_factor,让计数为0时y=-8(基线),计数最大时y=0,条形从-8向上延伸;scale_y_continuous的limits强制主轴显示0到-8的完整范围,保证基线对齐;- 次轴的转换公式把主轴的y值反向计算为计数,实现双轴刻度的准确对应。
调整后,折线从0向下到-8,条形从-8(次轴0)向上延伸,二者共享同一基线,符合需求。
内容的提问来源于stack exchange,提问作者Sharif Amlani
相关产品推荐
相关产品推荐

