Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help implementing datashader-like functionality #443

Closed
cjdoris opened this issue Mar 3, 2020 · 9 comments
Closed

Help implementing datashader-like functionality #443

cjdoris opened this issue Mar 3, 2020 · 9 comments

Comments

@cjdoris
Copy link

cjdoris commented Mar 3, 2020

I'd quite like to incorporate some datashader-like functionality into Makie. Basically, I need to be able to do the following, but it's not clear that it's currently possible in Makie?

  1. Draw an image with one image pixel per screen pixel.
  2. Get the size of the plot area in pixels.
  3. Get the limits of the axes.

Grateful if you could enlighten me on whether this is currently possible.

@asinghvi17
Copy link
Member

You can get the pixel-area of the scene by scene.px_area, and the limits by scene.limits or scene_limits(scene). You can plot all in pixel units by using raw=true as a keyword argument.

@SimonDanisch
Copy link
Member

While this is somewhat true, I'd recommend:

  • get pixel area with pixelarea(scene)
  • only ever use scene_limits(scene)
  • raw=true is just removing to add cameras + axis to the scene automatically, so won't let you plot in pixelspace... You will need Scene(camera=campixel!) for that, which also works well with raw=true to not show any axis etc!

@cjdoris
Copy link
Author

cjdoris commented Mar 4, 2020

Thanks for your replies.

Maybe take a look at the examples at the bottom of https://examples.pyviz.org/heat_and_trees/Heat_and_Trees.html#heat-and-trees-gallery-heat-and-trees to see what I'm aiming for.

That is, I still want to have axes, and maybe those axes will contain points and lines and things like any other plot, but I also want to be able to draw an image in that plot, where the image is produced at exactly the right size (in pixels) for the plot, hence I need to know the limits of the axes and the size of the axes in pixels. I believe pixelarea(scene) is the size of the whole scene, not just the plot area?

@SimonDanisch
Copy link
Member

Hm I guess, there are different ways of doing this... Do you want to use MakieLayout as well? And do you want to zoom in and then update the image that is displayed? Is it very important to map 1 image pixel to screen pixels, or would it just be nice?

@cjdoris
Copy link
Author

cjdoris commented Mar 4, 2020

I'm not familiar with MakieLayout, but from the quick look I've just had, yes!

The 1-1 correspondence between pixels is important: basically the image is a 2D histogram, where each pixel represents a bin, and so we get very fine-grained visualization. And yes, I want to be able to zoom in on regions of the image and have it be recomputed.

@SimonDanisch
Copy link
Member

@jkrumbiegel, this could be kind of easy in makielayouts, no?

@jkrumbiegel
Copy link
Member

jkrumbiegel commented Mar 12, 2020

yeah this is basically all you need:

using Makie
using MakieLayout


scene, layout = layoutscene()

ax = layout[1, 1] = LAxis(scene)

function datashader(limits, pixelarea)
    # return your heatmap data
    # here, I just calculate a sine field as a demo
    xpixels, ypixels = widths(pixelarea)
    xmin, ymin = minimum(limits)
    xmax, ymax = maximum(limits)
    
    [cos(x) * sin(y) for x in LinRange(xmin, xmax, xpixels),
                         y in LinRange(ymin, ymax, ypixels)]
end

xrange = lift(x -> minimum(x)[1] .. maximum(x)[1], ax.limits)
yrange = lift(x -> minimum(x)[2] .. maximum(x)[2], ax.limits)
pixels = lift(datashader, ax.limits, ax.scene.px_area)

heatmap!(ax, xrange, yrange, pixels,
    xautolimits = false, yautolimits = false)

This should work but for some reason doesn't perfectly, something is up with the coverage of the heatmap on the axis for me..

Update: I see what the problem is, the xrange and yrange cut their maximum off if they are written with colon notation, because the step size is implicitly 1. I've edited the example to use .. interval notation, this works perfectly.

@cjdoris
Copy link
Author

cjdoris commented Mar 31, 2020

Just seen this, that's brilliant, works like a charm. Thanks for your help!

@felixcremer
Copy link
Contributor

This is incorporated into Makie with #2883 with an experimental datashader functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants