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

Support extension/addon mechanism for creating custom marks #3187

Open
joelostblom opened this issue Sep 12, 2023 · 3 comments
Open

Support extension/addon mechanism for creating custom marks #3187

joelostblom opened this issue Sep 12, 2023 · 3 comments

Comments

@joelostblom
Copy link
Contributor

joelostblom commented Sep 12, 2023

I think it would be really helpful if it was possible to create custom marks outside altair/vega-lite that would be accessible through separate packages. ggplot has a similar mechanism where anyone can create a geom that is compatible with the base ggplot canvas, e.g. https://ggforce.data-imaginist.com/reference/geom_sina.html.

This could either happen at the vega-lite or altair level. An advantage with having it on the vega-lite level is that it becomes available in all languages that has a VL wrapper, not just python. An advantage with having it on the altair level is that it lower the barrier of entry for contributions significantly and provides access to a more powerful (scientific) ecosystem of other packages that could be used to create the marks (e.g. it would be easy to implement something like this vega/vega-lite#8067, in fact I already have a python implementation for that but I have a poor knowledge of what would be required to implement that directly in VL). This would also allow something like altair_tiles to integrate directly with altair as its own mark

In contrast to ggplot where each geom is a separate global function, this will be trickier in altair since marks are method on the base Chart class. I am not sure what an implementation would look like, maybe some monkey patching like this or using a library like mock or wrapt?

I believe we discussed this sometime in the past, but I couldn't find a dedicated issue for it. I also remember talking to @nicolaskruchten about something like this in the past

@jonmmease
Copy link
Contributor

Thanks for writing this up @joelostblom. Yeah, I agree it would be great to figure out a Python extension point.

Something I'm not sure of yet is what API a custom mark has to work with. Should a custom mark simply produce a combination of regular Vega-Lite marks (maybe in a "layer" container)?

We could allow registration of custom chart.mark_{custom} methods that would declare their inputs and return a Chart or LayerChart. This is a question for @binste, but would a chart.mark_tiles(...) method make sense as the entry point for creating map tile layers? I'm not sure how the .encode() part of the API should work for custom marks though.

If we figure out an extension point that allows altair_tiles to remain a standalone package but feel built into Altair, then I would guess we would find other uses for it.

I wonder if we could implement some of the gridded data support we've talked about using a custom chart.mark_raster() mark that would work with charts that wrap numpy/xarray data.

@jcmkk3
Copy link

jcmkk3 commented Sep 13, 2023

I would imagine that something like pandas "official" version of monkey patching or pandas_flavor would be best with the current API.

This is an area where the seaborn.objects or Observable Plot approach have some advantages. They use a style more like scikit-learn, which allows easy extension by other libraries. Plot even has a "marks" mark, which is kind of like a composite estimator in scikit-learn.

@binste
Copy link
Contributor

binste commented Sep 15, 2023

Really cool ideas! I'm having trouble making up my mind about the API for altair_tiles so I definitely appreciate the brainstorming here (see also vega/altair_tiles#8). So far I thought that mark_geoshape(tile=True) would be a great syntax to aim for. I've proposed this in vega/vega-lite#8885. Reasoning:

  • It's in line with mark_line(point=True) which, when being compiled to Vega, gets extended to a layered chart with line and point marks. mark_geoshape(tile=True) would be extended to a geoshape and an image layer.
  • The tiles themselves don't work without a geoshape mark present in the Vega-Lite specification
  • Users probably usually want to plot some geo data and then just add tiles as simple as possible. The case were a user wants only tiles without geoshapes is much rarer (and does not work as mentioned above, although one can simply add an empty geoshape layer as a workaround, something I do in altair_tiles). With mark_tiles, a user would need to do something like base.mark_geoshape() + base.mark_tiles() instead of base.mark_geoshape(tile=True)

Of course a mark_tile could also generate a layered chart but as a user I'd not expect that a mark can cause a transition from alt.Chart to alt.LayerChart. See the altair_tile docs for the current API.

But maybe I'm trying too hard to keep the Altair API in line with Vega-Lite.

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

No branches or pull requests

4 participants