-
Notifications
You must be signed in to change notification settings - Fork 798
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
Make individual colors from Vega color schemes accessible from Altair #2617
Comments
@joelostblom I'm adding some context for what is going on in your script, and linking docs for Vega/Color Schemes The
|
Yes, I agree that this is the better option |
@joelostblom something that might help push this forward is an example that would benefit from more granular access to the color palettes. It could be an existing Maybe even adapting some of the code from @mattijn's work in doc/user_guide/color_usage.rst. |
cc @hydrosquall regarding #2617 (comment) Wondering if you had any thoughts how we could expose the colors within a scheme from I feel like this would be simpler than vega/vega#1938 |
I think vega/vega#1938 might not help with this issue, since Vega expressions do not have knowledge of color palettes. A naive Altair question as I haven't changed it before - do you have the ability to Altair's Python code ask Vega JS runtime for a response, so Vega can be an input to Python rather than just an output? If you can't do it at runtime, you could write a json file into Altair in a CI step. The schemes are queryable through the same API used to add new schemes, so you wouldn't have to do parsing of a JS file from a URL (though that approach is very ingenious). |
Clarification
Apologies @hydrosquall, the link I was drawing between these issues wasn't very clear (my bad). What they have in common is that resolving either could result in new So if that was the goal here, I think we'd be able to get there with less effort than (vega/vega#1938). Re
|
ColorScheme_T: TypeAlias = Literal[ | |
"accent", | |
"category10", | |
"category20", | |
"category20b", | |
"category20c", | |
"dark2", | |
"paired", | |
"pastel1", | |
"pastel2", | |
"set1", | |
"set2", | |
"set3", | |
"tableau10", | |
"tableau20", | |
"observable10", | |
"blues", | |
"tealblues", | |
"teals", | |
"greens", | |
"browns", | |
"greys", | |
"purples", | |
"warmgreys", | |
"reds", | |
"oranges", | |
"turbo", | |
"viridis", | |
"inferno", | |
"magma", | |
"plasma", | |
"cividis", | |
"bluegreen", | |
"bluegreen-3", | |
"bluegreen-4", | |
"bluegreen-5", | |
"bluegreen-6", | |
"bluegreen-7", | |
"bluegreen-8", | |
"bluegreen-9", | |
"bluepurple", | |
"bluepurple-3", | |
"bluepurple-4", | |
"bluepurple-5", | |
"bluepurple-6", | |
"bluepurple-7", | |
"bluepurple-8", | |
"bluepurple-9", | |
"goldgreen", | |
"goldgreen-3", | |
"goldgreen-4", | |
"goldgreen-5", | |
"goldgreen-6", | |
"goldgreen-7", | |
"goldgreen-8", | |
"goldgreen-9", | |
"goldorange", | |
"goldorange-3", | |
"goldorange-4", | |
"goldorange-5", | |
"goldorange-6", | |
"goldorange-7", | |
"goldorange-8", | |
"goldorange-9", | |
"goldred", | |
"goldred-3", | |
"goldred-4", | |
"goldred-5", | |
"goldred-6", | |
"goldred-7", | |
"goldred-8", | |
"goldred-9", | |
"greenblue", | |
"greenblue-3", | |
"greenblue-4", | |
"greenblue-5", | |
"greenblue-6", | |
"greenblue-7", | |
"greenblue-8", | |
"greenblue-9", | |
"orangered", | |
"orangered-3", | |
"orangered-4", | |
"orangered-5", | |
"orangered-6", | |
"orangered-7", | |
"orangered-8", | |
"orangered-9", | |
"purplebluegreen", | |
"purplebluegreen-3", | |
"purplebluegreen-4", | |
"purplebluegreen-5", | |
"purplebluegreen-6", | |
"purplebluegreen-7", | |
"purplebluegreen-8", | |
"purplebluegreen-9", | |
"purpleblue", | |
"purpleblue-3", | |
"purpleblue-4", | |
"purpleblue-5", | |
"purpleblue-6", | |
"purpleblue-7", | |
"purpleblue-8", | |
"purpleblue-9", | |
"purplered", | |
"purplered-3", | |
"purplered-4", | |
"purplered-5", | |
"purplered-6", | |
"purplered-7", | |
"purplered-8", | |
"purplered-9", | |
"redpurple", | |
"redpurple-3", | |
"redpurple-4", | |
"redpurple-5", | |
"redpurple-6", | |
"redpurple-7", | |
"redpurple-8", | |
"redpurple-9", | |
"yellowgreenblue", | |
"yellowgreenblue-3", | |
"yellowgreenblue-4", | |
"yellowgreenblue-5", | |
"yellowgreenblue-6", | |
"yellowgreenblue-7", | |
"yellowgreenblue-8", | |
"yellowgreenblue-9", | |
"yellowgreen", | |
"yellowgreen-3", | |
"yellowgreen-4", | |
"yellowgreen-5", | |
"yellowgreen-6", | |
"yellowgreen-7", | |
"yellowgreen-8", | |
"yellowgreen-9", | |
"yelloworangebrown", | |
"yelloworangebrown-3", | |
"yelloworangebrown-4", | |
"yelloworangebrown-5", | |
"yelloworangebrown-6", | |
"yelloworangebrown-7", | |
"yelloworangebrown-8", | |
"yelloworangebrown-9", | |
"yelloworangered", | |
"yelloworangered-3", | |
"yelloworangered-4", | |
"yelloworangered-5", | |
"yelloworangered-6", | |
"yelloworangered-7", | |
"yelloworangered-8", | |
"yelloworangered-9", | |
"darkblue", | |
"darkblue-3", | |
"darkblue-4", | |
"darkblue-5", | |
"darkblue-6", | |
"darkblue-7", | |
"darkblue-8", | |
"darkblue-9", | |
"darkgold", | |
"darkgold-3", | |
"darkgold-4", | |
"darkgold-5", | |
"darkgold-6", | |
"darkgold-7", | |
"darkgold-8", | |
"darkgold-9", | |
"darkgreen", | |
"darkgreen-3", | |
"darkgreen-4", | |
"darkgreen-5", | |
"darkgreen-6", | |
"darkgreen-7", | |
"darkgreen-8", | |
"darkgreen-9", | |
"darkmulti", | |
"darkmulti-3", | |
"darkmulti-4", | |
"darkmulti-5", | |
"darkmulti-6", | |
"darkmulti-7", | |
"darkmulti-8", | |
"darkmulti-9", | |
"darkred", | |
"darkred-3", | |
"darkred-4", | |
"darkred-5", | |
"darkred-6", | |
"darkred-7", | |
"darkred-8", | |
"darkred-9", | |
"lightgreyred", | |
"lightgreyred-3", | |
"lightgreyred-4", | |
"lightgreyred-5", | |
"lightgreyred-6", | |
"lightgreyred-7", | |
"lightgreyred-8", | |
"lightgreyred-9", | |
"lightgreyteal", | |
"lightgreyteal-3", | |
"lightgreyteal-4", | |
"lightgreyteal-5", | |
"lightgreyteal-6", | |
"lightgreyteal-7", | |
"lightgreyteal-8", | |
"lightgreyteal-9", | |
"lightmulti", | |
"lightmulti-3", | |
"lightmulti-4", | |
"lightmulti-5", | |
"lightmulti-6", | |
"lightmulti-7", | |
"lightmulti-8", | |
"lightmulti-9", | |
"lightorange", | |
"lightorange-3", | |
"lightorange-4", | |
"lightorange-5", | |
"lightorange-6", | |
"lightorange-7", | |
"lightorange-8", | |
"lightorange-9", | |
"lighttealblue", | |
"lighttealblue-3", | |
"lighttealblue-4", | |
"lighttealblue-5", | |
"lighttealblue-6", | |
"lighttealblue-7", | |
"lighttealblue-8", | |
"lighttealblue-9", | |
"blueorange", | |
"blueorange-3", | |
"blueorange-4", | |
"blueorange-5", | |
"blueorange-6", | |
"blueorange-7", | |
"blueorange-8", | |
"blueorange-9", | |
"blueorange-10", | |
"blueorange-11", | |
"brownbluegreen", | |
"brownbluegreen-3", | |
"brownbluegreen-4", | |
"brownbluegreen-5", | |
"brownbluegreen-6", | |
"brownbluegreen-7", | |
"brownbluegreen-8", | |
"brownbluegreen-9", | |
"brownbluegreen-10", | |
"brownbluegreen-11", | |
"purplegreen", | |
"purplegreen-3", | |
"purplegreen-4", | |
"purplegreen-5", | |
"purplegreen-6", | |
"purplegreen-7", | |
"purplegreen-8", | |
"purplegreen-9", | |
"purplegreen-10", | |
"purplegreen-11", | |
"pinkyellowgreen", | |
"pinkyellowgreen-3", | |
"pinkyellowgreen-4", | |
"pinkyellowgreen-5", | |
"pinkyellowgreen-6", | |
"pinkyellowgreen-7", | |
"pinkyellowgreen-8", | |
"pinkyellowgreen-9", | |
"pinkyellowgreen-10", | |
"pinkyellowgreen-11", | |
"purpleorange", | |
"purpleorange-3", | |
"purpleorange-4", | |
"purpleorange-5", | |
"purpleorange-6", | |
"purpleorange-7", | |
"purpleorange-8", | |
"purpleorange-9", | |
"purpleorange-10", | |
"purpleorange-11", | |
"redblue", | |
"redblue-3", | |
"redblue-4", | |
"redblue-5", | |
"redblue-6", | |
"redblue-7", | |
"redblue-8", | |
"redblue-9", | |
"redblue-10", | |
"redblue-11", | |
"redgrey", | |
"redgrey-3", | |
"redgrey-4", | |
"redgrey-5", | |
"redgrey-6", | |
"redgrey-7", | |
"redgrey-8", | |
"redgrey-9", | |
"redgrey-10", | |
"redgrey-11", | |
"redyellowblue", | |
"redyellowblue-3", | |
"redyellowblue-4", | |
"redyellowblue-5", | |
"redyellowblue-6", | |
"redyellowblue-7", | |
"redyellowblue-8", | |
"redyellowblue-9", | |
"redyellowblue-10", | |
"redyellowblue-11", | |
"redyellowgreen", | |
"redyellowgreen-3", | |
"redyellowgreen-4", | |
"redyellowgreen-5", | |
"redyellowgreen-6", | |
"redyellowgreen-7", | |
"redyellowgreen-8", | |
"redyellowgreen-9", | |
"redyellowgreen-10", | |
"redyellowgreen-11", | |
"spectral", | |
"spectral-3", | |
"spectral-4", | |
"spectral-5", | |
"spectral-6", | |
"spectral-7", | |
"spectral-8", | |
"spectral-9", | |
"spectral-10", | |
"spectral-11", | |
"rainbow", | |
"sinebow", | |
] |
This is still helpful, but say for example "bluegreen"
we can only know through trial-and-error what was encoded at each stop:
altair/altair/vegalite/v5/schema/_typing.py
Lines 507 to 514 in 82ec269
"bluegreen", | |
"bluegreen-3", | |
"bluegreen-4", | |
"bluegreen-5", | |
"bluegreen-6", | |
"bluegreen-7", | |
"bluegreen-8", | |
"bluegreen-9", |
vega
!= vega-lite
I hadn't noticed before writing this, but we have 300+ color scheme names and that is a huge jump from https://vega.github.io/vega/docs/schemes/
Leads me to think the logic for this would need to be based on vega-lite
, rather than vega
.
Haven't quite worked out where this takes place - maybe related to vega-lite/src/scale.ts
?
Hi @dangotbanned , thanks very much for the clarifications and helpful links around expr evaluation and theme testing. I was thinking that when altair runs in jupyter it could communicate with Vega via the Jupyter widgets API (as we did in this streamlit POC ), but since altair can run without jupyter, this isn't a global solution. I think I see the connection you're drawing between the projects now - if there was a structured (JSON) representation of some Stepping from the code I'm curious about the end goal. If users are able to access the color definitions in python, what would they use it for? Would they be passed directly back into an One alternative devtool if they're not planning to use the colors right away would be to offer this info via a devtool page where you can
Alternately, we could augment the docs so clicking on a color block copies the hex code for that color to clipboard or displays in a tooltip, similar to how other color / design system sites work (e.g. material) |
Ah good find, it looks like those color scheme names originates in ![]() |
No worries, thanks for the detail as well @hydrosquall - interesting POC.
Yeah that's it 🙂
Good question! After some more reading - I'm finding that SchemeParams already solves the issue I had in mind.
Big +1 from me on copy-to-clipboard for the hex color codes! |
Can you run Vega-Lite or Vega at compile time with node and extract the colors into JSON or Python so that you don't need to do anything with javascript at runtime? |
@domoritz that sounds like a good way forward. I'm happy to work on how we integrate whatever the artifact is - but how to generate it is the bit I'm missing |
The rough outline would be to create a javascript file that imports Vega and Vega-Lite, runs whatever code you need to run, and writes a JSON or Python file. Then you can run the javascript file with node. |
I tried to suggest that as well, but it may have gotten lost. Thanks for raising that suggestion again.
I figure it would be something like this // get-vega-colors.js
import vega from 'vega';
import { continuous, discrete } from `vega-scale/src/palettes`;
// write some JS to
const myJsonToExport = {}
// get your palette names by enumerating the keys of continuous and discrete
// for all the color palette names, get the info colors from
// vega.scheme(schemeName)
console.log(myExportJson) Then in your CI script node get-vega-colors.js > my-color-definitions.json |
Ah apologies @hydrosquall yeah it looks like I skimmed over that part 🤦♂ @domoritz, @hydrosquall
For vega-themes itself, I can imagine it might be more ergonomic to define a theme as transformations on scheme - rather than defining multiple variations in a script. |
Vega themes seems like an odd place since it's only tangentially related to schemes. I'd rather make a new package but I think doing it in Altair makes the most sense. |
vl-convert has a get_themes function for retrieving all of the available themes, do we want an analogues |
@jonmmease that could be a good option! Would you be able to get the contents of each scheme/palette that way? |
I haven't looked at this in detail, but if we can write a JavaScript snippet that builds a JavaScript object containing the names and contents of each scheme/pallete then we could retrieve that in Rust/Python. For themes vl-convert runs this var vegaThemes;
import('{vega_themes_url}').then((imported) => {{
vegaThemes = imported;
}})
var themes = Object.assign({}, vegaThemes);
delete themes.version
delete themes.default And then fetches the |
Tasks
Description
I think it would be valuable to make all the individual colors from Vega schemes accessible programmatically from Altair. Since Vega stores them in a single file, we could parse that and create a Python dictionary that could be used to access single colors from each color scheme. Something like this:
Code block
The text was updated successfully, but these errors were encountered: