查看原文
其他

ggfree:试图让你摆脱ggplot2

Y叔叔 YuLabSMU 2022-09-24

推特上被人AT了一下,他用base plot把我用ggtree画的一张图给重复出来了:

然后他还画了一张圈图,这些当然用ggtree都是轻而易举的事情。

ggfree:一个目标很大的包

我们看这个描述,就知道它的目标有多大!想让你好像ggplot2一样愉快地使用base plot。这个我不得不说我干过一个相反的,《用par设置ggplot2参数?这个可以有!》,不过只是proof of concept的尝试而已,我并没有让theme的所有(或者大部分)参数可以通过par去设置。

这个ggfree包虽然口号很大,不过还处于活跃的开发之中,最终能不能实现口号我们以后再看看,现而今,实现的并不多,了解一个包,从看NAMESPACE开始:

从中我们可以看到,为什么画进化树这么方便,原来作者专门针对phyloLayoutimage, lines, pointstext的方法,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)

往期精彩

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存