Plotting 2D histogram with different bins for each dimension

I’m trying to plot a 2D histogram where the 2 dimensions have different bins.

I’m currently using

marginalhist(x, x, fc=:plasma, bins=[0.0, 1.0, 2.0], legend=true)

from PlotRecipes (although I’m not tied to that).

The problem is that it uses the same bins for both dimensions. How can I specify different bins for the second dimension? (Note that the documentation generally shows one setting the number of bins rather than the actual bin boundaries. I need to specify the bin boundaries. They are not evenly spaced.)

As a second question, anyone know how to label the bin values on the axes? As is, I get about 3 labels for all of the many bins.

Is there any plotting documentation I’m missing? Creating basic plots is explained but finding details for refining them is difficult, and the source, at least for PlotRecipes, is hard to read in many cases because functions are often created with macros.

Thanks.

You should be able to pass a Tuple of bins to histogram2d which is the Plots.jl recipe that does the work of marginalhist. This does not work at the moment, which looks like a bug to me. Could you open an issue on Plots.jl?
AFAICS Plots.jl does not support arbitrary sized bins - are you seeking to get a plot where some bins are visibly larger than others? I cannot imagine the use case (it may still be 100% valid of course).

Or you can do it manually with heatmap, the Plots code is really simple (slightly modified here):

function althist(x, y, xedges, yedges) 
   counts = zeros(length(yedges)-1, length(xedges)-1)

    for i=1:length(x)
        r = Plots.bucket_index(y[i], yedges)
        c = Plots.bucket_index(x[i], xedges)
        counts[r,c] += 1.0
    end

    heatmap(counts)
end


# An example of using the function
x = randn(1000); y = randn(1000)
xedges = linspace(minimum(x), maximum(x), 40)
yedges = linspace(minimum(y), maximum(y), 60)
althist(x, y, xedges, yedges)

Axis labelling is handled as normal in Plots - see e.g. ticks https://juliaplots.github.io/attributes/

(note though that heatmap requires all bins on an axis to visually have the same width on the plot)

1 Like

Even though the OP never responded I will just update for future readers.
There was a bug in marginalhist that has been fixed. It is possible to specify different bin numbers and uneven bins (even though that is a tricky thing to do on a 2d-histogram as larger bins will get more counts).

using StatPlots
pyplot() # currently the only backend who supports display of heatmaps with uneven bin sizes.
x, y = randn(10000), randn(10000)
marginalhist(x, y, fc = :plasma, bins = (6, 6sort(rand(20))-3))

giving

6 Likes

I think it still works, but you have to use StatsPlots instead of StatPlots