The Bokeh "default theme"

Dear all,

I am looking for the “default theme” of Bokeh, that is, the defaults that are used for the properties of the various graphical objects, if Bokeh is started without setting bokeh.plotting.curdoc().theme explicitly.
E.g. the value of background_fill_alpha for legends.

It that correct that the defaults are the properties of the classes?
I.e. the value for property “x” for class “C” (say, “background_fill_alpha” for class “Legend”) is first searched in curdoc().theme, and if not found, the value in C.x is used.

Or is there anything else in between curdoc().theme and the class properties?

Thanks in advance!

It’s a bit more complicated than that, because lookups have to keep track of whether a property value has been set explicitly by a user. Values that users set themselves always take precedence over both theme values and “intrinsic” defaults. But it’s also more complicated than that, since .accepts conversion can be specified on property types, and AFIAK these conversions apply to theme values as well, so the actual read property value on an instance may be converted from what is in a theme file.

If you really want to understand things at a low level, you’d have to follow all “getattr”-related the codepaths in these files:

bokeh/src/bokeh/core/has_props.py at branch-3.5 · bokeh/bokeh · GitHub
bokeh/src/bokeh/core/property/descriptors.py at branch-3.5 · bokeh/bokeh · GitHub
bokeh/src/bokeh/core/property/bases.py at branch-3.5 · bokeh/bokeh · GitHub

TLDR Bokeh adds a Python descriptor for every property using a metaclass, and then attribute access is delegated to the property objects via the descriptor protocol. That is what allows for doing conversions, or providing different values based on themes, or whether something has been explicitly set, etc.

If you are just asking a practical question, then yes just reading the value from a new instance using code is the best way to see what any given “default” value is. There is not any single declarative “default stylesheet”. Note there is also the properties_with_values method that can read properties in bulk off of model instances in case that is useful.

FWIW the “default theme” is currently implicit, it is what is baked directly into the properties defined on the model class definitions, e.g. here is an abbreviated example:

class Axis(GuideRenderer):

    axis_label_standoff = Int(default=5, help="...")

This is partly due to history (theme support was only added several years after Bokeh was created) but also due to the fact that some properties have more complex values (e.g. references to other instances or even dynamic per-instance defaults) that cannot be expressed conveniently in a JSON or YAML theme definition.

Bryan,

many thanks for your time in writing such a wonderful response.

Very appreciated and very useful :slight_smile:

1 Like