ggplot: сгруппированные смежные столбцы переменной ширины - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь создать барплот, в котором ширина и высота столбцов передают информацию: высота - это количество часов, потраченных на задачу, ширина соответственно указывает на воспринимаемую способность и важностьсвязано с задачей.Мне удалось создать это чудовище:

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))

Хотя я на самом деле сделал это, используя несколько более простой dataframe, который я расплавил () - edв тот, что выше.

Ответы [ 3 ]

0 голосов
/ 06 марта 2019

Я добился определенного прогресса, опираясь на идею йода о мутировании исходного фрейма данных.Я сделал два отдельных джем-бара и подтолкнул их друг к другу.Мне бы очень понравилось, если бы каждый бар касался своего соседа, но position_nudge () принимает только константу.Я все еще вхожу в ggplot, поэтому самым очевидным решением в моем представлении является переработанный вектор 'смещения', схожий с цветовым аргументом barplot ().

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'])
0 голосов
/ 07 марта 2019

Я сделал это - должен был нарисовать каждый столбец в виде прямоугольника, соответственно отрегулировав 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')
0 голосов
/ 04 марта 2019

Не идеальное решение, но вы можете создать новый столбец, который объединит Activity и Variable, использовать его в качестве 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

...