ggfree:试图让你摆脱ggplot2
推特上被人AT了一下,他用base plot把我用ggtree画的一张图给重复出来了:
然后他还画了一张圈图,这些当然用ggtree都是轻而易举的事情。
ggfree:一个目标很大的包
我们看这个描述,就知道它的目标有多大!想让你好像ggplot2一样愉快地使用base plot。这个我不得不说我干过一个相反的,《用par设置ggplot2参数?这个可以有!》,不过只是proof of concept的尝试而已,我并没有让theme的所有(或者大部分)参数可以通过par
去设置。
这个ggfree
包虽然口号很大,不过还处于活跃的开发之中,最终能不能实现口号我们以后再看看,现而今,实现的并不多,了解一个包,从看NAMESPACE
开始:
从中我们可以看到,为什么画进化树这么方便,原来作者专门针对phyloLayout
的image
, lines
, points
和text
的方法,points
打点,lines
画线,text
打文本,image
画热图,你用的这些都被重新定义了,所以比如说points
在进化树上把所有的tips都给打点了,text
可以把tip labels给加上去了。由于你传入的phyloLayout
有相应的信息,所以能够正确打出来。比如points
方法是这样定义的:
points.phyloLayout <- function(obj, ...) {
points(x=obj$nodes$x, y=obj$nodes$y, ...)
}
所以嘛,要和ggtree比,还差远着,因为你实现的方法还太少了。再者假如你要变量映射,比如上颜色,你就得在外面处理数据,准备好一个color的向量,和obj里的nodes一一对应。想想也心累。
徒有其表的主题
从上面看,现在的目标似乎只是针对进化树啊,不过作者说了,要让base plot像ggplot2一样好用。不过就这一点而已,它做的似乎只是写了一个函数,可以给画图加网格线:
require(ggfree)
plot(NA, xlim=range(faithful$eruptions), ylim=range(faithful$waiting),
xlab='Duration of eruption (mins)', ylab='Waiting time (mins)')
add.grid() # <-- a ggfree function!
points(faithful$eruptions, faithful$waiting, pch=21, bg='white')
还可以改一些参数:
plot(NA, xlim=range(faithful$eruptions), ylim=range(faithful$waiting),
xlab='Duration of eruption (mins)', ylab='Waiting time (mins)')
# now with non-default arguments!
add.grid(mode='x', bg.col='seashell2', lwd.minor=0)
points(faithful$eruptions, faithful$waiting, pch=21, bg='white')
就这一点而已,我觉得《prettyB:美化base plot》包做得更好。
当然论改细节,我们只用PPT:
画图函数
除此之外,作者实现了一些画图函数,这我觉得是这个包唯一的优点,但对于像ggplot2
一样好用,似乎也没什么关系。所以我感觉作者的思路其实是,现在很多ggplot2的扩展,好多好看的图,似乎都只有ggplot2
有现成的,base plot
都没有现成的函数,对于惯用base plot的伙伴们来说,太郁闷了。不如也来造一些函数,让base plot的人也一键生成,大家又可以愉快地使用base plot了。我想大概应该是这样,那就让我们看看都可以画些什么,并且期待随着不断开发,可以画出更多的图吧。
Slopegraphs
require(ggfree)
co2.emissions
#> per.cap.2000 per.cap.2010
#> Netherland Antilles 8.52 5.99
#> Bahrain 7.97 6.33
#> Kuwait 7.53 7.99
#> Aruba 7.19 6.73
#> United States Of America 5.42 4.69
#> Luxembourg 5.16 5.89
#> Trinidad And Tobago 5.03 9.84
#> Canada 4.75 4.27
#> Australia 4.69 4.81
#> Faeroe Islands 4.10 3.53
slopegraph(co2.emissions, colorize=T)
Ringplots
# prepare colour palettes
require(RColorBrewer)
#> Loading required package: RColorBrewer
pal1 <- brewer.pal(5, 'Blues')
pal2 <- brewer.pal(5, 'Reds')
# calling ringplot without x, y args makes new plot
ringplot(VADeaths[,1], r0=0.4, r1=0.65, col=pal1)
# called with x, y args adds ring to existing plot;
# setting use.names to TRUE adds labels
ringplot(VADeaths[,2], x=0, y=0, r0=0.65, r1=0.9, col=pal2,
use.names=T, offset=0.05, srt=90)
# write a label in the middle
text(x=0, y=0, adj=0.5, label='Death rates\nin Virginia\n(1940)', cex=0.8)
Polar area charts
pal <- brewer.pal(3, 'Pastel2')
# load the Florence Nightingale data set (note, need to install HistData)
require(HistData)
#> Loading required package: HistData
ng <- subset(Nightingale, Year==1855, c('Wounds.rate', 'Other.rate', 'Disease.rate'))
row.names(ng) <- Nightingale$Month[Nightingale$Year==1855]
par(mar=rep(0,4))
# the actual plotting function
polarplot(as.matrix(ng), x=0.2, y=0.3, theta=1.1*pi, col=pal,
use.names=T)
# add some nice labels
title('Causes of mortality in British army, Crimean War (1855)',
font.main=1, family='Palatino', line=-3)
legend(x=-0.8, y=0.6, legend=c('Wounds', 'Other', 'Disease'), bty='n',
fill=pal, cex=0.9)
Ridgeplots
par(mar=c(5,5,1,1))
pal <- add.alpha(brewer.pal(3, 'Set1'), 0.5)
ridgeplot(split(iris$Sepal.Length, iris$Species), step=0.4, col='white',
fill=pal, lwd=2, xlab='Sepal length', cex.lab=1.2)
往期精彩