截断图
你终于会做截断图了,可审稿人说不让做,怎么破
https://www.sohu.com/a/166996029_170798
数据可视化真是一个蛮头疼的问题,你不停地寻找最恰当的表达方法,让好不容易做出来的实验显得更惊艳。但有时候你踏破铁鞋终于找到了,做好了,写完文章投出去了,突然审稿人提了一些出乎意料的意见,这时头疼就变成了蛋疼。
比如,有时候我们会遇到一个很崎岖的数据集,有某组特大,有某组特小,于是你做出来的就是这样的:
正确是正确,但就是有点别扭。如果我想让B、C两组显得更清楚些,那么截断图是一个常规选则,像这样:
Y轴断成了两截,一截是0~15,一截是60~80,这样我就可以看到那两组数值较小的数据的变化。如果B、C两组本来没多大意义,那不看也罢。但万一是两组药物把某个指标从A的高值降到这么低,我就很想展示它们之间的差别,现在C组的离散程度就比B组小。
这样操作起来也容易,就在Graphpad里进行。
Graphpad中截断图的做法
做好上面那张原图之后,双击Y轴,在弹出的对话框中选择Left Y axis选项卡。接下来第一行就是Gaps and Direction,点开下拉框,根据情况选2截或3截,本例中就选2截,图标方向随意。
此时下方多一了行,下拉框有Bottom和Top,分别选中后可对上下两截Y轴进行设置,如图将下半截设成0~15。同理选择Top后将上半截设成60~80。
左边的百分比则是上下两截在视觉上各占Y轴全长的比例,只要设一个,另一个会自动根据总和100%来变化。这几个数值可根据实际情况调整,直到看起来舒服,就得到第2张Y轴分截的图。
其他细节如字体字号啥的也在这里设置好。然后兴冲冲地把文章投出去……
可这点功夫打不过人家啊!
一般情况下也不会有什么问题吧,这个做法也比较常见。直到有一天,我发现R语言常用的做图包ggplot2不能这么做。咦?这不是传说中功能完善、做图严谨又漂亮的包吗?居然这么水?!
细查之下,发现不是水,而是开发这个包的小哥哥不!愿!意!我有技术我任性!
你问他为啥,他是这么说的:
https://groups.google.com/forum/#!topic/ggplot2/jSrL_FnS8kc
对,不能做,因为本宝宝不喜欢。这样会对数据造成视觉上的扭曲。最好做两张图,一张是所有数据,一张只有数值小的,这样你就能看到大值如何碾压小值。
这可一语惊醒梦中人。数据可视化,追求的不仅是视觉上看着舒服甚至“酷炫”,其第一要义当然是数据的严谨呀!
不过,他说两张图?会不会太占空间了?
看看上面的原图,右边两组矮下去的部分留出了一大片空白,能不能把那张小数值的塞进去?
Graphpad中嵌合图的做法
还是那张原图。做好以后,New→New Graph of Existing Data,新建一张图。然后在弹出的对话框中选择好相应的图形,勾选Plot selected data sets only之后,点Select选择两组小数值。
然后设置图片外观啥的我就不说了,直接看排版。继续新建,New Layout,在弹出的对话框中可以看到嵌入式,就它了~
下边选择自动填充,Duang!
再拖动调整位置大小啥的,齐活了。
关于数值跨度太大的问题,在数据类的社区中也有不少讨论。除了做嵌合图外,也有人建议将Y轴做对数处理,这在Graphpad中也可以实现,就是双击Y轴后,在刚才选择分截那里的右边的下拉框里就有。但也有人认为,取对数可能仅有数学意义而不一定有实际意义。
另外也有人建议直接上表格,贴数字,简单粗暴。
至于有没有什么约定或规范说必须选哪种表达形式,貌似暂时没听说,只不过既然有这种观点存在,总是要留一手的才放心呐。还是那句老话,先仔细看期刊有没有特殊要求。
R 语言嵌合图的做法
喜欢R语言的同学可以用ggplot2包。这个包的做图思路比较清奇,是图层叠加方式。不过今天的重点不在画图,就简单讲一下吧。至于重点嵌套,其实只有最后三行代码。
# 载入需要的包
library(plyr)
library(Rmisc)
library(ggplot2)
library(grid)
#构建数据
A <- rnorm(10,75,10)
B <- rnorm(10,12,5)
C <- rnorm(10,4,3)
Group <- c(rep('A',10),rep('B',10),rep('C',10))
Value <- c(A,B,C)
D <- data.frame(Group,Value)
# 求标准差,后面画误差线要用
DSe <- summarySE(D,measurevar = 'Value',groupvars = 'Group')
# 把组别转化成因子
D$Group <- factor(D$Group)
# 挑三个颜色
C <- c('#55a0fb','#ff8080','#c5944e')
#画大图
p1 <- ggplot(DSe,aes(Group,Value)) + # 定义环境
geom_bar(aes(Group,Value,fill = Group),stat = 'identity',width = 0.5,show.legend = T) + # 画条形图
geom_errorbar(aes(ymin = Value-se, ymax = Value+se),width = .2) + #加误差线
scale_fill_manual(values = C) + # 配色
labs(x='修改X轴为Group',y='修改Y轴为Value',title = '添加标题')+
theme(axis.title = element_text(face = 'bold'),# 定义主题,如坐标轴标题样式、背景等
axis.text = element_text(face = 'bold',colour = 'black'),
plot.title = element_text(face = 'bold',colour = 'black',hjust = 0.5,size = 20),
legend.background = element_rect(I(0),linetype = 1))
p1 # 看下效果
# 选择小数据集、小颜色集
DSe2 <- DSe[2:3,]
C2 <- C[2:3]
# 画小图,基本和大图一样,后面要背景透明、显示坐标轴
p2 <- ggplot(DSe2,aes(Group,Value)) +
geom_bar(aes(Group,Value,fill = Group), stat = 'identity',width = 0.5) +
geom_errorbar(aes(ymin = Value-se, ymax = Value+se),width = .2)+
scale_fill_manual(values = C2)+
guides(fill = F)+
theme(axis.text = element_text(face = 'bold',colour = 'black'),
axis.title.y = element_blank(),
axis.line = element_line(linetype = 1,colour = 'black'), # 显示坐标轴
plot.background = element_rect(I(0),linetype = 0), # 背景透明
panel.background = element_rect(I(0)),
panel.grid.major = element_line(colour = NA),
panel.grid.minor = element_line(colour = NA))
p2
# 嵌套
sub <- viewport(width = 0.5,height = 0.4,x = 0.64,y = 0.6) # 配置环境。前两个是子图的大小比例,后两个是位置,可自行调整到好看为止。
p1 # 上大图
print(p2,vp = sub) # 加小图
就酱。如果你真的想做截断坐标轴的图,听说plotrix包可以,详见参考资料3。
参考资料:
1. https://groups.google.com/forum/#!topic/ggplot2/jSrL_FnS8kc
2. https://stats.stackexchange.com/questions/1764/what-are-alternatives-to-broken-axes
3. https://stackoverflow.com/questions/19612348/break-x-axis-in-r