0

Help!

I'm using ggplot2 to plot the counts for two values side by side each month (d1 and d2).

My code currently produces a chart like this:

enter image description here

BUT I really need to add a space between the paired bars each month so it is clearer to read. I've tried a load of things, but can't get it working. Can anybody suggest a solution?

The answers suggested here and here produce plots where the bars overlap each other and I get the error message 'position_dodge requires non-overlapping x intervals'.

Here's my code:

m_scores = ddply(data_NKsam2,.(zdate),summarise, d1 = sum(d1) , d2 = sum(d2))

require(tidyr)

df <- gather(m_scores, event, total, d1:d2)

plot <- ggplot(df, aes(zdate, total, fill=event))
plot <- plot + geom_bar(stat = "identity", position = 'dodge')

And here is a section of the data 'm_scores'

  zdate  d1   d2
11 Nov 2014 263  318
12 Dec 2014 430  662
13 Jan 2015 507  326
14 Feb 2015 326  279
15 Mar 2015 281  345
16 Apr 2015 352  260
17 May 2015 280  315
18 Jun 2015 243  238
19 Jul 2015 313  251
20 Aug 2015 446  439
21 Sep 2015 416  404
22 Oct 2015 616  423
23 Nov 2015 269  242
24 Dec 2015 781  527
25 Jan 2016 865  861
26 Feb 2016 997 2139
27 Mar 2016 920 1421
28 Apr 2016 376  498
29 May 2016 434  309
30 Jun 2016 271  284

or here, I tried to use dput() to copy it:

structure(list(zdate = structure(c(2014, 2014.08333333333, 2014.16666666667, 
2014.25, 2014.33333333333, 2014.41666666667, 2014.5, 2014.58333333333, 
2014.66666666667, 2014.75, 2014.83333333333, 2014.91666666667, 
2015, 2015.08333333333, 2015.16666666667, 2015.25, 2015.33333333333, 
2015.41666666667, 2015.5, 2015.58333333333), class = "yearmon"), 
    d1 = c(2, 5, 2, 2, 3, 3, 5, 8, 3, 158, 263, 430, 507, 326, 
    281, 352, 280, 243, 313, 446), d2 = c(0, 3, 5, 1, 3, 2, 0, 
    1, 2, 131, 318, 662, 326, 279, 345, 260, 315, 238, 251, 439
    )), row.names = c(NA, 20L), class = "data.frame")

Really appreciate any help that anyone can offer!

Nick Olczak
  • 305
  • 3
  • 14

1 Answers1

1

You can set the width argument. This controls the total with of the dodged bars (creating space in-between). See the revision to your plotting line here:

plot + geom_bar(stat = "identity", position = 'dodge')

enter image description here

And with the width argument set:

plot + geom_bar(stat = "identity", position = 'dodge', width=0.5)

enter image description here

chemdork123
  • 12,369
  • 2
  • 16
  • 32
  • Thanks for your help! How you show it in the picture is exactly what I want. But when I try that plotting line with my data, I get the Warning message: position_dodge requires non-overlapping x intervals, and the bars are squashed on top of each other. Any idea why, and why it worked for you? – Nick Olczak Apr 20 '21 at 17:29
  • 1
    It's because your `zdate` column is not discrete. I initially used `zdate` as containing values like `"11 Nov 2014"` (reading in your data posted as text). The column itself was a `chr` type, so it was discrete. In the `dput()` output, I see you are sharing `zdate` is a `num` type, which is continuous. That's what is causing the error for you. You can either model the values as a date or list them as an ordered vector of characters, but you need discrete x axis values to properly dodge the columns. – chemdork123 Apr 20 '21 at 17:51
  • Great, thank you so much! How would I best convert the `zdate` to one of those two? I guess I could create a new vector in `m_scores` with the values, but I'm not sure how to do the conversion? – Nick Olczak Apr 20 '21 at 18:06
  • 1
    Well, you can convert your dates into one of the date formats (check `lubridate` package for tips there) - but that can get complicated, and it may not be what you're looking for, depending on how your data is spread out. If you just want to line them up on the x axis and have equal spacing between them, you can just say `factor(zdate)` instead of `zdate` and this will force your numeric column into a factor, thus making it a column of discrete values. – chemdork123 Apr 20 '21 at 18:29
  • I ended up reading in your text version of the output you shared (before you shared via `dput()`) - via `read.table(header=TRUE, text="... your text...")`. I had to add characters of `d` and `m` and `y` in place of `zdate` to read in all the columns with spaces (so the header was `d m y d1 d2`), then I just joined the columns together with `your_data$zdate <- paste(your_data$d, your_data$m, your_data$y)`. It forced them all to be `chr` type in the `zdata` column, so it worked fine. – chemdork123 Apr 20 '21 at 18:32
  • Cool, thank you so much! You've really helped me out with this. – Nick Olczak Apr 20 '21 at 18:39