7
votes

The following code

library(ggplot2)
library(reshape2)

m=melt(iris[,1:4])

ggplot(m, aes(value)) + 
  facet_wrap(~variable,ncol=2,scales="free_x") +
  geom_histogram()

produces 4 graphs with fixed y axis (which is what I want). However, by default, the y axis is only displayed on the left side of the faceted graph (i.e. on the side of 1st and 3rd graph).

What do I do to make the y axis show itself on all 4 graphs? Thanks!

EDIT: As suggested by @Roland, one could set scales="free" and use ylim(c(0,30)), but I would prefer not to have to set the limits everytime manually.

@Roland also suggested to use hist and ddply outside of ggplot to get the maximum count. Isn't there any ggplot2 based solution?

EDIT: There is a very elegant solution from @babptiste. However, when changing binwidth, it starts to behave oddly (at least for me). Check this example with default binwidth (range/30). The values on the y axis are between 0 and 30,000.

library(ggplot2)
library(reshape2)

m=melt(data=diamonds[,c("x","y","z")])

ggplot(m,aes(x=value)) + 
  facet_wrap(~variable,ncol=2,scales="free") +
  geom_histogram() +
  geom_blank(aes(y=max(..count..)), stat="bin")

enter image description here

And now this one.

ggplot(m,aes(x=value)) + 
  facet_wrap(~variable,scales="free") +
  geom_histogram(binwidth=0.5) +
  geom_blank(aes(y=max(..count..)), stat="bin")

enter image description here

The binwidth is now set to 0.5 so the highest frequency should change (decrease in fact, as in tighter bins there will be less observations). However, nothing happened with the y axis, it still covers the same amount of values, creating a huge empty space in each graph.

[The problem is solved... see @baptiste's edited answer.]

3
+1! reproducible and clear!agstudy
Usually you don't copy every answer into the question.ziggystar
Is there a better way to respond to an answer when I want to provide code etc.? Or should I make a new answer with my response to the answer...?jakub

3 Answers

8
votes

Is this what you're after?

ggplot(m, aes(value)) + 
  facet_wrap(~variable,scales="free") +
  geom_histogram(binwidth=0.5) +
  geom_blank(aes(y=max(..count..)), stat="bin", binwidth=0.5)
3
votes
ggplot(m, aes(value)) + 
  facet_wrap(~variable,scales="free") +
  ylim(c(0,30)) +
  geom_histogram()
0
votes

Didzis Elferts in https://stackoverflow.com/a/14584567/2416535 suggested using ggplot_build() to get the values of the bins used in geom_histogram (ggplot_build() provides data used by ggplot2 to plot the graph). Once you have your graph stored in an object, you can find the values for all the bins in the column count:

library(ggplot2)
library(reshape2)

m=melt(iris[,1:4])    

plot = ggplot(m) + 
  facet_wrap(~variable,scales="free") +
  geom_histogram(aes(x=value))

ggplot_build(plot)$data[[1]]$count

Therefore, I tried to replace the max y limit by this:

max(ggplot_build(plot)$data[[1]]$count)

and managed to get a working example:

m=melt(data=diamonds[,c("x","y","z")])

bin=0.5 # you can use this to try out different bin widths to see the results

plot=
  ggplot(m) + 
  facet_wrap(~variable,scales="free") +
  geom_histogram(aes(x=value),binwidth=bin)

ggplot(m) + 
  facet_wrap(~variable,ncol=2,scales="free") +
  geom_histogram(aes(x=value),binwidth=bin) +
  ylim(c(0,max(ggplot_build(plot)$data[[1]]$count)))

enter image description here

It does the job, albeit clumsily. It would be nice if someone improved upon that to eliminate the need to create 2 graphs, or rather the same graph twice.