Y-break 与 R 中的比例变化
Y-break with scale change in R
我还是 R 的新手。我同意帮助一位朋友重新绘制他的图表,但事实证明他的一个绘图设计很难重现。这是因为他插入了一个 Y 轴中断,然后在条形图上进行了比例更改。下面的示例图片说明了这一点。
没想到这很难实现。我尝试使用:
barplot() #很难用所有元素实现,做不到
gap.barplot() #不允许分组条形图
ggplot() #经过相当长的时间学习基础知识后发现它不允许打断轴
请问有没有人有在 R 上绘制此图的直观方法?
注意:我知道显示此信息的最佳方式可能是对数据进行对数转换以使其适合比例,但我想建议使用手头的两个绘图选项。
下面给出了一些汇总数据,如果有人想测试的话:
AAP Sex min max mean sd
1 12d Female 100.97 702.36 444.07389 197.970342
2 12d Male 24.69 1090.15 469.48200 262.893780
3 18d Female 195.01 4204.68 1273.72000 1105.568111
4 18d Male 487.75 4941.30 1452.37937 1232.659688
5 24d Female 248.58 3556.11 1583.09958 925.263382
6 24d Male 556.60 4463.22 1589.50318 973.225661
7 3d Female 4.87 16.93 12.86571 4.197987
8 3d Male 3.23 16.35 8.13000 5.364383
9 6d Female 3.20 37.63 15.07500 11.502331
10 6d Male 4.64 94.93 28.39300 30.671206
无论使用哪种图形包,所涉及的基本步骤都是相同的:
- 将数据转换成你想要的 Y 尺度
- 提供一些规模中断的迹象
- 更新 y 轴以显示新比例
所以 ggplot 中的示例可能看起来像
library(ggplot2)
dput (dat)
#structure(list(AAP = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L,
#4L, 5L, 5L), .Label = c("12d", "18d", "24d", "3d", "6d"), class = "factor"),
#Sex = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("Female",
#"Male"), class = "factor"), min = c(100.97, 24.69, 195.01,
#487.75, 248.58, 556.6, 4.87, 3.23, 3.2, 4.64), max = c(702.36,
#1090.15, 4204.68, 4941.3, 3556.11, 4463.22, 16.93, 16.35,
#37.63, 94.93), mean = c(444.07389, 469.482, 1273.72, 1452.37937,
#1583.09958, 1589.50318, 12.86571, 8.13, 15.075, 28.393),
#sd = c(197.970342, 262.89378, 1105.568111, 1232.659688, 925.263382,
#973.225661, 4.197987, 5.364383, 11.502331, 30.671206)), .Names = c("AAP",
#"Sex", "min", "max", "mean", "sd"), class = "data.frame", row.names = c(NA,
#-10L))
#Function to transform data to y positions
trans <- function(x){pmin(x,40) + 0.05*pmax(x-40,0)}
yticks <- c(0, 20, 40, 500, 1000, 1500, 2000)
#Transform the data onto the display scale
dat$mean_t <- trans(dat$mean)
dat$sd_up_t <- trans(dat$mean + dat$sd)
dat$sd_low_t <- pmax(trans(dat$mean - dat$sd),1) #
ggplot(data=dat, aes(x=AAP, y=mean_t, group=Sex,fill=Sex)) +
geom_errorbar(aes(ymin=sd_low_t, ymax=sd_up_t),position="dodge") +
geom_col(position="dodge") +
geom_rect(aes(xmin=0, xmax=6, ymin=42, ymax=48), fill="white") +
scale_y_continuous(limits=c(0,NA), breaks=trans(yticks), labels=yticks) +
labs(y="Relative titer of CLas")
请注意,我没有得到与您示例完全相同的错误栏,并且生成的输出可能不会令 ggplot2 的作者 Hadley Wickham 满意。
@Miff 我想使用你上面的代码,但我做的不对:
trans <- function(x){pmin(x,15000) + 0.05*pmax(x-15000,0)}
yticks <- c(0, 5000, 10000, 15000, 30000, 40000)
p <-
labdata_N %>%
ggplot(aes(x = reorder(type, measure), weight = measure, fill = type, alpha = Tobacco.Constituent)) +
geom_bar(position = "dodge", width = 0.75) +
scale_alpha_manual(values = c(0.4, 1)) +
geom_rect(aes(xmin=0, xmax=12.5, ymin=15000, ymax=16000), fill="white") +
scale_y_continuous(limits=c(0,NA), breaks=trans(yticks), labels=yticks) +
labs(x = "SLT type", y = "Nitrosamine level") +
scale_fill_manual(values=mycols,
labels=c(type)) +
theme(legend.position = "bottom",
legend.title = element_blank(),
axis.text = element_text(size=12),
axis.title = element_text(size=14),
plot.title = element_text(size=14),
legend.text = element_text(size=9),
panel.background = element_rect(fill = "grey90"))
print(p)
我得到这样的结果:
我还是 R 的新手。我同意帮助一位朋友重新绘制他的图表,但事实证明他的一个绘图设计很难重现。这是因为他插入了一个 Y 轴中断,然后在条形图上进行了比例更改。下面的示例图片说明了这一点。
没想到这很难实现。我尝试使用:
barplot() #很难用所有元素实现,做不到
gap.barplot() #不允许分组条形图
ggplot() #经过相当长的时间学习基础知识后发现它不允许打断轴
请问有没有人有在 R 上绘制此图的直观方法? 注意:我知道显示此信息的最佳方式可能是对数据进行对数转换以使其适合比例,但我想建议使用手头的两个绘图选项。
下面给出了一些汇总数据,如果有人想测试的话:
AAP Sex min max mean sd
1 12d Female 100.97 702.36 444.07389 197.970342
2 12d Male 24.69 1090.15 469.48200 262.893780
3 18d Female 195.01 4204.68 1273.72000 1105.568111
4 18d Male 487.75 4941.30 1452.37937 1232.659688
5 24d Female 248.58 3556.11 1583.09958 925.263382
6 24d Male 556.60 4463.22 1589.50318 973.225661
7 3d Female 4.87 16.93 12.86571 4.197987
8 3d Male 3.23 16.35 8.13000 5.364383
9 6d Female 3.20 37.63 15.07500 11.502331
10 6d Male 4.64 94.93 28.39300 30.671206
无论使用哪种图形包,所涉及的基本步骤都是相同的:
- 将数据转换成你想要的 Y 尺度
- 提供一些规模中断的迹象
- 更新 y 轴以显示新比例
所以 ggplot 中的示例可能看起来像
library(ggplot2)
dput (dat)
#structure(list(AAP = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L,
#4L, 5L, 5L), .Label = c("12d", "18d", "24d", "3d", "6d"), class = "factor"),
#Sex = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("Female",
#"Male"), class = "factor"), min = c(100.97, 24.69, 195.01,
#487.75, 248.58, 556.6, 4.87, 3.23, 3.2, 4.64), max = c(702.36,
#1090.15, 4204.68, 4941.3, 3556.11, 4463.22, 16.93, 16.35,
#37.63, 94.93), mean = c(444.07389, 469.482, 1273.72, 1452.37937,
#1583.09958, 1589.50318, 12.86571, 8.13, 15.075, 28.393),
#sd = c(197.970342, 262.89378, 1105.568111, 1232.659688, 925.263382,
#973.225661, 4.197987, 5.364383, 11.502331, 30.671206)), .Names = c("AAP",
#"Sex", "min", "max", "mean", "sd"), class = "data.frame", row.names = c(NA,
#-10L))
#Function to transform data to y positions
trans <- function(x){pmin(x,40) + 0.05*pmax(x-40,0)}
yticks <- c(0, 20, 40, 500, 1000, 1500, 2000)
#Transform the data onto the display scale
dat$mean_t <- trans(dat$mean)
dat$sd_up_t <- trans(dat$mean + dat$sd)
dat$sd_low_t <- pmax(trans(dat$mean - dat$sd),1) #
ggplot(data=dat, aes(x=AAP, y=mean_t, group=Sex,fill=Sex)) +
geom_errorbar(aes(ymin=sd_low_t, ymax=sd_up_t),position="dodge") +
geom_col(position="dodge") +
geom_rect(aes(xmin=0, xmax=6, ymin=42, ymax=48), fill="white") +
scale_y_continuous(limits=c(0,NA), breaks=trans(yticks), labels=yticks) +
labs(y="Relative titer of CLas")
请注意,我没有得到与您示例完全相同的错误栏,并且生成的输出可能不会令 ggplot2 的作者 Hadley Wickham 满意。
@Miff 我想使用你上面的代码,但我做的不对:
trans <- function(x){pmin(x,15000) + 0.05*pmax(x-15000,0)}
yticks <- c(0, 5000, 10000, 15000, 30000, 40000)
p <-
labdata_N %>%
ggplot(aes(x = reorder(type, measure), weight = measure, fill = type, alpha = Tobacco.Constituent)) +
geom_bar(position = "dodge", width = 0.75) +
scale_alpha_manual(values = c(0.4, 1)) +
geom_rect(aes(xmin=0, xmax=12.5, ymin=15000, ymax=16000), fill="white") +
scale_y_continuous(limits=c(0,NA), breaks=trans(yticks), labels=yticks) +
labs(x = "SLT type", y = "Nitrosamine level") +
scale_fill_manual(values=mycols,
labels=c(type)) +
theme(legend.position = "bottom",
legend.title = element_blank(),
axis.text = element_text(size=12),
axis.title = element_text(size=14),
plot.title = element_text(size=14),
legend.text = element_text(size=9),
panel.background = element_rect(fill = "grey90"))
print(p)
我得到这样的结果: