Reputation: 33
Here is my graph so far:
counts <- table(all_study$study, all_study$time_of_day_num)
barplot(counts, main="Distribution of Enrollment Time by Study for 24-25",
col=c("blue","red","green","yellow","orange"),
ylab= "Count", names.arg=c("Night", "Evening", "Day"))
legend(0.2,70, legend=c("MATIC","TCD-2","TROOP","Lublin","Microbiome"),
fill=c("orange","yellow","green","red","blue"), cex=0.75)
And here is what the graph looks like:
I am trying to figure out how to place the count of each study under each type of day. For example, it looks like there is about 25 Microbiomes under Night and 2 TROOP under Night. So I want the number 25 placed in the center of the blue bar for night and 2 squeezed into the green bar for night.
I have tried text() and things like stat='count' and more.
Upvotes: 3
Views: 85
Reputation: 7979
We can calclate the middle heights ym
of each stacked bar with cumsum()
.
This approach adds 'white'
labels. If you do not like it, just remove rect()
, use a different colour palette or adjust the opacity in hcl.colors()
via it's alpha
-argument.
nr = nrow(counts2)
b = barplot(counts2, col=hcl.colors(n=nr), ylab='Count',
legend.text=row.names(counts2),
main='Distribution of Enrollment Time by Study for 24-25',
args.legend=list(x=4L, y=-7L, horiz=TRUE))
ym = apply(counts2, 2L, cumsum) - counts2 / 2L
rect(b-.07, t(ym)-1L, b+.07, t(ym)+1L, col='white')
text(rep(b, each=nr), ym, labels=t(counts2))
Please adapt the xy-coords in args.legend
of barplot()
and rect()
according to your needs.
Short-cut version
where the qualitative colour palette 'Dark 2'
is used.
b = barplot(counts2, col=hcl.colors(n=nrow(counts2)))
ym = apply(counts2, 2L, cumsum) - counts2 / 2L
rect(b-.07, t(ym)-1L, b+.07, t(ym)+1L, col='white')
text(rep(b, each=nrow(counts2)), ym, labels=t(counts2))
Running both nrow(counts2)
and t(ym)
twice should be tolierable overhead here.
Data
User jay.sf's counts
modified to match OP's data in dimension.
counts2 = structure(c(5, 18, 11, 5, 6, 6, 3, 6, 12, 10, 14, 6, 11, 6, 8), dim = c(5L, 3L), dimnames = list(c("MATIC", "TCD-2", "TROOP", "Lublin", "Microbiome"), c("Night", "Evening", "Day")))
> counts2
#> Night Evening Day
#> MATIC 5 6 14
#> TCD-2 18 3 6
#> TROOP 11 6 11
#> Lublin 5 12 6
#> Microbiome 6 10 8
Upvotes: 0
Reputation: 73562
You could write an ymids()
function, that calculates a cumulative sum, where the new element is always halved, i.e. x1/2, x1 + x2/2, x1 + x2 + x3/2, ... .
> ymids <- \(x) {
+ r <- numeric(length(x))
+ for (i in seq_len(length(x))) {
+ if (i == 1) {
+ r[i] <- x[i]/2
+ } else {
+ r[i] <- sum(x[seq_len(i - 1)]) + x[i]/2
+ }
+ }
+ r
+ }
> b <- barplot(counts, col=hcl.colors(4, alpha=.5))
> text(b, t(apply(counts, 2, ymids)), labels=t(counts))
If you really want these grey labels you can invent sth with rect
, but IMO it would just clutter the plot and adds no useful information.
Data:
> dput(counts)
structure(c(5L, 18L, 11L, 5L, 6L, 3L, 6L, 12L, 14L, 6L, 11L,
6L), dim = 4:3)
Upvotes: 2