I want to plot two histograms where the x and y ranges are the same for both. After reading some posts, my solution is to use ggplot2, geom_histogram twice. The first time I am creating the plots without plotting for each dataset of interest with the intention to get the maximum y/count and x axes values among all plots of interest. For example, having two plots, if for the first one ymax_1 = 10 for the other ymax_2 = 15, then both plots will have a y axis range from 0 to 15 at least. Similarly holds for the x axis.
After this plot, I take the ymax/xmax values and plot the histograms like before with the addition of xlim( 0, xmax) and ylim( 0, ymax). However, when I do this, the amount of counts changes. More specifically, in the first plots where I don't have any xlim/ylim specified I get from ggplot_build( ggplot(...) + geom_histogram(...)) ymax = 2000 but when I use xlim the second time I get ymax = 4000. Nevertheless, from the 1st plot I have ymax = 2000 and hence the second time the histograms are not plotted properly. When I remove the xlim option I get the same result.
How and why the xlim option affects the amount of counts? I hope that was clear.
df = read.table( paste( path, f, sep = "/"), header = TRUE, fill = TRUE, sep = ",", stringsAsFactors = TRUE)
measure = colnames( df)[ 7]
combs = unique( df[, c( 'A', 'B', 'C')])
# order combs in specific order to get a specific sequence of plots
combs = combs[ with( combs, order( B, C, A)), ]
bns = lst()
xmxs = lst()
ymxs = lst()
for( j in seq( 1, length( combs[ , 1]), 2)) {
if( combs[ j, 2] == combs[ j, 3]) {
next
}
tmp = subset( df, A == combs[ j, 1] & B == combs[ j, 2] & C == combs[ j, 3], select = c( measure))
# Freedman – Diaconis rule, "On the histogram as a density estimator: L2 theory"
bw = 2 * IQR( tmp[ , 1]) / ( length( tmp[ , 1])^(1/3))
bns[[ j]] = ceiling( ( max( tmp[ , 1]) - min( tmp[ , 1])) / bw)
plots[[ j]] = ggplot( tmp, aes_string( measure)) + geom_histogram( bins = bns[[ j]], aes( fill = ..count..))
histg = ggplot_build( plots[[ j]])$data[[ 1]]
ymxs[[ j]] = max( histg$count)
xmxs[[ j]] = max( histg$x)
tmp = subset( df, A == combs[ j + 1, 1] & B == combs[ j + 1, 2] & C == combs[ j + 1, 3], select = c( measure))
# Freedman – Diaconis rule, "On the histogram as a density estimator: L2 theory"
bw = 2 * IQR( tmp[ , 1]) / ( length( tmp[ , 1])^(1/3))
bns[[ j + 1]] = ceiling( ( max( tmp[ , 1]) - min( tmp[ , 1])) / bw)
plots[[ j + 1]] = ggplot( tmp, aes_string( measure)) + geom_histogram( bins = bns[[ j + 1]], aes( fill = ..count..))
histg = ggplot_build( plots[[ j + 1]])$data[[ 1]]
ymxs[[ j + 1]] = max( histg$count)
xmxs[[ j + 1]] = max( histg$x)
if( ymxs[[ j]] > ymxs[[ j + 1]]) {
ymxs[[ j + 1]] = ymxs[[ j]]
}
else {
ymxs[[ j]] = ymxs[[ j + 1]]
}
if( xmxs[[ j]] > xmxs[[ j + 1]]) {
xmxs[[ j + 1]] = xmxs[[ j]]
}
else {
xmxs[[ j]] = xmxs[[ j + 1]]
}
}
pplots = lst()
for( j in 1 : length( combs[ , 1])) {
if( combs[ j, 2] == combs[ j, 3]) {
next
}
tmp = subset( df, A == combs[ j, 1] & B == combs[ j, 2] & C == combs[ j, 3], select = c( measure))
avg = sprintf( "%.2f", mean( tmp[ , 1]))
stdv = sprintf( "%.2f", std( tmp[ , 1]))
count = length( tmp[ , 1])
entities[[ j]] = paste( combs[ j, 1], " ", combs[ j, 2], " vs ", combs[ j, 3])
pplots[[ j]] = ggplot( tmp, aes_string( measure)) +
geom_histogram( bins = bns[[ j]], aes( fill = ..count..)) +
# xlim( 0, 1.2*xmxs[[ j]]) +
# ylim( 0, 1.2*ymxs[[ j]]) +
ggtitle( bquote( atop( paste( .(entities[[ j]])), paste( mu, " = ", .( avg), ", ", sigma, " = ", .( stdv), ", #cells = ", .( count), sep = " ")))) +
theme( plot.title = element_text( size = 20), axis.text = element_text( size = 12), axis.title = element_text( size = 15))
}
# plot every two plots because the Reference.Population is the same
for( j in seq( 1, length( plots), 2)) {
fileext = str_remove_all( entities[[ j]], 'N')
filename_hi = paste( gsub( '.{4}$', '', f), "_distribution_", fileext, ".png", sep = "")
png( filename = paste( path, filename_hi, sep = "/"))
grid.draw( rbind( ggplotGrob( pplots[[ j]]), ggplotGrob( pplots[[ j + 1]]), size = "last"))
dev.off()
}
So, in the code above, plots
contains the initial plots from which I get the min and max values for y,x axes and pplots
contains the plots that I plot finally using the xlim/ylim
options. However, for example,
max( plots[[ 8]]$data[[ 1]]$count) != max( plots[[ 8]]$data[[ 1]]$count)
when I use the xlim
option. The first one gives 1947
and the other one gives 4529
for my data.
Thanks