def _add_glyph_defaults(self, cls, props):
from ..models.glyphs import Glyph
if issubclass(cls, Glyph):
if hasattr(cls, "line_alpha"):
props.update(self._line_defaults)
if hasattr(cls, "fill_alpha"):
props.update(self._fill_defaults)
if hasattr(cls, "text_alpha"):
props.update(self._text_defaults)
Is this method using the existence of a line_alpha attribute in a glyph as a short hand way to detect if there a whole set of line attributes associated to that glyph? For example, the Line glyph has properties:
Does this set of properties come as a package whenever you have line_alpha? So
you can create an entry in the theme dict for line_defaults and then set defaults for all
of these attributes; they will be applied to any glyph that has “lines” as characterized by the existence of a line_alpha attribute?
For glyphs, specifically, this is true. It is not true in general for eery Bokeh model class.
So you can create an entry in the theme dict for line_defaults and then set defaults for all
of these attributes; they will be applied to any glyph that has “lines” as characterized by the existence of a line_alpha attribute?
It appears so. If I ever knew about this feature, I’d forgotten it existed. It’s not documented anywhere I can find. Nor do I really see tests for it. If you intend to use this feature I would say it’s highly advisable to open a GitHub issue about making it better / more officially supported.
It did look like a hack, if you’ll forgive me for saying so. I’m not sure if I want to use it, for now I’m really just trying to understand fully how themes are implemented.
Well, the hasattr checks above only happen on Glyphs, for which they are always 100% reliable indicators of which property mixins are present or not. It is important to only apply property values for properties that actually exist on a model, e g. if you try to se line_color on a text glyph that will cause an (intentional, desirable) error. The code above prevents exactly that from happening. Happy to consider a better alternative if you have one.
I’m really just trying to understand fully how themes are implemented.
Taken literally, that’s a very large topic as it intersects all the meta-programming that underpins the cross-runtime properties system. I’m not really certain of the focus of your interest. If you can explain a bit more what you are trying to accomplish that would help.
Short term, I want to improve my theme builder app so that:
you can upload an initial theme that you want to edit
you can save the results of your edits as a theme.yaml file
you can edit the glyph defaults as well as the Plot, Grid, Title, Toolbar, and Axis defaults
Longer term, I imagine a tool that allows you to manipulate the attributes of an existing model graphically – for example, linking the structure graph to the model so that when you click on a node you get the attributes of that node and you can tinker with them and see how they affect the model.
The more philosophical question I’m interested in is how to make the whole process of setting plot options less of an exercise in googling and working through the documentation, and so that the choices are more directly available to you.
This is already the case, for individual glyphs. You can make theme defaults for Circle, or Rect exactly the same as you can or Plot or Axis. The line_defaults features is about customizing defaults for all glyphs, all at once. I think that is a marginally useful feature, but it just needs to be brought under better test and documentation. (Esp. nail down how precedence works).
However you might want to check out and chime in on this existing discussion around making the set of theme-able things more flexible:
BTW I very much like the “save edits in a new theme file” that would be a terrific feature. We had discussed some introspective styling/editing tools in the past but no one was ever able to devote time to it.
I sort of have that feature, but starting from the default theme. You can try it here.
Part of the reason I’m deep in the theme code is that I want to load a theme yaml file and then set all my widgets to the associated defaults and that is a bit of a pain.