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

datashader rasterize not supported? #3780

Open
Jzege opened this issue Feb 13, 2025 · 4 comments
Open

datashader rasterize not supported? #3780

Jzege opened this issue Feb 13, 2025 · 4 comments
Labels
bug Something isn't working

Comments

@Jzege
Copy link

Jzege commented Feb 13, 2025

Describe the bug

Would Marimo be able to support DataShader's rasterise()?

In Jupyter, plots with millions of points can be rasterized before being sent to the browser .

E.g. https://holoviews.org/user_guide/Large_Data.html when converted to Marimo, the rasterized plots are not re-rendered when zoomed in.

Environment

Replace this line with the output of marimo env. Leave the backticks in place.

Code to reproduce

https://holoviews.org/user_guide/Large_Data.html
https://raw.githubusercontent.com/holoviz/holoviews/main/examples/user_guide/15-Large_Data.ipynb

@Jzege Jzege added the bug Something isn't working label Feb 13, 2025
@mscolnick
Copy link
Contributor

@Jzege, what specifically is not supported?

I currently am running the example you linked, and it seems like its working:

Image

@Jzege
Copy link
Author

Jzege commented Feb 14, 2025

Hello @mscolnick,

In the initial state, both Jupyter and Marimo will render the same thing:

Image

Try zooming in (using another example so the difference is clearer):
Jupyter (points are re-rendered smaller):

Image

Marimo (points scale up and become pixelated):

Image

@mscolnick
Copy link
Contributor

mscolnick commented Feb 14, 2025

Thanks for clarifying. Just for reference, here is a smaller version of the ipynb notebook converted to marimo

Details

import marimo

__generated_with = "0.11.4"
app = marimo.App(width="medium")


@app.cell
def _():
    import datashader as ds
    import holoviews as hv
    import numpy as np
    import pandas as pd
    from holoviews import opts
    from holoviews.operation import decimate
    from holoviews.operation.datashader import (
        datashade,
        dynspread,
        rasterize,
        shade,
        spread,
    )
    from holoviews.operation.resample import ResampleOperation2D

    hv.extension("bokeh", "matplotlib", width=100)
    decimate.max_samples = 1000
    dynspread.max_px = 20
    dynspread.threshold = 0.5
    ResampleOperation2D.width = 500
    ResampleOperation2D.height = 500


    def random_walk(n, f=5000):
        """Random walk in a 2D space, smoothed with a filter of length f"""
        xs = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f) / f).cumsum()
        ys = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f) / f).cumsum()
        xs = xs + 0.1 * np.sin(0.1 * np.array(range(n - 1 + f)))
        xs = xs + np.random.normal(0, 0.005, size=n - 1 + f)
        ys = ys + np.random.normal(0, 0.005, size=n - 1 + f)
        return np.column_stack([xs, ys])


    def random_cov():
        """Random covariance for use in generating 2D Gaussian distributions"""
        A = np.random.randn(2, 2)
        return np.dot(A, A.T)


    def time_series(T=1, N=100, mu=0.1, sigma=0.1, S0=20):
        """Parameterized noisy time series"""
        dt = float(T) / N
        t = np.linspace(0, T, N)
        W = np.random.standard_normal(size=N)
        W = np.cumsum(W) * np.sqrt(dt)
        X = (mu - 0.5 * sigma**2) * t + sigma * W
        S = S0 * np.exp(X)
        return S
    return (
        ResampleOperation2D,
        datashade,
        decimate,
        ds,
        dynspread,
        hv,
        np,
        opts,
        pd,
        random_cov,
        random_walk,
        rasterize,
        shade,
        spread,
        time_series,
    )


@app.cell
def _(hv, np, random_walk):
    np.random.seed(1)
    points = hv.Points(
        np.random.multivariate_normal((0, 0), [[0.1, 0.1], [0.1, 1.0]], (1000,)),
        label="Points",
    )
    paths = hv.Path([random_walk(2000, 30)], kdims=["u", "v"], label="Paths")

    points + paths
    return paths, points


@app.cell
def _(hv, np, random_walk):
    np.random.seed(1)
    points_1 = hv.Points(
        np.random.multivariate_normal((0, 0), [[0.1, 0.1], [0.1, 1.0]], (1000000,)),
        label="Points",
    )
    paths_1 = hv.Path(
        [0.15 * random_walk(100000) for i in range(10)],
        kdims=["u", "v"],
        label="Paths",
    )
    return paths_1, points_1


@app.cell
def _(datashade, decimate, points_1, rasterize):
    points2 = decimate(points_1, dynamic=False, max_samples=3000)
    points2.opts(color="green", size=6, marker="s")
    (
        points2
        + rasterize(points2).relabel("Rasterized")
        + datashade(points2).relabel("Datashaded")
    )
    return (points2,)


@app.cell
def _(datashade, points2, rasterize, spread):
    w = 225

    (
        points2
        + spread(rasterize(points2, width=w, height=w), px=4, shape="square")
        .opts(cmap=["green"])
        .relabel("Rasterized")
        + spread(
            datashade(points2, width=w, height=w, cmap=["green"]),
            px=4,
            shape="square",
        ).relabel("Datashaded")
    )
    return (w,)


@app.cell
def _():
    import bokeh.palettes as bp

    greens = bp.Greens[256][::-1][64:]
    return bp, greens


@app.cell
def _(datashade, greens, points2, rasterize, spread, w):
    (
        points2
        + spread(rasterize(points2, width=w, height=w), px=4, shape="square")
        .opts(cmap=greens, cnorm="eq_hist")
        .relabel("Rasterized")
        + spread(
            datashade(points2, width=w, height=w, cmap="green", cnorm="eq_hist"),
            px=4,
            shape="square",
        ).relabel("Datashaded")
    )
    return


@app.cell
def _():
    import marimo as mo
    return (mo,)


if __name__ == "__main__":
    app.run()

@philippjfr, do you know if the bokeh rasterize features use something in Panel that hasn't been implemented yet in marimo.

@mb-915
Copy link
Contributor

mb-915 commented Feb 14, 2025

Hello, I opened a discussion recently for the same issue: #3751 , containing a minimal example using hvplot.

What is strange is that hvplot downsample work on wasm but not on native. (I could not try with datashading, though, as the datashader package is not supported by pyodide).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants