observablehq / plot

A concise API for exploratory data visualization implementing a layered grammar of graphics
https://observablehq.com/plot/
ISC License
4.13k stars 172 forks source link

Themes #630

Open mkfreeman opened 2 years ago

mkfreeman commented 2 years ago

To support different styles, we could create a set of plot themes (e.g., dark, light, etc.). As a comparison, the ggthemes package has default styles to emulate popular styles like the Wallstreet Journal, FiveThirtyEight, etc.

Perhaps a simple approach would be to define a set of styles in Plot.themes that could be set as the style property in a Plot:

Plot.plot({
    style: Plot.themes.dark
})

Where Plot.themes.dark has a set of key/value pairs describing the style: {background: "black", color: "white",...}

Fil commented 2 years ago

related: #6 #7 #114 #253 #397 #662

awiederkehr commented 2 years ago

Would love to help work on this however I can!

mbostock commented 1 year ago

The new axis mark #1197 will help with this, for example you could have a ggplot2 theme https://github.com/observablehq/plot/pull/1197#issuecomment-1364573933.

Fil commented 1 year ago

Also relevant: https://observablehq.com/@observablehq/custom-plot-themes

Fil commented 1 year ago

Here's a handy response from Mike on the user forum: https://talk.observablehq.com/t/set-global-plot-defaults-for-observable-plot/7797/3

martindaniel4 commented 1 year ago

As a Plot user, that feature would be very useful! Here is also another R package that was relevant to style graphs from a former Airbnb DS - https://github.com/ricardo-bion/ggtech

Fil commented 11 months ago

Textures #903

tophtucker commented 11 months ago

I like Mike’s nice style: Plot.themes.dark suggestion. And it could be prototyped as an ongoing notebook.

It gets trickier when you want to set a default theme across many plots. One can also imagine wanting to set default categorical/sequential/diverging color schemes, etc.

Maybe there could be something like

Plot.defaults({
  style: Plot.themes.dark,
  color: {scheme: {sequential: "blues"}}
})

which would return a new instance of Plot with those defaults? There’d be various difficulties. What’s that object syntax? (Note that I abused the color scheme option.) To name your version Plot in a notebook, would you have to do something like Plot = (await require("@observablehq/plot")).defaults({style: Plot.themes.dark}), or could you take advantage of the built-in Plot?

mbostock commented 11 months ago

Yes, exactly Toph. On Observable, my hope is that you can configure Plot for your workspace and it automatically applies the theme to notebooks in your workspace without you having to edit them. And likewise in vanilla JavaScript, you could call export default Plot.defaults(…) or whatever and import that instead of Plot.

Fil commented 10 months ago

Projections! (suggested in #1111)

mbostock commented 10 months ago

Projections!

What about projections, @Fil? Not sure how this is related to themes.

Fil commented 10 months ago

In that comment I wanted a mechanism to add a few named projections to my "themed" or personalized Plot, similarly to the way we'll be able to add (or modify) color themes. Once we have a theming mechanism in place it will seem natural to want to extend it (progressively) to other hard-coded lists of named option values. Even more so if it's called "defaults" and not "theme".

christophe-g commented 6 days ago

Stumbled across this while trying to adjust my observable colors to my themes.

What about adding a new scheme for categorical color space along the following, using css variables:

export default [
  'var(--plot-color-0)',
  'var(--plot-color-1)',
  'var(--plot-color-2)',
  'var(--plot-color-3)',
  'var(--plot-color-4)',
  'var(--plot-color-5)',
  'var(--plot-color-6)',
  'var(--plot-color-7)',
  'var(--plot-color-8)',
  'var(--plot-color-9)',
]

It would then be the consumer responsibility to set relevant colors - we could provide a helper so that it uses observable10 scheme by default. Handling dark, and customized theme is then pretty easy.

Happy to provide a PR if that makes sense