用不同的x-y轴绘制多个矩阵 [英] Plot multiple matrices in facets with different x-y axis
问题描述
我从一系列在线论坛收集数据,并且想要使用ggplot和方面(每个论坛的一个方面)绘制矩阵,表示用户A回复用户B的次数。
以下是加载玩具示例的代码:
library(ggplot2)
library(dplyr)
df.edges< - data.frame(from = c('forum1_user1','forum1_user1',
'forum1_user2','forum1_user2',
'forum2_user1','forum2_user1',
'forum2_user2','forum2_user2',
'forum3_user1','forum3_user1',
'forum3_user2','forum3_user2'),
to = c('forum1_user1','forum1_user2',
'forum1_user1','forum1_user2',
'forum2_user1','forum 2_user2',
'forum2_user1','forum2_user2',
'forum3_user1','forum3_user2',
'forum3_user1','forum3_user2'),
weight = 1:12,
timestamp = 1:12,
subforum = c('forum1','forum1','forum1','forum1',
'forum2','forum2','forum2', 'forum2',
'forum3','forum3','forum3','forum3'))
我试试这个:
#排序以备后用于scale_discrete
df.edges< - df (时间戳)
gg < - ggplot(df.edges,aes(x = from,y = to,fill = weight))+
geom_raster()+ coord_fixed()+
facet_grid(。 〜subforum,scales ='fixed')+
scale_x_discrete(from,aes(limits = from))+
scale_y_discrete(to,aes(limits = from))+
theme_bw()+
theme(axis.line = element_blank(),
axis.text.x = element_text(angle = 90,hjust = 1,size = 8),
axis.text .y = element_text(hjust = 1,size = 10),
axis.ticks = element_blank(),
strip.background = element_rect(fill ='white'),
aspect.ratio = 1)+
ggtitle(交互矩阵)+ xlab('from')+ ylab('to')
print(gg)
这就是:
p>
如果我设置方面比例 scale ='free'
:
然而,我希望每个方面都可以只显示属于该论坛的用户。
有什么想法?
您可以为 首先,创建单独的图并存储在列表中。我们添加 subforum
的每个级别创建一个单独的图,然后使用 grid.arrange $ c将它们放在一起
$ p $ library(gridExtra)
库(网格)
scale_fill_continuous(limits = range(df.edges $ weight))
以确保三个图中的填充梯度一致:
$ b $ (df.edges,df.edges $ subforum),function = to,fill = weight))+
geom_raster()+ coord_fixed()+
facet_grid(。〜subforum,scales ='fixed')+
scale_x_discrete(from,aes (限制= from))+
scale_y_discrete(to,aes(limits = from))+
scale_fill_continuous(limits = range(df.edges $ weight))+
theme_bw()+
theme(axis.line = element_blank(),
axis.text.x = element_text(angle = 90,hjust = 1,size = 8),
axis.text.y = element_text (hjust = 1,size = 10),
axis.ticks = element_blank(),
strip.background = element_rect(fill ='white'),
aspect.ratio = 1)+
xlab('from')+ ylab('to')
})
提取图例,因为我们只需要一个图例,而不是每个图的单独图例:
#提取图例
#https://github.com/hadley/ggplot2/wiki/Share的函数-a-legend-between-two-ggplot2-graphs
g_legend< -function(a.gplot){
tmp< - ggplot_gtable(ggplot_build(a.gplot))
leg< - (sapply(tmp $ grobs,function(x)x $ name)==guide-box)
legend< - tmp $ grobs [[leg]]
return(legend)}
#将图例提取为grob
leg = g_legend(pl [[1]])
用图例和标题排列图:
grid.arrange(
textGrob(
arrangeGrob(
arrangeGrob(grobs = lapply(pl,function(x)x + guides(fill = FALSE)),ncol = 3),
leg, ncol = 2,widths = c(10,1)
),
heights = c(1,20)
)
I collected the data from a set of online forums and wanted to plot, using ggplot and facets (one facet per forum), the matrix that represent how many times user A replied to user B.
Here is the code to load a toy example:
library(ggplot2)
library(dplyr)
df.edges <- data.frame(from = c('forum1_user1', 'forum1_user1',
'forum1_user2', 'forum1_user2',
'forum2_user1', 'forum2_user1',
'forum2_user2', 'forum2_user2',
'forum3_user1', 'forum3_user1',
'forum3_user2', 'forum3_user2'),
to = c('forum1_user1', 'forum1_user2',
'forum1_user1', 'forum1_user2',
'forum2_user1', 'forum2_user2',
'forum2_user1', 'forum2_user2',
'forum3_user1', 'forum3_user2',
'forum3_user1', 'forum3_user2'),
weight = 1:12,
timestamp = 1:12,
subforum = c('forum1', 'forum1', 'forum1', 'forum1',
'forum2', 'forum2', 'forum2', 'forum2',
'forum3', 'forum3', 'forum3', 'forum3'))
I try this:
# Sort for later use in scale_discrete
df.edges <- df.edges %>% arrange(timestamp)
gg <- ggplot(df.edges, aes(x = from, y = to, fill = weight)) +
geom_raster() + coord_fixed() +
facet_grid(. ~subforum, scales='fixed') +
scale_x_discrete("from", aes(limits = from))+
scale_y_discrete("to", aes(limits = from)) +
theme_bw() +
theme(axis.line = element_blank(),
axis.text.x = element_text(angle = 90, hjust=1, size=8),
axis.text.y = element_text(hjust=1, size=10),
axis.ticks = element_blank(),
strip.background = element_rect(fill = 'white'),
aspect.ratio = 1) +
ggtitle("Matrix of interactions") + xlab('from') + ylab('to')
print(gg)
which gives this:
And if I set the facet scale scale='free'
:
However, I want each facet to show only those users belonging to that forum. The matrices should be completely filled with 4 cells in each one.
Any idea?
You could create a separate plot for each level of subforum
and then lay them out together using grid.arrange
:
library(gridExtra)
library(grid)
First, create the separate plots and store in a list. We add scale_fill_continuous(limits=range(df.edges$weight))
to ensure a consistent fill gradient across the three plots:
pl = lapply(split(df.edges, df.edges$subforum), function(df) {
ggplot(df, aes(x = from, y = to, fill = weight)) +
geom_raster() + coord_fixed() +
facet_grid(. ~subforum, scales='fixed') +
scale_x_discrete("from", aes(limits = from))+
scale_y_discrete("to", aes(limits = from)) +
scale_fill_continuous(limits=range(df.edges$weight)) +
theme_bw() +
theme(axis.line = element_blank(),
axis.text.x = element_text(angle = 90, hjust=1, size=8),
axis.text.y = element_text(hjust=1, size=10),
axis.ticks = element_blank(),
strip.background = element_rect(fill = 'white'),
aspect.ratio = 1) +
xlab('from') + ylab('to')
})
Extract the legend, as we want only one legend, rather than a separate legend for each plot:
# Function to extract legend
#https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend) }
# Extract legend as a grob
leg = g_legend(pl[[1]])
Arrange the plots with legend and title:
grid.arrange(
textGrob("Matrix of Interactions"),
arrangeGrob(
arrangeGrob(grobs=lapply(pl, function(x) x + guides(fill=FALSE)), ncol=3),
leg, ncol=2, widths=c(10,1)
),
heights=c(1,20)
)
这篇关于用不同的x-y轴绘制多个矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!