-
-
Notifications
You must be signed in to change notification settings - Fork 111
Document the Styling Options #1574
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR updates the API reference guide by documenting the new Styling Options, specifically highlighting the fontscale option. Key changes include:
- Repositioning the fontscale documentation block in hvplot/converter.py.
- Updating the option arrays to reflect the new organization of fontscale.
- Adding a link and navigation entry for Styling Options in the documentation page.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
File | Description |
---|---|
hvplot/converter.py | Moved the fontscale documentation from the Size And Layout section and adjusted its placement in option lists. |
doc/ref/plotting_options/index.md | Added a documentation link for Styling Options and updated navigation to include styling options. |
Comments suppressed due to low confidence (2)
hvplot/converter.py:226
- The fontscale documentation was removed from the Size And Layout Options block and reinserted later. Please confirm that this repositioning clearly conveys its usage and grouping alongside other styling options.
- fontscale : number
hvplot/converter.py:520
- Removing 'fontscale' from this option list and later re-adding it in a different section may lead to confusion. Verify that the ordering of options remains clear for future maintenance.
- 'fontscale',
" cmap='viridis',\n", | ||
" clim=(4.5, 6.5),\n", | ||
" title=\"Earthquakes with Clipped Magnitude Scale\"\n", | ||
") # It doesn't look like it worked" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clim
keyword used in the example doesn't seem like it changed anything. I'm open to a better example that shows it working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please open an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit uncomfortable with the fact that, except fontsize
and fontscale
, these styling options are effectively color spec/mapping options.
Should we rename it Color Options and move the font options elsewhere? I would also love if we could have a place where we can add more information on colormaps (display the default ones, show a list of colormaps users can pick from, etc.).
"df = hvsampledata.penguins(\"pandas\")\n", | ||
"\n", | ||
"# Color by species column\n", | ||
"df.hvplot.scatter(\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add other examples that show how to set color with the other options it accepts? Single color name, list of colors, array, etc.
"metadata": {}, | ||
"source": [ | ||
"(option-color)=\n", | ||
"## `color`\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to explain somewhere the difference between color
and by
. See also https://discourse.holoviz.org/t/use-color-instead-of-by-when-possible/6784
"(option-cmap)=\n", | ||
"## `cmap`\n", | ||
"\n", | ||
"The `cmap` option controls the colormap used when mapping numerical or categorical data values to color. It supports:\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add examples showing how to use all these options?
"- Named colormaps (e.g., 'viridis', 'plasma', 'coolwarm')\n", | ||
"- Lists of color strings or hex codes (for custom sequences)\n", | ||
"- Dictionaries (for categorical color mappings)\n", | ||
"- Colormap objects from Matplotlib or HoloViews\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to include links.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Links to the color palettes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Links and/or additional information to guide a user to find and use these colormap objects (imagine a user who has no clue about all this).
"- Dictionaries (for categorical color mappings)\n", | ||
"- Colormap objects from Matplotlib or HoloViews\n", | ||
"\n", | ||
"hvPlot selects a default colormap based on the data type, but cmap lets you override this behavior. Only one of `cmap`, `colormap`, or `color_key` should be used at a time." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we reference the default colormaps here too or is it enough to have them in the docstring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will add it in the note differentiating by
and color
"The `fontsize` option sets the font size for different text elements in the plot. It can be:\n", | ||
"- A single value (e.g. 12, '14pt', or '10px') to apply to all text.\n", | ||
"- A dictionary to control individual elements like title, axes labels, or ticks.\n", | ||
"Example: {'title': '15pt', 'xlabel': '12pt', 'ylabel': '12pt', 'ticks': 10}\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm that looks very Bokeh specific. Does it work too with Matplotlib? I'd suggest adding a Matplotlib example here .
"# Simulate discrete values by binning magnitude\n", | ||
"df['mag_bin'] = df['mag'].round()\n", | ||
"\n", | ||
"df.hvplot.scatter(\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a plot with rescale_discrete_levels=False
(True is the default) so people can compare.
"plot1 = ds.hvplot.image(width=350)\n", | ||
"plot2 = ds.hvplot.image(robust=True, width=350)\n", | ||
"\n", | ||
"plot1 + plot2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use this example from xarray, it makes it more obvious robust
can help with outliers https://docs.xarray.dev/en/latest/user-guide/plotting.html#robust
"ds = hvsampledata.air_temperature(\"xarray\")\n", | ||
"# Select a single date and convert to Celsius to get\n", | ||
"# both negative and positive values around 0\n", | ||
"data = ds.sel(time='2014-02-25 12:00') - 273\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"data = ds.sel(time='2014-02-25 12:00') - 273\n", | |
"data = ds.sel(time='2014-02-25 12:00') - 273.15\n", |
"ds = hvsampledata.air_temperature(\"xarray\").sel(time=\"2014-02-25 12:00\")\n", | ||
"\n", | ||
"plot1 = (ds - 273).hvplot.image(width=350, title=\"Default check for symmetry\")\n", | ||
"plot2 = (ds - 273).hvplot.image(check_symmetric_max=10, width=350, title=\"Avoid symmetry check above 10\")\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ds = hvsampledata.air_temperature(\"xarray\").sel(time=\"2014-02-25 12:00\")\n", | |
"\n", | |
"plot1 = (ds - 273).hvplot.image(width=350, title=\"Default check for symmetry\")\n", | |
"plot2 = (ds - 273).hvplot.image(check_symmetric_max=10, width=350, title=\"Avoid symmetry check above 10\")\n", | |
"da = hvsampledata.air_temperature(\"xarray\").sel(time=\"2014-02-25 12:00\") - 273.15\n", | |
"\n", | |
"plot1 = da.hvplot.image(width=350, title=\"Default check for symmetry\")\n", | |
"plot2 = da.hvplot.image(check_symmetric_max=10, width=350, title=\"Avoid symmetry check above 10\")\n", |
I'd say let's finish with documenting all the options then we can decide holistically how and what to re-arrange. |
Thanks for the review @maximlt . This looks much better now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I liked a lot many of the changes you made. Left a few comments part of this review.
"\n", | ||
"- **`color='<categorical column name>'`** assigns colors *within a single plot* based on the values in the categorical column using the default `glasbey_category10` colormap. You can customize the colormap using the `cmap` keyword like in the examples above. This maps the values in the categorical column to colors using the specified colormap.\n", | ||
"\n", | ||
"- **`by='<categorical column name>'`** splits the data into multiple groups and creates an [overlay](inv:holoviews#holoviews.core.element.NdOverlay) of plots, one per unique value in the column. However, it does **not** honor the `cmap` you provide. Instead, it uses a default color cycle (`glasbey_hv`) to assign colors per group.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh wait isn't that a bug?
However, it does not honor the
cmap
you provide. Instead, it uses a default color cycle (glasbey_hv
) to assign colors per group.\
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh, I don't know or can't remember if it's a bug or it's by design. This is just the result of me trying out all the different options and combinations and writing out what I see.
Edit: I asked ChatGPT and got a better explanation:
"""
When you use by='<categorical column>'
, hvPlot groups the data and produces an overlay of plots (NdOverlay or NdLayout). Each group becomes a separate layer, and the plotting system (e.g. HoloViews + Bokeh) assigns a color to each layer via a style cycle — not via colormap mapping like cmap='viridis'
.
⸻
So what happens when you provide a cmap?
• If cmap is a named colormap (like 'viridis', 'kbc_r', etc.), it is ignored because these colormaps are designed for continuous data, and by=
creates discrete overlays.
• If you pass a list of colors, hvPlot automatically wraps it in a Cycle(...), which is used by HoloViews to color the overlaid elements — and that’s why it works. This is expected behavior.
So it’s not a bug — it’s that by
supports color cycling, but not colormap mapping.
"""
"(option-color_key)=\n", | ||
"## `color_key`\n", | ||
"\n", | ||
"The `color_key` option defines a categorical color mapping, primarily used with `datashade=True`. It maps distinct categories in your dataset to specific colors.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we say color_key
should only be used exclusively with datashade=True
? Until we figure out why it needs to be used instead of cmap
(still not clear to me, maybe the answer is in your colormapping notebook?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I will try to re-write the explanation and examples to make it clearer.
"\n", | ||
"For example:\n", | ||
"- `cmap='viridis'` is great for smooth gradients like 'magnitude' or 'depth'.\n", | ||
"- `color_key={'Shallow': 'blue', 'Deep': 'green'}` is best for labeled classes like 'depth_class'.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So for a datashaded plot we cannot use cmap={'Shallow': 'blue', 'Deep': 'green'}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works for categorical columns because internally cmap
becomes color_key
:
if 'cmap' in self._style_opts and self.datashade:
...
if isinstance(cmap, dict):
opts['color_key'] = cmap
else:
opts['cmap'] = process_cmap(cmap, levels, categorical=categorical)
https://github.com/holoviz/hvplot/blob/main/hvplot/converter.py#L1977-L1983
The difference is when you want to map colors for use in continuous columns. I will update the explanation and examples used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok thanks. I'm trying to understand why color_key
is needed, and if not, I'd be really happy to deprecate it (having colormap
and cmap
is already enough...). I am trying to avoid documenting too much a feature I'd rather hide if it doesn't bring much to the table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import hvplot.pandas # noqa\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this cell is required here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which cell?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"import hvsampledata\n",
"\n",
"df = hvsampledata.penguins(\"pandas\")\n",
"df.head(3)"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the cell where the penguins dataset is imported for the examples. If I remove it there, then I'll have to import it twice (once each for the bokeh and mpl examples).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Since df
there serves both plots which are not in the same cell, I wanted to show a snippet of the dataframe before its plotted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think it's strange to call .head(3)
in the middle of this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I can remove that line then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments. The PR needs to be updated to resolve a few conflicts with the main branch.
closes #1573
This PR documents the
Styling Options
in the new API reference guide.