用 ggplot2 再现晶格树状图
Posted
技术标签:
【中文标题】用 ggplot2 再现晶格树状图【英文标题】:Reproducing lattice dendrogram graph with ggplot2 【发布时间】:2011-10-04 03:05:34 【问题描述】:这可以用 ggplot2 重现这个格子图吗?
library(latticeExtra)
data(mtcars)
x <- t(as.matrix(scale(mtcars)))
dd.row <- as.dendrogram(hclust(dist(x)))
row.ord <- order.dendrogram(dd.row)
dd.col <- as.dendrogram(hclust(dist(t(x))))
col.ord <- order.dendrogram(dd.col)
library(lattice)
levelplot(x[row.ord, col.ord],
aspect = "fill",
scales = list(x = list(rot = 90)),
colorkey = list(space = "left"),
legend =
list(right =
list(fun = dendrogramGrob,
args =
list(x = dd.col, ord = col.ord,
side = "right",
size = 10)),
top =
list(fun = dendrogramGrob,
args =
list(x = dd.row,
side = "top",
size = 10))))
【问题讨论】:
到目前为止你有没有尝试过? 我的猜测:可能(一切都是可能的),并不容易。有人在ggplot2中做了一些系统发育,可能还有其他绘制树状图的代码。你可能必须做这些碎片并将它们与grid
图形放在一起......实际上,既然你已经有了dendrogramGrobs
,你也许可以用geom_tile
制作中间部分,然后将它们放在一起具有来自ggExtra
和gridExtra
的函数...
@BenBolker 正如你所说,一切皆有可能。在这种情况下,它变得更容易了。看我的回答:***.com/questions/6673162/…
【参考方案1】:
这些链接为 ggplot2 中带有树状图的热图提供了解决方案:
https://gist.github.com/chr1swallace/4672065
https://github.com/chr1swallace/random-functions/blob/master/R/ggplot-heatmap.R
还有这个:
Align ggplot2 plots vertically
【讨论】:
【参考方案2】:编辑
从 2011 年 8 月 8 日起,ggdendro
软件包可在 CRAN 上获得
另请注意,树状图提取函数现在称为 dendro_data
而不是 cluster_data
是的,是的。但暂时你将不得不跳过几个圈:
-
安装
ggdendro
包(可从CRAN 获得)。这个包将从几种类型的集群方法(包括Hclust
和dendrogram
)中提取集群信息,目的是在ggplot
中绘图。
使用网格图形创建视口并对齐三个不同的绘图。
代码:
首先加载库并为ggplot设置数据:
library(ggplot2)
library(reshape2)
library(ggdendro)
data(mtcars)
x <- as.matrix(scale(mtcars))
dd.col <- as.dendrogram(hclust(dist(x)))
col.ord <- order.dendrogram(dd.col)
dd.row <- as.dendrogram(hclust(dist(t(x))))
row.ord <- order.dendrogram(dd.row)
xx <- scale(mtcars)[col.ord, row.ord]
xx_names <- attr(xx, "dimnames")
df <- as.data.frame(xx)
colnames(df) <- xx_names[[2]]
df$car <- xx_names[[1]]
df$car <- with(df, factor(car, levels=car, ordered=TRUE))
mdf <- melt(df, id.vars="car")
提取树状图数据并创建图
ddata_x <- dendro_data(dd.row)
ddata_y <- dendro_data(dd.col)
### Set up a blank theme
theme_none <- theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.title.x = element_text(colour=NA),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.line = element_blank()
#axis.ticks.length = element_blank()
)
### Create plot components ###
# Heatmap
p1 <- ggplot(mdf, aes(x=variable, y=car)) +
geom_tile(aes(fill=value)) + scale_fill_gradient2()
# Dendrogram 1
p2 <- ggplot(segment(ddata_x)) +
geom_segment(aes(x=x, y=y, xend=xend, yend=yend)) +
theme_none + theme(axis.title.x=element_blank())
# Dendrogram 2
p3 <- ggplot(segment(ddata_y)) +
geom_segment(aes(x=x, y=y, xend=xend, yend=yend)) +
coord_flip() + theme_none
使用网格图形和一些手动对齐来定位页面上的三个图
### Draw graphic ###
grid.newpage()
print(p1, vp=viewport(0.8, 0.8, x=0.4, y=0.4))
print(p2, vp=viewport(0.52, 0.2, x=0.45, y=0.9))
print(p3, vp=viewport(0.2, 0.8, x=0.9, y=0.4))
【讨论】:
非常好。最好(1)将图例移到某个地方并(2)扩展 geom_tile() 使其充满整个面板(我认为这些都是可行的,在内部 #2 和带有ggExtra
技巧的 #1 。 ..)
@Andrie:这个 R 包什么时候可以安装?其实我想使用这个包,但不知道下载后如何构建它。谢谢
这太棒了!希望有这个功能!我想知道是否有办法让树状图大小与平铺图大小相匹配?手动调整视口大小和位置很繁琐,而且不能完美地工作,但应该可以从图中的信息中做到这一点:(***.com/questions/13867325/… 和 ***.com/questions/13294952/…)
@Lilith-Elina 感谢您确定该修复程序。我已经更新了答案以反映这一点,也符合ggplot2
的当前版本,即没有主题警告。
感谢您的更正。还需要加载 gridExtra 包。此外,我沿 x 轴的树状图未正确对齐。还有其他人得到类似的东西吗?【参考方案3】:
正如本所说,一切皆有可能。一些支持树状图的工作已经完成。 Andrie de Vries 制作了一个树对象的fortify 方法。但是,生成的图形并不像您看到的那样漂亮。
瓷砖很容易做。对于树状图,我会检查plot.dendrogram
(使用getAnywhere
)来查看段的坐标是如何计算的。提取这些坐标并使用 geom_segment 绘制树状图。然后使用视口将图块和树状图绘制在一起。抱歉,我不能举个例子,工作量很大,为时已晚。
希望对你有帮助
干杯
【讨论】:
+1 用于挖掘我很久很久以前写的代码。正如你所说,不漂亮......【参考方案4】:怀疑。我在 ggplot2 的索引中没有看到任何建议支持树状图的函数,当这位博主整理了 Sarkar 的 Lattice 书中插图的一组翻译时,他无法获得 ggplot 的树状图图例:
http://learnr.wordpress.com/2009/08/10/ggplot2-version-of-figures-in-lattice-multivariate-data-visualization-with-r-part-9/
【讨论】:
我认为有些人已经组合了一些解决方案,这些解决方案至少是一个很好的起点:请参阅here、here 并且可能this 也可能有用。 @DWin 永远不要说永远。看我的回答:***.com/questions/6673162/…以上是关于用 ggplot2 再现晶格树状图的主要内容,如果未能解决你的问题,请参考以下文章