0

My goal is to produce two overlapping PMFs of binomial distributions using ggplot2, color-coded according to colors that I specify, with a legend at the bottom.

So far, I think I have set up the data frame right.

successes <- c(seq(0,10,1),seq(0,10,1))
freq <- c(dbinom(seq(0,10,1),10,0.2),dbinom(seq(0,10,1),10,0.8))
class <- c(rep('  A  ',11),rep('  B  ',11))
df1 <- data.frame(cbind(successes,freq,class))

However, this gives the wrong result.

library(ggplot2)
g <- ggplot(df1, aes(successes),y=freq)
g + geom_bar(aes(fill = class))

I feel like I'm following an example yet getting a totally different result. This (almost) does what I want: it would be exact if it gave relative frequencies.

g <- ggplot(mpg, aes(class))
g + geom_bar(aes(fill = drv))

A couple of questions:

1) Where am I going wrong in my block of code?

2) Is there a better way to show to PMFs in one graph? I'm not determined to use a histogram or bar chart.

3) How can I set this up to give me the ability to choose the colors?

4) How do I order the values on the x-axis? They aren't categories. They are the numbers 0-10 and have a natural order that I want to preserve.

Thanks!

UPDATE

The following two blocks worked.

successes <- c(seq(0,10,1),seq(0,10,1))
freq <- c(dbinom(seq(0,10,1),10,0.2),dbinom(seq(0,10,1),10,0.8))
class <- c(rep('  A  ',11),rep('  B  ',11))
df1 <- data.frame(successes,freq,class)
ggplot(df1, aes(successes ,y=freq, fill = class)) +
geom_bar(stat = "identity") +
scale_x_continuous(breaks = seq(0,10,1)) +
scale_fill_manual(values = c("blue", "green")) + theme_bw()

AND

successes <- c(seq(0,10,1),seq(0,10,1))
freq <- c(dbinom(seq(0,10,1),10,0.2),dbinom(seq(0,10,1),10,0.8))
class <- c(rep('  A  ',11),rep('  B  ',11))
df1 <- data.frame(successes,freq,class)
ggplot(df1, aes(x=successes,y=freq),y=freq) + 
geom_col(aes(fill = class)) +
scale_x_continuous(breaks = seq(0,10,1)) +
scale_fill_manual(values = c("blue", "green")) + theme_bw()
Dave
  • 314
  • 2
  • 13
  • 1
    Your use of `cbind()` within `data.frame()` is what made all your variables into factors. You can use `data.frame()` directly without the `cbind()` step: `df1 <- data.frame(successes, freq, class)` – aosmith Jul 09 '19 at 16:37
  • 1
    If you want to use a `y` variable in the plot, make sure `y = freq` is *inside* `aes()`. Then you can use `geom_col()` instead of `geom_bar()`. – aosmith Jul 09 '19 at 16:43

2 Answers2

2

I think your issue is that successes and freq are being changed to factors when you create df1

Maybe this is what you're thinking of?

successes <- c(seq(0,10,1),seq(0,10,1))
freq <- c(dbinom(seq(0,10,1),10,0.2),dbinom(seq(0,10,1),10,0.8))
class <- c(rep('  A  ',11),rep('  B  ',11))
df1 <- data.frame(successes = as.numeric(successes), freq = as.numeric(freq), class)

ggplot(df1, aes(x = successes, y = freq)) +
  geom_bar(stat = "identity", aes(fill = class))

If not, happy to answer any further questions!

MayaGans
  • 1,815
  • 9
  • 30
1

Is this what you're looking for?

library(ggplot2)
g <- ggplot(df1, aes(successes ,y=freq, fill = class))
g + geom_bar(stat = "identity") +
scale_fill_manual(values = c("blue", "green"))

Of course, keeping in mind you'd indeed change your dataframe creation to:

successes <- c(seq(0,10,1),seq(0,10,1))
freq <- c(dbinom(seq(0,10,1),10,0.2),dbinom(seq(0,10,1),10,0.8))
class <- c(rep('  A  ',11),rep('  B  ',11))
df1 <- data.frame(successes,freq,class)

as suggested in the comments.

Sven
  • 1,203
  • 1
  • 5
  • 14
  • It seems like the trick was the use stat="identity". What does that mean? – Dave Jul 09 '19 at 17:47
  • it means that you're using a column in the data for your y aesthetic. – Sven Jul 09 '19 at 17:54
  • Now how do I get a legend at the bottom and with no title? I've used "theme(legend.position="bottom",legend.title=element_blank())" in the past, but that isn't working here. – Dave Jul 09 '19 at 19:48
  • I just tried exactly that and it works for me... are you getting any error messages? – Sven Jul 09 '19 at 20:42
  • The plot thickens...that line works, but only if I leave out the "theme_bw()" command. How can I get the white background AND the legend at the bottom? It seems like the two "theme" commands may be conflicting, but that hasn't happened to me before when I've put the legend at the bottom and had the white background. (SOLVED! It turns out that "theme_bw" has to come first.) – Dave Jul 09 '19 at 20:42
  • 1
    if you do the `theme_bw` first and then the `theme(legend...` ones it will work fine. The order is important. – Sven Jul 09 '19 at 20:45
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/196222/discussion-between-dave-and-sven). – Dave Jul 09 '19 at 20:46