JuliaPlots / StatsPlots.jl

Statistical plotting recipes for Plots.jl
Other
436 stars 88 forks source link

Raincloud Plots #533

Open mkitti opened 1 year ago

mkitti commented 1 year ago

Raincloud plots are a combination of a half-violin plot, a boxplot, and a dotplot. Should this go into StatsPlots.jl or live in its own package?

Background

image

I've prototype a recipe as follows

    @recipe function f(
        ::Type{Val{:raincloud}},
        plt::AbstractPlot;
        trim = true, #violin
        side = :right, # differs from violin default
        show_mean = false,
        show_median = false,
        quantiles = Float64[],
            notch = false, # boxplot
        whisker_range = 1.5,
        outliers = true,
        whisker_width = :half,
            mode = :density, # dotplot,
        dotshift = 0.2, # raincloud
            boxshift = 0,
        boxfillcolor = :same,
        box_bar_width = 0.25,
        dot_bar_width = 0.25
    )
        x = plotattributes[:x]
        y = plotattributes[:y]

        permute --> (:x, :y)
        markeralpha --> 0.5

        @series begin
            seriestype := violin
            side := side
            trim := trim
            show_mean := show_mean
            show_median := show_median
            quantiles := quantiles
            linecolor --> :match
            seriescolor := plotattributes[:series_plotindex]
            #bandwidth := bandwidth
        end

        for (k,v) in series_list[1].plotattributes
            println(k," = ", v)
        end

        @series begin
            primary := false
            label := :none
            seriestype := boxplot
            notch := notch
            whisker_range := whisker_range
            outliers := outliers
            whisker_width := whisker_width
            bar_width --> box_bar_width
            whisker_width --> :match
            seriescolor := plotattributes[:series_plotindex]
            if side == :right
                side := :left
                x := x .- boxshift
            elseif side == :left
                side := :right
                x := x .+ boxshift
            end
            if boxfillcolor != :same
                fillcolor := boxfillcolor
            end
        end

        @series begin
            primary := false
            seriestype := dotplot
            mode := mode
            seriescolor := plotattributes[:series_plotindex]
            bar_width --> dot_bar_width
            if side == :right
                side := :left
                x := x .- dotshift
            elseif side == :left
                side := :right
                x := x .+ dotshift
            end
        end
    end
    Plots.@shorthands raincloud
mkitti commented 1 year ago

@BeastyBlacksmith do you think a raincloud recipe would make sense to add directly to StatsPlots.jl or would it better for it to be a separate package?

BeastyBlacksmith commented 1 year ago

thats a bit on you. I would accept a PR adding this to StatsPlots.jl given that you're in for maintaining that.

mkitti commented 1 year ago

I might pursue a dual track strategy of providing a stable version of raincloud here but also iterating upon it more quickly in a distinct package.