如何绘制嵌套类别轴的图表? [英] How do I plot charts with nested categories axes?

查看:132
本文介绍了如何绘制嵌套类别轴的图表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在绘制既有类别又有子类别的数据(请参见下面的示例数据),并且想要将它们嵌套显示(这个示例是在Excel中创建的):

b
$ b



最好的I在R中提出的是用所需的名称创建一个新列,如下所示:

  df<  -  data .frame(main.cat = c(A,A,B,B,B,C),
second.cat = c(a1,a2 ,b1,b2,b3,c1),
值= c(2,3,4,2.5,1.5,2.3))

df $ x.labels< - paste(df $ second.cat,df $ main.cat,sep =\\\


ggplot(data = df,aes(x = x.labels, y = value))+ geom_point()

这至少保留了两个类别的级别,的主要类别标签:



有人知道更好的东西,看起来更像是Excel的输出吗?

我认为facet方法没问题:

 库(ggplot2)
库(gtable)
库(网格)

df < - data.frame(main.cat = c(A,A,B,B,B,C),
second.cat = c(a1,a2,b1,b2,b3,c1),
值= c(2,3,4,2.5,1.5,2.3))

p = ggplot(data = df,aes(x = second.cat,y = value))+
geom_point()+ facet_grid(。〜main.cat,space =free_x,scale =free_x)+
主题(strip.background = element_rect(fill = NA))



<但是如果你想要更接近excel外观的东西,一种方法是使用 gtable 函数来提取条并将其插入刻度标记标签下,然后插入一些边界主要类别之间的界限。请注意,以下代码特定于您的示例数据。

  p = p +主题(panel.spacing = unit(0,lines))
g = ggplotGrob p)
gtable_show_layout(g)#查看布局

#在x轴刻度标记下方添加一行,
#与条带相同的高度
g = gtable_add_rows(g,g $ height [6],8)

#获取strip grob
stripGrob = gtable_filter(g,strip)

#插入grob到新行
g = gtable_add_grob(g,stripGrob,9,4,9,8)

#删除旧条带
g = g [-6 ,]

#插入行grob作为主要类别之间的边界线
linesGrob = linesGrob(gp = gpar(col =grey75))
for(i in c(5 ,7))g = gtable_add_grob(g,linesGrob,t = 7,l = i,b = 8,r = i)

#插入新的零宽度列, (g,单位(0,lines),i)
g = gtable_add_grob(g, linesGrob,t = 7,l = i + 1,b = 8,r = i + 1)
}

grid.newpage ()
grid.draw(g)



编辑 / b>

 库(ggplot2)
库(gtable)
库(网格)
$ b $数据帧(main.cat = c(A,A,B,B,C,D),
second.cat = c( a1,a2,b1,b2,c1,d1),
值= c(2,3,4,2.5,1.5,2.3))

p = ggplot(data = df,aes(x = second.cat,y = value))+
geom_point()+ facet_grid(。〜main.cat,space =free_x,scales = free_x)+
主题(strip.background = element_rect(fill = NA))


p = p + theme(panel.spacing = unit(0,lines)) )
g = ggplotGrob(p)
gtable_show_layout(g)#查看布局

#获取面板的索引(t = top,l = left,...)
面板< -c(子集(g $ layout,grepl(panel,g $ layout $ name),se = t:r))

#获取strip grob
stripGrob = gtable_filter(g,strip)

#它的高度是
height = stripGrob $ height

#Add在x轴刻度标记下面一行,
#与条带高度相同。
g = gtable_add_rows(g,高度,独特(面板$ b + 1))

#将条状grob插入新行
g = gtable_add_grob(g,stripGrob,
t =独特(面板$ b + 2),
l = min(面板$ l),
r = max(面板$ r))

#插入线条作为边界主要类别之间的界限
linesGrob = linesGrob(gp = gpar(col =grey75))
panelsR = panels $ r [-length(panels $ r)]
for(i in panelsR +1)g = gtable_add_grob(g,linesGrob,
t = unique(panels $ b + 1),
l = i,
b = unique(panels $ b + 2))

#插入零宽度的新列以获取第一条和最后一条边界线的线grob
panelBound = c(3,max(panels $ r)+1)
for(i in panelBound){
g = gtable_add_cols(g,unit(0,lines),i)
g = gtable_add_grob(g,linesGrob,
t = unique(panels $ b + 1),
l = i + 1,
b =唯一(面板$ b + 2))
}

#删除旧条带
g = g [-6,]

#绘制
grid.newpage()
grid.draw(g)


I'm plotting data which have both a category and a sub-category (see the example data below) and I'd like to display these with them nested (this example was created in Excel):


The best I've come up with in R is to create a new column with the desired names, like this:

df <- data.frame(main.cat = c("A", "A", "B", "B", "B", "C"),
                 second.cat = c("a1", "a2", "b1", "b2", "b3", "c1"),
                 value = c(2, 3, 4, 2.5, 1.5, 2.3))

df$x.labels <- paste(df$second.cat, df$main.cat, sep = "\n")

ggplot(data = df, aes(x = x.labels, y = value)) + geom_point()

This at least retains both levels of categories, but duplicates all of the main category labels:

Does anyone know of anything better, which would look more like Excel's output?

解决方案

I think the facet approach is fine:

library(ggplot2)
library(gtable)
library(grid)

df <- data.frame(main.cat = c("A", "A", "B", "B", "B", "C"),
                 second.cat = c("a1", "a2", "b1", "b2", "b3", "c1"),
                 value = c(2, 3, 4, 2.5, 1.5, 2.3))

p = ggplot(data = df, aes(x = second.cat, y = value)) + 
   geom_point() + facet_grid(.~main.cat, space = "free_x", scales = "free_x") +
   theme(strip.background = element_rect(fill = NA))

But if you want something closer to the excel look, one approach is to use gtable functions to extract the strip and insert it below the tick mark labels, then insert some boundary lines between the major categories. Note that the code below is specific to your sample data.

p = p + theme(panel.spacing = unit(0, "lines"))
g = ggplotGrob(p)
 gtable_show_layout(g)  # to see the layout

# Add a row below the x-axis tick mark labels,
# the same height as the strip
g = gtable_add_rows(g, g$height[6], 8)

# Get the strip grob
stripGrob = gtable_filter(g, "strip")

# Insert the strip grob into the new row
g = gtable_add_grob(g, stripGrob, 9, 4, 9, 8)

# remove the old strip
g = g[-6, ]

# Insert line grobs as boundary lines between major categories
linesGrob = linesGrob(gp = gpar(col = "grey75"))
for(i in c(5,7))  g = gtable_add_grob(g, linesGrob, t=7, l=i, b=8, r=i)

# Insert new columns of zero width to take the line grobs for the first and last boundary lines
for(i in c(3, 9)) {
   g = gtable_add_cols(g, unit(0, "lines"), i)
   g = gtable_add_grob(g, linesGrob, t=7, l=i+1, b=8, r=i+1)
}

grid.newpage()
grid.draw(g)

Edit A crude attempt at generalising

library(ggplot2)
library(gtable)
library(grid)

df <- data.frame(main.cat = c("A", "A", "B", "B", "C", "D"),
                 second.cat = c("a1", "a2", "b1", "b2", "c1", "d1"),
                 value = c(2, 3, 4, 2.5, 1.5, 2.3))

p = ggplot(data = df, aes(x = second.cat, y = value)) + 
   geom_point() + facet_grid(.~main.cat, space = "free_x", scales = "free_x") +
   theme(strip.background = element_rect(fill = NA))


p = p + theme(panel.spacing = unit(0, "lines"))
g = ggplotGrob(p)
 gtable_show_layout(g)  # to see the layout

# Get the indices for the panels (t=top, l=left, ...
panels <- c(subset(g$layout, grepl("panel", g$layout$name), se=t:r))

# Get the strip grob
stripGrob = gtable_filter(g, "strip")

 # Its height is
 height = stripGrob$height

# Add a row below the x-axis tick mark labels,
# the same height as the strip. 
g = gtable_add_rows(g, height, unique(panels$b+1))

# Insert the strip grob into the new row
g = gtable_add_grob(g, stripGrob, 
                      t = unique(panels$b+2), 
                      l = min(panels$l), 
                      r = max(panels$r))

# Insert line grobs as boundary lines between major categories
linesGrob = linesGrob(gp = gpar(col = "grey75"))
panelsR = panels$r[-length(panels$r)]
for(i in panelsR+1)  g = gtable_add_grob(g, linesGrob, 
                       t=unique(panels$b+1), 
                       l=i, 
                       b=unique(panels$b+2))

# Insert new columns of zero width to take the line grobs for the first and last boundary lines
 panelBound = c(3, max(panels$r)+1)
for(i in panelBound) {
   g = gtable_add_cols(g, unit(0, "lines"), i)
   g = gtable_add_grob(g, linesGrob, 
                    t=unique(panels$b+1), 
                    l=i+1, 
                    b=unique(panels$b+2))
}

# remove the old strip
g = g[-6, ]

# Draw it
grid.newpage()
grid.draw(g)

这篇关于如何绘制嵌套类别轴的图表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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