使用 ggplot2 再现格子树状图

发布于 2024-11-20 00:37:44 字数 914 浏览 2 评论 0原文

这可以用 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))))

在此处输入图像描述

Is this possible to reproduce this lattice plot with 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))))

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

没有伤那来痛 2024-11-27 00:37:45

正如本所说,一切皆有可能。一些支持树状图的工作已经完成。 Andrie de Vries 提出了一种强化方法树对象。然而,生成的图形并不像您所看到的那样漂亮。

瓷砖很容易做。对于树状图,我将检查plot.dendrogram(使用getAnywhere)以查看如何计算线段的坐标。提取这些坐标并使用 geom_segment 绘制树状图。然后使用视口将图块和树状图一起绘制。抱歉,我无法举例,这需要大量工作,而且为时已晚。

我希望这有帮助

干杯

dendrogram

As Ben says, everything is possible. Some work to support dendrograms has been done. Andrie de Vries has made a fortify method of tree objects. However, the resulting graphic is not pretty as you can see.

The tile would be easy to do. For the dendrogram I would inspect plot.dendrogram (using getAnywhere) to see how the coordinates for the segments are calculated. Extract those coordinates and use geom_segment to plot the dendrogram. Then use viewports to plot the tiles and the dendrogram together. Sorry I can't give a example, it's a lot of work and it's too late.

I hope this helps

Cheers

dendrogram

我一直都在从未离去 2024-11-27 00:37:45

疑。我在 ggplot2 索引中没有看到任何建议支持树状图的函数,当这位博主将 Sarkar 的 Lattice 书中插图的一组翻译放在一起时,他无法获得 ggplot 树状图图例:

http://learnr.wordpress.com/2009/08/10/ggplot2-version-of-figures-in-lattice-multivariate-data-visualization-with-r-part-9/

Doubtful. I do not see any functions in the Index for ggplot2 that would suggest support for dendrograms, and when this blogger put together a set of translations of the illustrations in Sarkar's Lattice book, he was unable to get a ggplot dendrogram legend:

http://learnr.wordpress.com/2009/08/10/ggplot2-version-of-figures-in-lattice-multivariate-data-visualization-with-r-part-9/

优雅的叶子 2024-11-27 00:37:45

如果您想使用 ggplot2 来创建带有树状图的热图。我创建了一个名为 ggalign 的包,您可以使用它来创建与 一样复杂的热图Complexheatmap:

具体来说,它可以将热图拆分为分面组,并确保即使在分面之后树状图也能正确对齐。

mat <- matrix(rnorm(81), nrow = 9)
rownames(mat) <- paste0("row", seq_len(nrow(mat)))
colnames(mat) <- paste0("column", seq_len(ncol(mat)))
ggheatmap(mat) +
  scale_fill_viridis_c() +
  hmanno("t") +
  align_dendro(aes(color = branch), k = 3L) +
  labs(color = "top-branch") +
  ggalign(aes(y = value), data = rowSums) +
  geom_bar(stat = "identity", aes(fill = factor(.panel))) +
  scale_fill_brewer(name = NULL, palette = "Dark2") +
  hmanno("l") +
  ggalign(aes(x = value), data = rowSums, size = 0.5) +
  geom_bar(
    aes(y = .y, fill = factor(.y)),
    stat = "identity",
    orientation = "y"
  ) +
  scale_x_reverse() +
  align_dendro(aes(color = branch),
    size = unit(1, "null"),
    k = 4L
  ) +
  labs(color = "left-branch") +
  scale_x_reverse()

创建于 2024 年 7 月 17 日,使用 reprex v2.1.0
~
输入图片此处描述

可以从 ComplexHeatmap 创建更复杂的热图示例:

expr <- readRDS(system.file(package = "ComplexHeatmap", "extdata", "gene_expression.rds"))
mat <- as.matrix(expr[, grep("cell", colnames(expr))])
base_mean <- rowMeans(mat)
mat_scaled <- t(apply(mat, 1, scale))
type <- gsub("s\\d+_", "", colnames(mat))

ggstack(data = mat_scaled) +
  # group stack rows into 5 groups
  align_kmeans(centers = 5L) +
  # add a block plot for each group in the stack
  ggpanel(size = unit(1, "cm")) +
  geom_tile(aes(x = 1, fill = factor(.panel))) +
  scale_fill_brewer(palette = "Dark2", name = "Kmeans group") +
  scale_x_continuous(breaks = NULL, name = NULL) +
  # add a heatmap plot in the stack
  ggheatmap() +
  hmanno(free_spaces = "l") +
  scale_y_continuous(breaks = NULL) +
  scale_fill_viridis_c() +
  # add dendrogram for this heatmap
  hmanno("t") +
  align_dendro() +
  # add a block for the heatmap column
  ggalign(data = type, size = unit(1, "cm")) +
  geom_tile(aes(y = 1, fill = factor(value))) +
  scale_y_continuous(breaks = NULL, name = NULL) +
  scale_fill_brewer(palette = "Set1", name = "type") +
  # reset the heatmap active context into the heatmap body
  hmanno() +
  # add another heatmap in the stack
  ggheatmap(base_mean) +
  # set the heatmap body width
  hmanno(width = unit(2, "cm")) +
  scale_y_continuous(breaks = NULL) +
  scale_x_continuous(name = "base mean", breaks = FALSE) +
  scale_fill_gradientn(colours = c("#2600D1FF", "white", "#EE3F3FFF")) +
  # set the active context of the heatmap to the top
  # and set the size of the top stack
  hmanno("t", size = unit(4, "cm")) +
  # add box plot in the heatmap top
  ggalign() +
  geom_boxplot(aes(y = value, fill = factor(.extra_panel))) +
  scale_x_continuous(expand = expansion(), breaks = NULL) +
  scale_fill_brewer(palette = "Dark2", guide = "none") +
  theme(axis.title.y = element_blank()) +
  # we move into the stack layout
  stack_active() +
  # add a point plot
  ggalign(data = expr$length, size = unit(2, "cm")) +
  geom_point(aes(x = value)) +
  labs(x = "length") +
  theme(
    panel.border = element_rect(fill = NA),
    axis.text.x = element_text(angle = -60, hjust = 0)
  ) +
  # add another heatmap
  ggheatmap(expr$type) +
  # set the heatmap body width, and remove the spaces in the y-axis
  hmanno(width = unit(2, "cm"), free_spaces = "y") +
  scale_fill_brewer(palette = "Set3", name = "gene type") +
  scale_x_continuous(breaks = NULL, name = "gene type") +
  # add barplot in the top annotation
  hmanno("t") +
  ggalign(limits = FALSE) +
  geom_bar(
    aes(.extra_panel, fill = factor(value)),
    position = position_fill()
  ) +
  scale_x_discrete() +
  scale_y_continuous(expand = expansion()) +
  scale_fill_brewer(palette = "Set3", name = "gene type", guide = "none") &
  theme(plot.margin = margin())

在此处输入图像描述

If you want to use ggplot2 to create a heatmap plot with dendrogram. I have created a package named ggalign, you can use it to create a heatmap as complex as Complexheatmap:

Specifically, it can split the heatmap into facet groups and ensure the proper alignment of the dendrogram even after faceting.

mat <- matrix(rnorm(81), nrow = 9)
rownames(mat) <- paste0("row", seq_len(nrow(mat)))
colnames(mat) <- paste0("column", seq_len(ncol(mat)))
ggheatmap(mat) +
  scale_fill_viridis_c() +
  hmanno("t") +
  align_dendro(aes(color = branch), k = 3L) +
  labs(color = "top-branch") +
  ggalign(aes(y = value), data = rowSums) +
  geom_bar(stat = "identity", aes(fill = factor(.panel))) +
  scale_fill_brewer(name = NULL, palette = "Dark2") +
  hmanno("l") +
  ggalign(aes(x = value), data = rowSums, size = 0.5) +
  geom_bar(
    aes(y = .y, fill = factor(.y)),
    stat = "identity",
    orientation = "y"
  ) +
  scale_x_reverse() +
  align_dendro(aes(color = branch),
    size = unit(1, "null"),
    k = 4L
  ) +
  labs(color = "left-branch") +
  scale_x_reverse()

Created on 2024-07-17 with reprex v2.1.0
~
enter image description here

A more complex heatmap example from the ComplexHeatmap can be created:

expr <- readRDS(system.file(package = "ComplexHeatmap", "extdata", "gene_expression.rds"))
mat <- as.matrix(expr[, grep("cell", colnames(expr))])
base_mean <- rowMeans(mat)
mat_scaled <- t(apply(mat, 1, scale))
type <- gsub("s\\d+_", "", colnames(mat))

ggstack(data = mat_scaled) +
  # group stack rows into 5 groups
  align_kmeans(centers = 5L) +
  # add a block plot for each group in the stack
  ggpanel(size = unit(1, "cm")) +
  geom_tile(aes(x = 1, fill = factor(.panel))) +
  scale_fill_brewer(palette = "Dark2", name = "Kmeans group") +
  scale_x_continuous(breaks = NULL, name = NULL) +
  # add a heatmap plot in the stack
  ggheatmap() +
  hmanno(free_spaces = "l") +
  scale_y_continuous(breaks = NULL) +
  scale_fill_viridis_c() +
  # add dendrogram for this heatmap
  hmanno("t") +
  align_dendro() +
  # add a block for the heatmap column
  ggalign(data = type, size = unit(1, "cm")) +
  geom_tile(aes(y = 1, fill = factor(value))) +
  scale_y_continuous(breaks = NULL, name = NULL) +
  scale_fill_brewer(palette = "Set1", name = "type") +
  # reset the heatmap active context into the heatmap body
  hmanno() +
  # add another heatmap in the stack
  ggheatmap(base_mean) +
  # set the heatmap body width
  hmanno(width = unit(2, "cm")) +
  scale_y_continuous(breaks = NULL) +
  scale_x_continuous(name = "base mean", breaks = FALSE) +
  scale_fill_gradientn(colours = c("#2600D1FF", "white", "#EE3F3FFF")) +
  # set the active context of the heatmap to the top
  # and set the size of the top stack
  hmanno("t", size = unit(4, "cm")) +
  # add box plot in the heatmap top
  ggalign() +
  geom_boxplot(aes(y = value, fill = factor(.extra_panel))) +
  scale_x_continuous(expand = expansion(), breaks = NULL) +
  scale_fill_brewer(palette = "Dark2", guide = "none") +
  theme(axis.title.y = element_blank()) +
  # we move into the stack layout
  stack_active() +
  # add a point plot
  ggalign(data = expr$length, size = unit(2, "cm")) +
  geom_point(aes(x = value)) +
  labs(x = "length") +
  theme(
    panel.border = element_rect(fill = NA),
    axis.text.x = element_text(angle = -60, hjust = 0)
  ) +
  # add another heatmap
  ggheatmap(expr$type) +
  # set the heatmap body width, and remove the spaces in the y-axis
  hmanno(width = unit(2, "cm"), free_spaces = "y") +
  scale_fill_brewer(palette = "Set3", name = "gene type") +
  scale_x_continuous(breaks = NULL, name = "gene type") +
  # add barplot in the top annotation
  hmanno("t") +
  ggalign(limits = FALSE) +
  geom_bar(
    aes(.extra_panel, fill = factor(value)),
    position = position_fill()
  ) +
  scale_x_discrete() +
  scale_y_continuous(expand = expansion()) +
  scale_fill_brewer(palette = "Set3", name = "gene type", guide = "none") &
  theme(plot.margin = margin())

enter image description here

泼猴你往哪里跑 2024-11-27 00:37:44

编辑

从 2011 年 8 月 8 日起,ggdendro 软件包可在 CRAN
另请注意,树状图提取函数现在称为 dendro_data 而不是 cluster_data 是的


,确实如此。但目前您必须克服一些困难:

  1. 安装 ggdendro 包(可从 CRAN 获得)。该包将从多种类型的聚类方法(包括 Hclust 和树状图)中提取聚类信息,其明确目的是在 ggplot 中进行绘图。
  2. 使用网格图形创建视口并对齐三个不同的绘图。

在此处输入图像描述

代码:

首先加载库并设置 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))

EDIT

From 8 August 2011 the ggdendro package is available on CRAN
Note also that the dendrogram extraction function is now called dendro_data instead of cluster_data


Yes, it is. But for the time being you will have to jump through a few hoops:

  1. Install the ggdendro package (available from CRAN). This package will extract the cluster information from several types of cluster methods (including Hclust and dendrogram) with the express purpose of plotting in ggplot.
  2. Use grid graphics to create viewports and align three different plots.

enter image description here

The code:

First load the libraries and set up the data for 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")

Extract dendrogram data and create the plots

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

Use grid graphics and some manual alignment to position the three plots on the page

### 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))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文