事情很简单,就是实验数据想分组做个 barplot,由于数据之间差别有点大所以需要给 Y 轴加 gap。
直接给例子吧:
set.seed(123)
vl <- c(rnorm(10) + 4, rnorm(8) + 50)
grp <- c(rep("A", 5), # 实验有 4 个分组
rep("B", 4),
rep("C", 4),
rep("D", 5))
lbs <- c(paste0("A", 1:5), # 每组数据量不一
paste0("B", 1:4),
paste0("C", 1:4),
paste0("D", 1:5))
colors <- c(rep("red", 5), # 打算每组用不同的颜色
rep("darkgreen", 4),
rep("blue", 4),
rep("orange", 5))
dat <- data.frame(id = 1:18,
group = grp,
label = lbs,
color = colors,
value = vl)
# 先看看直接组图会长什么样子,后面再来自己一步一步修
barplot(value ~ id, dat)
得到平平无奇的柱图:
然后就是加上分组和颜色。
我没找到很完美的“自动”分组作图的方法,自己很笨地用了手动指定颜色和间隔:
atidx <- c(.5 + 1.2 * 0:4,
.5 + 1.2 * 4 + 2 + 1.2 * 0:3,
.5 + 1.2 * 4 + 2 + 1.2 * 3 + 2 + 1.2 * 0:3,
.5 + 1.2 * 4 + 2 + 1.2 * 3 + 2 + 1.2 * 3 + 2 + 1.2 * 0:4)
sp <- c(0, rep(.2, 4), 1,
rep(.2, 3), 1,
rep(.2, 3), 1,
rep(.2, 4))
barplot(value ~ label,
col = colors,
space = sp,
border = "white",
axes = FALSE, axisnames = FALSE,
ylim = c(0, 56),
data = dat)
axis(1,
lwd = 2,
tck = -.01,
# lwd.ticks = 2,
at = atidx,
# tick = FALSE,
labels = FALSE, )
text(x = atidx,
y = par("usr")[3] - 3,
labels = dat$label,
xpd = NA,
## Rotate the labels by 35 degrees.
srt = 30,
cex = .75)
axis(2, lwd = 2, at = c(seq(0, 60, 10)))
得到:
然后我就 Google 到了可以加 gap 的 plotrix
包:
library("plotrix")
gap.barplot(
dat$value,
xlab = "Sample",
ylim = c(0, 25),
xtics = 1:18,
xaxlab = FALSE,
ytics = c(5, 10, 15, 20, 45, 50, 55),
gap = c(10, 40),
col = dat$color
)
text(x = 1:18,
y = par("usr")[3] - 1.5,
labels = dat$label,
xpd = NA,
srt = 30,
cex = .75)
plotrix::axis.break(
axis = 2,
breakpos = 10.4,
breakcol = "black",
style = "slash"
)
plotrix::axis.break(
axis = 4,
breakpos = 10.4,
breakcol = "black",
style = "slash"
)
是那个样子:
但是发现 gap.barplot()
不接受 border
和 space
参数...这样分组就没法画图了。虽然 help 文档是说 ...
参数直接传给 barplot()
,但是不知道为什么我加上 space
又不行。
然后我就求助了(可能)更强大的 ggplot2
library("ggplot2")
library("ggprism")
p <- ggplot(data = dat,
aes(x = label, y = value,
fill = group)) +
geom_bar(position="dodge", stat="identity",
width = .75, size = 1.5,
# color = "black",
show.legend = FALSE) +
geom_bar(stat = "identity", position = "dodge",
# show.legend = FALSE,
width = .75) +
scale_fill_grey("Sample", start = .9, end = .1,
labels = c("A", "B", "C", "D")
) +
ggprism::theme_prism(base_size = 14, base_family = "Arial") + # 科研作图,选择了常用的 prism 主题
scale_y_continuous(expand = expansion(mult = c(0, .1))) +
theme(legend.position = c(.2, .8), legend.direction = "vertical") +
theme(axis.text.x = element_text(angle = 45, vjust = .75, hjust = .65)) +
NULL
p
还行:
下面来加 gap 吧。 Google 到了 gg.gap:
library("gg.gap")
gg.gap(p, segments = list(c(10, 40)), ylim = c(0, 60))
额......
然后排除了一下
ggprism::theme_prism(base_size = 14, base_family = "Arial")
和
scale_y_continuous(expand = expansion(mult = c(0, .1))) +
都和 gg.gap()
有点冲突,移除之后能得到类似想要的结果:
但是这个主题现在没法改了,gg.gap()
似乎和 theme_xxx_()
有冲突....
知道坛里作图高手多多,希望大家提点意见,我知道我的代码写得很烂,冗余度极高,大家尽管骂我。