juliagadfly

Processing statistics in Gadfly


I want to extend the Gadfly package to match my own idiosyncratic preferences. However I am having trouble understanding how to use Gadfly's statistics in a way that allows for their output to be processed before plotting.

For example, say I want to use the x,y aesthetics produced by Stat.histogram. To add these to a plot, I understand I can include Stat.histogram as an argument in a layer(). But what do I do if I want to use Stat.histogram to calculate the x,y aesthetics, edit them using my own code, and then plot these edited aesthetics?

I'm looking for a function like load_aesthetics(layer(x=x, Stat.histogram)), or a field like layer(x=x, Stat.histogram).aesthetics.


Solution

  • Building off @bjarthur's answer, I wrote the below function.

    "Return the aesthetics produced by a Gadfly Statistic object."
    function process_statistic(statistic::Gadfly.StatisticElement,
                               input_aesthetics::Dict{Symbol,<:Any}
                               )
    
        # Check that enough statistics have been provided.
        required_aesthetics = Gadfly.input_aesthetics(statistic)
        for required_aesthetic in required_aesthetics
            if required_aesthetic ∉ keys(input_aesthetics) 
                error("Aesthetic $(required_aesthetic) is required")
            end
        end
    
        # Create the aes object, which contains the statistics.
        aes = Gadfly.Aesthetics()
        [setfield!(aes, key, value) for (key, value) in input_aesthetics]
    
        # These need to be passed to the apply_statistic() function. I do
        # not understand them, and the below code might need to be edited
        # for this function to work in some cases.
        scales = Dict{Symbol, Gadfly.ScaleElement}()
        coord  = Gadfly.Coord.Cartesian()
    
        # This function edits the aes object, filling it with the desired aesthetics.
        Gadfly.Stat.apply_statistic(statistic, scales, coord, aes)
    
        # Return the produced aesthetics in a dictionary.
        outputs = Gadfly.output_aesthetics(statistic)
        return Dict(output => getfield(aes, output) for output in outputs)
    
    end
    

    Example usage:

    process_statistic(Stat.histogram(), Dict(:x => rand(100)))