Reputation: 1297
could you tell me if it is possible make a bar plot with bar height normalized to 1, but bar width proportional to the number of elements in each bin.
Example : this plot
ggplot(mtcars, aes(x=factor(cyl), fill=factor(vs))) + geom_bar(position="fill")
and then make the width of the 3 bars proportional to
table(factor(mtcars$cyl))
There is well that "width" parameter in position_fill() but it has to be a constant, hasn't it ?
Thank you,
François
EDIT :
I tried a bit further, and get the message : "position_fill requires constant width"
So I guess to get what I tried to get is impossible, at least using geom_bar.
Upvotes: 5
Views: 7485
Reputation: 58875
I can do it by preprocessing the data, but not entirely within a single ggplot
call.
library("plyr")
mt <- ddply(mtcars, .(cyl, vs), summarise, n=length(cyl))
mt <- ddply(mt, .(cyl), mutate, nfrac = n/sum(n), width = sum(n))
mt$width <- mt$width / max(mt$width)
The mt
data set now has everything needed to make the plot:
> mt
cyl vs n nfrac width
1 4 0 1 0.09090909 0.7857143
2 4 1 10 0.90909091 0.7857143
3 6 0 3 0.42857143 0.5000000
4 6 1 4 0.57142857 0.5000000
5 8 0 14 1.00000000 1.0000000
and the ggplot
call would look like
ggplot(mt, aes(x=factor(cyl), fill=factor(vs), y=nfrac)) +
geom_bar(aes(width=width), position="stack", stat="identity")
It does throw the warning:
Warning message:
position_stack requires constant width: output may be incorrect
but creates the plot:
Upvotes: 5
Reputation: 18487
Is this what you want?
library(ggplot2)
ggplot(mtcars, aes(x=factor(cyl), fill=factor(vs))) + geom_bar(position="fill") + coord_flip()
Upvotes: 0