Open dangotbanned opened 1 month ago
Maybe useful, maybe not, but themes are also known within vl-convert:
import vl_convert as vlc
list(vlc.get_themes().keys())
['carbong10', 'carbong100', 'carbong90', 'carbonwhite', 'dark', 'excel', 'fivethirtyeight', 'ggplot2', 'googlecharts', 'latimes', 'powerbi', 'quartz', 'urbaninstitute', 'vox']
Maybe useful, maybe not, but themes are also known within vl-convert:
import vl_convert as vlc list(vlc.get_themes().keys())
Thanks @mattijn, that seems to end up at https://github.com/vega/vl-convert/blob/89bbda91334494fbcf29144b4c1fe7b6ed18168e/vl-convert-python/src/lib.rs#L1028-L1044
If I've understood this correctly (maybe @jonmmease can correct), this seems like the equivalent of asking vega-lite
what is on the menu?
This would be a pretty simple solve for keeping the Literal
updated.
But would mean depending on vl_convert
during tools/generate_schema_wrapper.py
, to check if we need to update
Related to improving the experience of modifying chart styles is making it easier to modify common elements in existing themes, e.g. setting a larger default font size as tracked in this issue https://github.com/vega/altair/issues/2820 and the various comments linked there. It's a bit outside the scope of what you are suggesting here @dangotbanned but I wanted to link it so that you were aware of some of the previous discussion we've had on similar topics.
If I've understood this correctly (maybe @jonmmease can correct), this seems like the equivalent of asking vega-lite what is on the menu?
Hi @dangotbanned, yes vl-convert vendors the vega-themes JavaScript library (which vega-lite pulls themes from), and extracts the theme definitions from there. I'm in the process of updating it to use the new vega-themes release that includes the carbon themes in https://github.com/vega/vl-convert/pull/178.
I think depending on vl-convert during generate_schema_wrapper.py
is reasonable, It's already a requirement for building the docs and running the image export tests.
My motivation for adding this info to vl-convert was so that we could eventually let Altair users inspect the definitions of these themes to use them as starting points for their own themes. I haven't thought it through in detail, but I wonder if we should inline the full theme definitions during generate_schema_wrapper.py
so we have them in Altair.
If I've understood this correctly (maybe @jonmmease can correct), this seems like the equivalent of asking vega-lite what is on the menu?
Hi @dangotbanned, yes vl-convert vendors the vega-themes JavaScript library (which vega-lite pulls themes from), and extracts the theme definitions from there. I'm in the process of updating it to use the new vega-themes release that includes the carbon themes in vega/vl-convert#178.
Thanks for the explanation @jonmmease! That wasn't what I thought was happening, glad you cleared it up
My motivation for adding this info to vl-convert was so that we could eventually let Altair users inspect the definitions of these themes to use them as starting points for their own themes. I haven't thought it through in detail, but I wonder if we should inline the full theme definitions during
generate_schema_wrapper.py
so we have them in Altair.
I definitely agree with the end goal, but had an alternative way to get there.
Would it be in scope for https://github.com/vega/vega-themes/ to output (during CI) a .json
of all current themes?
I'm thinking it would be quite easy to have one file, mapping the theme names to each config. Especially if we only consider the final export theme-powerbi.ts#L113 - rather than all the parameterization in the full .ts
.
I think depending on vl-convert during
generate_schema_wrapper.py
is reasonable, It's already a requirement for building the docs and running the image export tests.
Looking at the frequency of vega-themes
releases this might be a non-issue, and if bumping all of these is trivial.
However, my hesitation would be that were a new theme added, an altair
user needs the latest altair
which requires vl-convert
to pull the new themes and make a new release, w/ altair
releasing on that new version.
Simply reading the latest .json
from vega-themes
would ensure each release of altair
is always up-to-date. Also wouldn't look out of place with since we already grab the schema from the github https://github.com/vega/altair/blob/95f654fcd036069e1101883d176ec67c6f13fa25/tools/generate_schema_wrapper.py#L39
@jonmmease do you think this would be a reasonable ask?
If not then I think using vl-convert
would be the way to go π
Are you picturing that this .json
file would be loaded only when generate_schema_wrapper.py
runs, or also at runtime? I would lean against loading it at runtime since this introduces a runtime dependency on an internet connection, which we don't want to introduce if we can help it. vl-convert vendors everything it needs so that operations like image export work offline.
But if it's only at code generation time, then that seems perfectly reasonable, though I don't know if there are a lot of benefits over using vl-convert in that case.
Are you picturing that this
.json
file would be loaded only whengenerate_schema_wrapper.py
runs, or also at runtime?
Apologies for being unclear, yeah I meant updated at on each generate_schema_wrapper.py
run. Absolutely agree on avoiding needing an internet connection.
But if it's only at code generation time, then that seems perfectly reasonable, though I don't know if there are a lot of benefits over using vl-convert in that case.
That's fair, you certainly know more than I do about the ease of coordinating between the two projects.
I wonder if we should inline the full theme definitions during
generate_schema_wrapper.py
so we have them in Altair
If you can figure this out with vl-convert
we should go with that @jonmmease
Just finished reading through https://github.com/vega/vl-convert/pull/39 and feel dumb for not realising vl_convert
already can return the full theme definitions.
Since @mattijn's https://github.com/vega/altair/issues/3519#issuecomment-2267624907 I thought vlc.get_themes()
was only returning the names π€¦ββοΈ
Please disregard all of https://github.com/vega/altair/issues/3519#issuecomment-2269004203
- Creating a
TypedDict
for the theme config object
@binste I briefly mentioned in https://github.com/vega/altair/pull/3523#issuecomment-2273140252 that this might take a while for me to do.
Thought I'd add some notes here, prior to a PR, in case you (or anyone else) were more familiar with codegen.py
So far, these seem like the relevant starting points/outputs:
core.Config
generate_vegalite_config_mixin
generate_vegalite_mark_mixin
While reading through these, core.Config
seemed like an example where we could be more specific in the type annotations - rather than SchemaBase
.
Not sure how common the scenario would be, but writing some logic to use the actual type when:
len(SchemaInfo.title) <= some_limit
For cases like the above, it would mean a user wouldn't need to refer to the docs as often - if their IDE/etc can utilise the annotations
It's exciting to see this π I'll try to contribute through comments soon. For now, just some drive-by thoughts in case you find them useful:
How could the bigger picture UX look like for themes?
ThemeConfig
typed dict, as you are now developing it in #3536, gives all the flexibility but can be overwhelming for new joiners.ThemeConfig
. Or is this hiding complexity which should not be hidden? It could have arguments/methods to set some commonly used characteristics such as:
view.strokeWidth: 0
)Writing this out, we should have a solution which allows for the full flexibility (dict/typed dict) and I do see the appeal of a light convenience function/class to get started with a new theme.
Inspiration
@binste I will try to go through https://github.com/vega/altair/issues/3519#issuecomment-2292010192 in detail tomorrow, but wanted to say really appreciate all the thought you've put in to the UX!
Just finished the most significant part of #3536 with bb99389
(#3536).
Still a way off from review, but the end-result is ready for playing around with π
Maybe we want a "theme builder" class instead/a function which produces the
ThemeConfig
. Or is this hiding complexity which should not be hidden? It could have arguments/methods to set some commonly used characteristics such as ...
Sounds interesting! I'll say I fully didn't anticipate the level of customization you can do with a theme. Having the option to ease into/simplify seems worth exploring IMO
@binste I think the key missing component of theme documentation is demonstrating patterns like in https://github.com/dangotbanned/altair/blob/c35324d5cd15bf04fbc47efa611837eefd20e138/altair/vegalite/v5/theme.py#L77-L133
This wouldn't require any additional functions/classes and would be "teaching" theme generation in a way that closely mirrored vega-themes
:
Looking at seaborn.set_theme, this is pretty much the same idea but with 1 of 4 scale constants applied in sns.rcmod.plotting_context
As I understand, the `alt.Chart.configure_` calls are being used to avoid registering + enabling a theme - which could override a user's custom theme. These work fine in isolation, but AFAIK would have issues if a user were to layer/concat/facet the result - since `config` is only valid at the top-level. You might want to add tests to see if [these ops](https://github.com/vega/altair/blob/df14929075b45233126f4cfe579c139e0b7f0559/tests/vegalite/v5/test_api.py#L332-L361) would still be possible - https://altair-viz.github.io/user_guide/customization.html#global-config - https://altair-viz.github.io/user_guide/configuration.html#top-level-chart-configuration Using a theme would have the benefit of deferring these config settings until the `Chart` is rendered - placing them in the [top-level only](https://github.com/vega/altair/blob/df14929075b45233126f4cfe579c139e0b7f0559/altair/vegalite/v5/api.py#L1837). --- It might be worth seeing if we can come to a good solution to this as part of https://github.com/vega/altair/issues/3519 since we have already [discussed](https://github.com/pola-rs/polars/pull/17995#issuecomment-2282795126) [issues](https://github.com/pola-rs/polars/pull/17995#issuecomment-2282802508) with the theme route
What is your suggestion?
Following discussion w/ @binste in
Original comment relating to autocomplete
For a *long-term* solution, I'd want to: - Extract the names directly from [source](https://github.com/vega/vega-themes/blob/main/src/index.ts) as (`VegaThemes: Literal[...]`) - Define `altair` themes as (`AltairThemes: Literal["opaque", ...`) - [Your comment](https://github.com/pola-rs/polars/pull/17995#issuecomment-2266683585) which was what sparked this PR π - [changing-the-theme](https://altair-viz.github.io/user_guide/customization.html#changing-the-theme) which states a plan to add more in the future - ~~`_ThemeName`~~ -> `DefaultThemes: TypeAlias = AltairThemes | VegaThemes` - Annotate `themes.enable(name: DefaultThemes)` - Revisit the need for defining this across two `theme.py` modules, as part of https://github.com/vega/altair/issues/3337The larger goal would be making the process of creating/choosing a theme as easy as possible.
After linking to the existing docs in https://github.com/pola-rs/polars/pull/17995#issuecomment-2266657656, I thought we could improve both the docs and the UX itself.
Ideas
Feat
3586
3536
3526
3523
Docs
3528
altair
?I know that @binste had some ideas as well, maybe others do too