ggplot:可变宽度的分组相邻条形图

时间:2019-03-04 17:29:41

标签: r ggplot2 bar-chart

我正在尝试制作一个条形图,其中条形图的宽度和高度都传达信息:高度是在一项任务上花费的小时数,宽度分别表示感知的能力与任务相关的重要性。我设法产生了这种怪异现象:

Nested Bars Plot

它功能正常,但可怕。我真的很想将条形图并排放置(而不是覆盖它们),以便每个活动都由两个相同高度(=花时间)但宽度和颜色不同的触摸条表示。我一直在尝试将宽度参数传递给该图:

Plot w/ dodged bars

但是设置'aes(width = widthVariable)'会给我重叠的条(类似于第一张图片)和以下警告消息:

“ position_dodge需要不重叠的x间隔”。

是否可以通过活动对条形进行分组,相邻显示并改变其宽度?

以下是我正在使用的df:

molten = data.frame(Activity = rep(c('Administration','Working with Colleagues','Use of Social Media','Leadership Role'),2),
            variable = c(rep('Importance',4),rep('Competence',4)),
            value = rep(c(3.02,1.71,2.39,3.32),2),
            width = c(3.48,3.52,4.01,2.98,
                      3.85,2.34,4.87,3.81))

第二个情节是这样的

 ggplot(molten, aes(x=Activity, y=value, fill=variable)) + geom_bar(stat='identity',position = 'dodge')

和第一个类似的东西:

 ggplot(molten, aes(x=Activity, y=value, fill=variable)) + geom_bar(stat='identity',aes(width = width/10))

尽管我实际上是使用稍微简单一些的数据框来实现的,但我将其熔化()化为上面的数据框。

3 个答案:

答案 0 :(得分:1)

不是一个完美的解决方案,但是您可以创建一个新列,将“活动”和“变量”组合在一起,将其用作x,然后按变量填充:

molten<-mutate(molten,activity=paste(Activity,variable))
ggplot(molten, aes(x=activity, y=value,width = width/10)) + 
  geom_bar(stat='identity', aes(fill=variable)) + 
  theme(axis.text.x = element_text(angle = 45,hjust=1)) + 
  scale_x_discrete(breaks=molten$activity, labels=molten$Activity)

enter image description here

答案 1 :(得分:0)

在iod改变原始数据帧的想法的基础上,我已经取得了一些进展。 我已经制作了两个单独的geom-bars,并将它们微调到另一个。如果每个小节都碰到它的邻居,我真的很喜欢它,但是position_nudge()只需要一个常量。我仍在进入ggplot,因此在我看来,最明显的解决方案是回收的“微调”矢量,类似于barplot()的color参数。

tldr:条形之间的间隙很小,但现在相当漂亮。

Improved barplot. I've shuffled the labels so that the data remains unpublished

 molten<-mutate(molten,activity=paste(Activity,variable))
    molten$importanceBars = c(value[variable=='Importance'],rep(0,nrow(molten)-sum(variable=='Importance')))
    molten$competenceBars = c(rep(0,nrow(molten)-sum(variable=='Competence')),value[variable=='Competence'])

ggplot(molten, aes(x=activity,width = width/6, fill = variable)) + 
  geom_bar(stat='identity', aes(y=importanceBars),position=position_nudge(x=-0.2-0.35)) +
  geom_bar(stat='identity', aes(y=competenceBars),position=position_nudge(x=-0.35)) +
  theme(axis.text.x = element_text(angle = 45,hjust=1)) + 
  scale_x_discrete(breaks=molten$activity[molten$variable=='Competence'], 
                   labels=molten$Activity[molten$variable=='Competence'])

答案 2 :(得分:0)

我已经完成了-必须将每个条形绘制为矩形,并相应地调整xmin和xmax。

perfected barplot

wadjust = 5.5
gap = 0.0
minv = 1:length(value) - 0.5 + gap/2
maxv = minv + 1 -gap


minv[1:length(minv)%%2!=0] = maxv[1:length(maxv)%%2!=0] - width[order(Activity)][(1:length(width))%%2!=0]/wadjust
maxv[1:length(maxv)%%2==0] = minv[1:length(minv)%%2==0] + width[order(Activity)][(1:length(width))%%2==0]/wadjust

minv = minv +0.525
maxv = maxv +0.525

minvord = minv[order(Activity)]
maxvord = maxv[order(Activity)]

ggplot(molten, aes(x=activity,width = width/6, fill = variable)) + 
  geom_rect(xmin = minv,xmax = maxv, ymin = rep(0,28), ymax = value[order(Activity)],
            fill = rep(c('#e1de00','#e84619'),len=28))  + 
  theme(axis.text.x = element_text(angle = 45,hjust=1)) + 
  theme(plot.margin=unit(c(1,0.5,1,2),"cm")) +
  scale_x_discrete(breaks=molten$activity[molten$variable=='Importance'], 
                   labels=molten$Activity[molten$variable=='Importance'][order(Activity[molten$variable=='Importance'])]) +
  scale_y_continuous(labels = 0:3, breaks = 0:3, limits = c(0,3)) +
  xlab('Activity') + ylab('Hours Spent') + 
  labs(title = 'Perceived Importance & Competence\nAssociated with Clerical Duties') +
  theme(panel.grid.major.x = element_blank()) +
  geom_vline(xintercept = (maxv[1:length(maxv)%%2!=0]+minv[1:length(minv)%%2==0])/2,col='white') +
  geom_vline(xintercept = seq(len = 14, by = 2),col = 'white')