Graph function using AlgebraOfGraphics

I would like to overlay a density function over a histogram and have a strong preference for using the AlgebraOfGraphics to graph this exact function. Currently, to accomplish this I have to translate the function into a dataframe of values and then, plot the dataframe. Might the data() function somehow be able to take an interval and function as inputs.

This is the graph I want to create:

And here is some code where I want to skip the part of creating pdfDF:

using Random, Distributions, DataFrames, CairoMakie, AlgebraOfGraphics
CairoMakie.activate!(type = "svg") # crisper plots than default png
betaSamplingDist = Beta(2,2)  ## create RV

## get N samples
N = 1000
Random.seed!(123) # Setting the seed so we can get the same random numbers
dataDF = DataFrame(samples = rand(betaSamplingDist,N)) ##**

## samples easy to plot using AlgebraOfGraphics
kumaHist = data(dataDF) * mapping(:samples) * 
            visual(Hist, normalization = :pdf, bins = 30, color = :cadetblue)
draw(kumaHist, axis = (xlabel = "samples", ylabel = "y"))

## make dataframe for plotting
pdfDF = DataFrame(xVal = 0:0.001:1)
pdfDF."density" = pdf(betaSamplingDist,pdfDF.xVal)

## combine histogram of sample and pdf from density function 
overlayDensityPlot = kumaHist +
    data(pdfDF) * mapping(:xVal,:density) * visual(Lines, color = :orange, linewidth = 8)
draw(overlayDensityPlot, axis = (xlabel = "y", ylabel = "density(y)"))

## is there a way to draw the above without creating the intermediate dataframe?
## for example, here is the Makie way to plot a function without a DataFrame
plot(0..1, x -> pdf(betaSamplingDist,x), color = :orange, linewidth = 8,
    axis = (xlabel = "y", ylabel = "density(x)"))

For these cases (plots that don’t depend on any data, like a pdf of a given distribuion), I think you can just combine Makie and AlgebraOfGraphics, for example

fg = draw(kumaHist , axis = (xlabel = "y", ylabel = "density(y)"))
ax = only(fg.grid).axis # `fg.grid` here has only one element as there is no layout
plot!(ax, 0..1, x -> pdf(betaSamplingDist,x), color = :orange, linewidth = 8)
# maybe `plot!(ax, betaSamplingDist)` already works and figures out the extrema

But I see your point, ideally one should allow things like

data((x=0..1, y=t -> pdf(dist, t)) * mapping(:x, :y)

I’ll try to think if there is an easy way to add it that is consistent with the rest of the API.

Thanks Pietro. I am a big fan of the AlgebraOfGraphics (AOG). The refactoring you did to simplify the code base and the user experience is just phenomenal. I am a big user of ggplot2 and increasingly becoming a Julia-user; I find AOG to be a super-clean improvement of ggplot2’s API. Pure gold! Thx again.

PS: All that being said, I would love the ability to graph functions and stay in the AlgebraOfGraphics paradigm - thx for considering it :slight_smile:

1 Like