Closed jlstevens closed 7 months ago
Not sure whether I'm convinced one way or another, but I would guess a flat syntax like 'hover+time+voltage-temperature' would be simpler to work with.
Definitely don't like using some special syntax inside a string like that. I'd be okay with a tooltips
plot option, which accepts a list of dimensions.
What would tooltips
do if there is no hover tool? Would it complain, silently ignore the issue or enable the hover tool if not already activated?
I don't thinks tooltips
is the right name (these aren't tips for using tools) but maybe something like hoverdims
or hoverinfo
would be ok? Maybe just call the option hover
?
What would tooltips do if there is no hover tool?
It would enable the hover tool.
I don't thinks tooltips is the right name (these aren't tips for using tools) but maybe something like hoverdims or hoverinfo would be ok?
Tooltips is the right name imo, here's the definition of tooltips:
a message which appears when a cursor is positioned over an icon, image, hyperlink, or other element in a graphical user interface.
The key bit for me is the last point - it is normally about describing function and not giving data values. @jbednar's opinion might help us with a better suggestion and I don't mind tooltips
too much if both of you don't think it is confusing.
tooltips
is also what bokeh calls it, so it would also be consistent.
That is a good argument for calling it tooltips
then.
Don't ask me; I've always thought tooltips
was a ridiculous and annoying name, and much prefer hover
.
I also like hover
more than tooltips
. This might be one of those times where we decide we chose a better name than bokeh. :-)
So, what was the result of this? that sintaxis proposed in the OP works? thanks for your answers đź‘Ť
We never have made progress on this issue, and it remains a major sticking point, particularly for hvPlot users, because the Bokeh syntax for creating a custom HoverTool is miles away from the concise and convenient syntax that hvPlot and HoloViews users expect.
Basically, you can have a nice, clean notebook about your work only if you don't care what shows up in the hover tool, i.e. if what it does by default is precisely what you wanted it to do. In my experience it's rare that what it shows by default is ideal, yet I still rarely modify that default in practice, because the syntax for specifying hover options is so verbose, awkward, and distracting from the story I am trying to tell in a given notebook. Hover is useful, but it's rarely the main story, yet configuring it immediately takes over the notebook and becomes a complicated digression that I usually choose not to get into.
We don't necessarily need a DSL as proposed above, but I do think we should support some simple list syntax for specifying what fields to include in the hover without needing to import HoverTool.
I think a mini-DSL as proposed above fits in best with the existing plot options and would be the shortest, most concise way to do this. Unfortunately, specifying a hood hover tool is verbose and awkward as you point out and I can't think of a more concise (and backwards compatible) way to do this. I guess you could try something like:
tools=[{'hover':['col1', 'col2']}, 'pan']
But that is hardly an improvement or any clearer imho.
I can't quite grok that syntax; seems like a tuple would work better than a dictionary there:
tools=['pan', ('hover', ['col1', 'col2'])]
And to extend that to cover the full tooltips
argument of the Bokeh HoverTool when needed:
tools=['pan', ('hover', dict(col1='@name', col2='@symbol', col3='$color[hex, swatch]:CPK')]
But just like @philippjfr above, I was imagining a separate option like hover_cols=['col1','col2']
(or tooltips
, if anyone likes that name!) and the equivalent dictionary version hover_cols=dict(col1='@name', col2='@symbol', col3='$color[hex, swatch]:CPK')
. Not sure whether the separate option or parsing tools
is easier to implement, but either of these seems like a big improvement over importing HoverTool and configuring it.
That final suggestion seems pretty reasonable to me. The only think I would like is for there to be a clear mechanism that maps a string (e.g. 'pan', 'wheelzoom', 'hover') to a Bokeh tool model or the tuple format (e.g. ('hover', ['col1', 'col2'])
which should also support the HTML template). I'm not sure what would be customized for other tools but I would hope to make this mechanism general for all the tools...
Sounds like we could support a general mechanism for Bokeh tools where we generalize our tools
parameter to accept tuples, i.e. something like tools=['tool1', ('tool2', settings2), ('tool3', settings3)]
. To implement that per tool, we'd register a handler for that tool that maps the given settings into configuration for that tool. For hover, what the handler would do is accept a string (i.e., HTML template), list (i.e., list of dimensions), or dict (i.e., list of dimension:formatter pairs) specification, and would map that into the tooltips
argument of HoverTool. Other tools could be configured similarly. Something for you to attack, @jlstevens ?
Would be great to revisit this. still a major sticking point.
Especially if a user can also specify whether to include their 'label' and 'group' arg value as a hover/tooltip entry.. for instance: https://github.com/holoviz/holoviews/issues/3603
Wanted to drop some feature ideas:
including/excluding columns (maybe new opts?) hover_cols
or just a dict of list tools=[{"hover": ["index", "x"]}]
formatting (dict of list): like https://github.com/holoviz/hvplot/issues/1095
tools=[{"hover": ["{index.0f}", "{x:.1f}", {"y:.1f}"]}]
renaming (dict of dict): https://github.com/holoviz/hvplot/issues/1258
tools=[{"hover": {"index": "Index", "x": "X-Coordinate"}}
renaming & formatting (dict of dict of tuple)?
tools=[{"hover": {"index": ("Index", ".0f"), "x": ("X-Coordinate", ".1f")}}
direct support bokeh tooltips kwarg directly (without having to import HoverTool(tooltips=...)` https://github.com/holoviz/holoviews/issues/1600, e.g.
tools=[{"hover": {[
("index", "$index"),
("(x,y)", "(x=$x{0[.]00000}, y=$y{0[.]00000})"),
]}}]
Questions:
Over time, I have become even more hesitant to support these nested structures and I think I've come to the conclusion that we should leave tools
alone and support hover_X
options instead e.g:
hover_labels={"index": "Index", "x": "X-Coordinate"},
hover_format=["{index.0f}", "{x:.1f}", {"y:.1f}"]
I think that hover_format
could support a dictionary to support the bokeh tooltip kwargs: this is still better than having to import the model from Bokeh (and of course, you can still supply the model directly in tools
if you want).
@jlstevens could you expand on why you've become l hesitant to support the nested approach?
These nested representations are often opaque, hard to manipulate correctly and brittle (more chance for syntax errors among other things).
Neither the nested nor the separate keywords are particularly discoverable ("how was I supposed to know there is a separate hover_cols
keyword when I want to configure this tool?" vs "what on earth is that obscure syntax supposed to indicate"), so in the end I'm not sure I have much of an opinion other than that I just want something providing control over this behavior without needing a separate tool and separate import. That way it can start working its way into our examples and people will be able to learn about either the separate keywords or about the fancy syntax. So I'd say we should have a quick meeting about it, make a prototype, pass it around to see if it horrifies anyone, and go with it; it's better than dithering for more years!
A nested dict is indeed hard to work with, and since most people agreed that tile_opts would be the better option in https://github.com/holoviz/hvplot/pull/1299, I think I'll just start going with separate keywords like
hover_labels={"index": "Index", "x": "X-Coordinate"},
hover_format=["{index.0f}", "{x:.1f}", {"y:.1f}"]
However, I think both of these should be a list potentially? I'll have to try to get a better idea
I propose these three new params:
hover_tooltips = param.ClassSelector(class_=(str, list), default=[], doc="""
A list of strings to be displayed in the hover tooltip.
Or a list of tuples can be provided to also additionally specify the
label and value format. Lastly, a string can be provided if a custom
HTML template is provided.
""")
hover_formatters = param.List(default=[], doc="""
A list of formatting options for the hover tooltips.""")
hover_mode = param.ObjectSelector(default='mouse', objects=['mouse', 'vline', 'hline'], doc="""
The hover mode determines how the hover tool is activated.""")
To not deviate too much from Bokeh, it should mirror what Bokeh has:
hover_tooltips=[
( 'date', '@date{%F}' ),
( 'close', '$@{adj close}{%0.2f}' ), # use @{ } for field names with spaces
( 'volume', '@volume{0.00 a}' ),
],
hover_formatters={
'@date' : 'datetime', # use 'datetime' formatter for '@date' field
'@{adj close}' : 'printf', # use 'printf' formatter for '@{adj close}' field
# use default 'numeral' formatter for other fields
},
hover_mode='vline'
I believe this will be extremely convenient for users to have it broken up like this. Previously, users would have to import and completely build the HoverTool
if they wanted to change one thing about the hover tooltips; now they just have to change one of these params.
I'd like to also propose supporting a list of strings in hover_tooltips:
hover_tooltips=["date", "close"]
And potentially a list of Python string formats(?, will decide if this is easy to implement; I think yes?)
hover_tooltips=["{date:%Y%m%d%H}", "{close:.02f}"]
In case users don't want to specify the format.
I like @ahuang11's suggestion: we can point to Bokeh's API and all we are doing is removing a level of nesting and an import when creating a hovertool (at least regarding the keywords and their basic functionality...we can also add some sugar if it is useful).
I'm +1 as well. Python string formats sound nice, but in practice may not be straightforward.
Okay I started implementing it in https://github.com/holoviz/holoviews/pull/6180. As I understand, there's a lot of places that rebuild HoverTool so lots more work to add, but wanted to solicit initial feedback first before continuing.
A couple things added to the proposal
hover_tooltips
not only supports a list of strings, but also can support a list of a mix of strings AND tuples, giving the user extra flexibility if they want to format only a specific key (rather than tediously putting all tuples), e.g.hover_tooltips=["x", ("Dollars", "$@{y}{0.2f}")]
VS
hover_tooltips=[("x", "@x"), ("Dollars", "$@{y}{0.2f}")]
To use group
and label
in the hover, I added special support for @hv_label
/ @{hv_label}
and @hv_group
/ @{hv_group}
--basically a find and replace.
If hover
not in tools, but hover_tooltips
is defined, then automatically add hover
to tools.
https://github.com/holoviz/holoviews/assets/15331990/ca6124f0-719f-4c56-9dff-ab277332b281
In the PR above, I don't think I'll be supporting converting Python formats to Bokeh; perhaps in the future.
hover_tooltips=["{date:%Y%m%d%H}", "{close:.02f}"]
To use group and label in the hover, I added special support for @hv_label / @{hv_label} and @hv_group / @{hv_group}--basically a find and replace.
Don't much like the naming of these. For one the hv_
prefix is weird and secondly the @
syntax specifically means "look up the value on the data", which isn't the case here.
Field names that begin with $ are “special fields”. These often correspond to values that are part of the plot, such as the coordinates of the mouse in data or screen space. These special fields are listed here:
So $label
and $group
? I guess that would work; if user wants to point to value in their data, @label
I suppose semantically that makes sense although there will now be special fields defined by bokeh as well as some additional ones defined by holoviews. Not too terrible I suppose!
Okay, I think https://github.com/holoviz/holoviews/pull/6180 is in a pretty good state now for review.
See the new docs under Hover tools
on usage, starting at to replicate the behavior above.
(repeat of what was already described here)
https://github.com/holoviz/holoviews/blob/00bc0560de4240df2a7f96b2bdea597ee040dec8/examples/user_guide/Plotting_with_Bokeh.ipynb
The only thing missing are tests now I think.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Instead of building an explicit hover tool to choose dimensions to show hover information for, maybe we could have a syntax such as:
Where
+
means you are building a whitelist (what to include) and-
means it is a blacklist (what to exclude). E.g to exclude 'time' and 'voltage':