Makie.jl icon indicating copy to clipboard operation
Makie.jl copied to clipboard

Plots.jl recipes

Open asinghvi17 opened this issue 5 years ago • 19 comments

Plots.jl has a lot of small, easy-to-implement convenience functions and recipes that would be nice to have in AbstractPlotting, or StatsMakie.

  • [ ] stephist:
    stephist(x)
    stephist(x)

Make a histogram step plot (bin counts are represented using horizontal lines
instead of bars). See `histogram`. 
  • [ ] scatterhist:
    scatterhist(x)
    scatterhist!(x)

Make a histogram scatter plot (bin counts are represented using points 
instead of bars). See `histogram`. 
  • [x] sticks:
    sticks(x,y)
    sticks!(x,y)

Draw a stick plot of y vs x. 

sticks

  • [ ] hexbin: Note that Plots doesn't seem to have support for this.
    hexbin(x,y)
    hexbin!(x,y)

Make a hexagonal binning plot (a histogram of the observations `(x[i],y[i])` 
with hexagonal bins)
  • [x] hline:
    hline(y)
    hline!(y)

Draw horizontal lines at positions specified by the values in 
the AbstractVector `y`
  • [x] vline:
    vline(x)
    vline!(x)

Draw vertical lines at positions specified by the values in 
the AbstractVector `x`
  • [ ] ohlc:
    ohlc(x,y::Vector{OHLC})
    ohlc!(x,y::Vector{OHLC})

Make open-high-low-close plot. Each entry of y is represented by a vertical 
segment extending from the low value to the high value, with short horizontal 
segments on the left and right indicating the open and close values, respectively.
  • [ ] curves:
    curves(x,y)
    curves!(x,y)

Draw a Bezier curve from `(x[1],y[1])` to `(x[end],y[end])` 
with control points `(x[2],y[2]), ..., (x[end-1],y[end]-1)`
  • [x] pie: Plot a pie diagram

  • [ ] areaplot:

    areaplot([x,] y)
    areaplot!([x,] y)
Draw a stacked area plot of the matrix y.

asinghvi17 avatar Jun 25 '19 10:06 asinghvi17

Implementation for sticks (needs to be turned into a recipe but you get the picture):

function sticks!(scene, x, y)
for (i, j) in zip(x, y)
    linesegments!(scene, (Point2f0(i, min(j, 0)), Point2f0(i, max(j, 0)))
end
end

sticks-makie

This could use a LinesegmentBuffer to be more performant as well.

asinghvi17 avatar Jun 25 '19 10:06 asinghvi17

Here's GR.jl's (polar) axis drawing code, for reference.

https://github.com/jheinen/GR.jl/blob/9edecc09594ac855bae70113a6fd452db12c5ea0/src/jlgr.jl#L414-L526

function draw_polar_axes()
    viewport = plt.kvs[:viewport]
    diag = sqrt((viewport[2] - viewport[1])^2 + (viewport[4] - viewport[3])^2)
    charheight = max(0.018 * diag, 0.012)


    window = plt.kvs[:window]
    rmin, rmax = window[3], window[4]


    GR.savestate()
    GR.setcharheight(charheight)
    GR.setlinetype(GR.LINETYPE_SOLID)


    tick = 0.5 * GR.tick(rmin, rmax)
    n = round(Int, (rmax - rmin) / tick + 0.5)
    for i in 0:n
        r = float(i) / n
        if i % 2 == 0
            GR.setlinecolorind(88)
            if i > 0
                GR.drawarc(-r, r, -r, r, 0, 359)
            end
            GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
            x, y = GR.wctondc(0.05, r)
            GR.text(x, y, string(signif(rmin + i * tick, 12)))
        else
            GR.setlinecolorind(90)
            GR.drawarc(-r, r, -r, r, 0, 359)
        end
    end
    for alpha in 0:45:315
        a = alpha + 90
        sinf = sin(a * π / 180)
        cosf = cos(a * π / 180)
        GR.polyline([sinf, 0], [cosf, 0])
        GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
        x, y = GR.wctondc(1.1 * sinf, 1.1 * cosf)
        GR.textext(x, y, string(alpha, "^o"))
    end
    GR.restorestate()
end

Seems that the logic would be easy enough to port to AbstractPlotting.

asinghvi17 avatar Jul 01 '19 16:07 asinghvi17

Plots.jl bezier curves: https://github.com/JuliaPlots/Plots.jl/blob/2816b1128f2d2b2fdba5b170facd316954eb61e2/src/recipes.jl#L280-L339

asinghvi17 avatar Jul 03 '19 05:07 asinghvi17

For vline and hline, is there a way to get the Scene's limits as an Observable (or, in general, a way to manipulate the Scene within the plotting command that doesn't involve bypassing the recipe pipeline and creating a function vline!(scene, xcoord; linesegment_kwargs...))?

asinghvi17 avatar Jul 03 '19 06:07 asinghvi17

@jheinen, this doesn't seem to be in the GR documentation - what does gr_ wctondc (from the C-API) do?

asinghvi17 avatar Aug 02 '19 06:08 asinghvi17

gr_wctondc converts the user's "world coordinates" to "normalized device coordinates" [0, 1]

jheinen avatar Aug 02 '19 06:08 jheinen

Thanks! Will look into the polar axis adaptation further.

asinghvi17 avatar Aug 02 '19 07:08 asinghvi17

Hi, could I ask what the progress on this has been like / what the status of this is? I would be interested in helping out if you need help --- I'm guessing that it won't be very hard or require metaprogramming skills (though please correct me if I'm wrong)!

ym-han avatar Aug 03 '21 17:08 ym-han

I have done a bit of work for a hexbin plot (everything I had imagined should work fine except the labelling for the colorbar with the logscale -> image: bottom right) . I am not totally sure if I had done everything right with the Observables, is there an easy way to test this? image

TabeaW avatar Dec 01 '21 15:12 TabeaW

That looks great :)

is there an easy way to test this?

Make an animation with an observable? Or what do you mean?

SimonDanisch avatar Dec 01 '21 15:12 SimonDanisch

Yes, exactly. I tried it, but maybe I mixed something up with the observables because I get an error LoadError: Metadata array needs to have same length as data. Found 7218 data items, and 4650 metadata items

TabeaW avatar Dec 03 '21 08:12 TabeaW

Nevermind, managed it, should work now :)

TabeaW avatar Dec 03 '21 10:12 TabeaW

Very cool, is this going to be a PR?

jkrumbiegel avatar Dec 03 '21 10:12 jkrumbiegel

Hi there!

I wonder if there is any progress regarding areaplot

I can try to help if someone gives me a process on how to start (should I try to port things from plots.jl?)

Azzaare avatar Jul 26 '22 08:07 Azzaare

I guess one can do that with: band(1:10, 0, rand(10))?

SimonDanisch avatar Jul 26 '22 09:07 SimonDanisch

Yeah pretty much, since one can get the transformed plot limits from the model matrix theoretically it could be done in a recipe. However, for the best implementation this should probably wait until we have a better interface for using Axis-level attributes in recipes, so that the palette can be shared.

asinghvi17 avatar Jul 26 '22 10:07 asinghvi17

I see. I will try to use a workaround with band while waiting for the official recipe!

Thanks

EDIT: band did the trick

Azzaare avatar Jul 26 '22 12:07 Azzaare

Just for the follow-up, the second Axis in the video is the result of using band. Thanks again.

I assume you don't need a MWE, but I can write one to illustrate the areaplot recipe for Makie.

https://user-images.githubusercontent.com/4535131/181269095-914f417a-4349-4de5-8eda-ce22b5451e5f.mp4

Azzaare avatar Jul 27 '22 14:07 Azzaare

A PR with the recipe would be even greater ;)

SimonDanisch avatar Jul 27 '22 14:07 SimonDanisch

hexbin has been added?

Moelf avatar Nov 08 '22 01:11 Moelf