用不同的x-y轴绘制多个矩阵 [英] Plot multiple matrices in facets with different x-y axis

查看:179
本文介绍了用不同的x-y轴绘制多个矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从一系列在线论坛收集数据,并且想要使用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
$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆