MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.33k stars 292 forks source link

Plots.jl recipes #368

Open asinghvi17 opened 5 years ago

asinghvi17 commented 5 years ago

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

Make a histogram step plot (bin counts are represented using horizontal lines instead of bars). See histogram.


- [ ] `scatterhist`: 
```julia
    scatterhist(x)
    scatterhist!(x)

Make a histogram scatter plot (bin counts are represented using points 
instead of bars). See `histogram`. 

Draw a stick plot of y vs x.

![sticks](https://user-images.githubusercontent.com/32143268/60090423-f6350a00-975b-11e9-9d4b-d14e95b3655e.png)

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

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

Draw horizontal lines at positions specified by the values in the AbstractVector y


- [x] `vline`: 
```julia
    vline(x)
    vline!(x)

Draw vertical lines at positions specified by the values in 
the AbstractVector `x`

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`: 
```julia
    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)`
asinghvi17 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

asinghvi17 commented 5 years ago

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 commented 4 years ago

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

jheinen commented 4 years ago

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

asinghvi17 commented 4 years ago

Thanks! Will look into the polar axis adaptation further.

ym-han commented 2 years ago

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)!

TabeaW commented 2 years ago

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

SimonDanisch commented 2 years ago

That looks great :)

is there an easy way to test this?

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

TabeaW commented 2 years ago

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 commented 2 years ago

Nevermind, managed it, should work now :)

jkrumbiegel commented 2 years ago

Very cool, is this going to be a PR?

Azzaare commented 1 year ago

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?)

SimonDanisch commented 1 year ago

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

asinghvi17 commented 1 year ago

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.

Azzaare commented 1 year ago

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

Thanks

EDIT: band did the trick

Azzaare commented 1 year ago

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

SimonDanisch commented 1 year ago

A PR with the recipe would be even greater ;)

Moelf commented 1 year ago

hexbin has been added?