Skip to content
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

Easy specification of dimensions for hover tool #1816

Closed
jlstevens opened this issue Aug 21, 2017 · 30 comments · Fixed by #6180
Closed

Easy specification of dimensions for hover tool #1816

jlstevens opened this issue Aug 21, 2017 · 30 comments · Fixed by #6180
Assignees
Labels
czi type: feature A major new feature
Milestone

Comments

@jlstevens
Copy link
Contributor

Instead of building an explicit hover tool to choose dimensions to show hover information for, maybe we could have a syntax such as:

tools=['hover+time|voltage']

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':

tools=['hover-time|voltage']
@jlstevens jlstevens added the type: feature A major new feature label Aug 21, 2017
@jbednar
Copy link
Member

jbednar commented Aug 21, 2017

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.

@philippjfr
Copy link
Member

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.

@jlstevens
Copy link
Contributor Author

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?

@philippjfr
Copy link
Member

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.

@jlstevens
Copy link
Contributor Author

image

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.

@philippjfr
Copy link
Member

tooltips is also what bokeh calls it, so it would also be consistent.

@jlstevens
Copy link
Contributor Author

That is a good argument for calling it tooltips then.

@jbednar
Copy link
Member

jbednar commented Sep 4, 2017

Don't ask me; I've always thought tooltips was a ridiculous and annoying name, and much prefer hover.

@jlstevens
Copy link
Contributor Author

I also like hover more than tooltips. This might be one of those times where we decide we chose a better name than bokeh. :-)

@philippjfr philippjfr added this to the v1.9 milestone Sep 23, 2017
@philippjfr philippjfr self-assigned this Oct 7, 2017
@philippjfr philippjfr modified the milestones: v1.9, v1.10 Nov 1, 2017
@philippjfr philippjfr modified the milestones: v1.10, v1.11 Mar 19, 2018
@kako-f
Copy link

kako-f commented Aug 10, 2018

So, what was the result of this? that sintaxis proposed in the OP works?
thanks for your answers 👍

@philippjfr philippjfr modified the milestones: v1.11.0, v1.11.x Dec 27, 2018
@philippjfr philippjfr modified the milestones: v1.11.x, v1.12.0 Mar 22, 2019
@philippjfr philippjfr modified the milestones: v1.12.0, v1.12.x Apr 22, 2019
@philippjfr philippjfr modified the milestones: v1.12.x, v1.13.0 Jan 5, 2020
@philippjfr philippjfr modified the milestones: v1.13.0, v1.13.x Mar 3, 2020
@jbednar
Copy link
Member

jbednar commented Feb 13, 2021

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.

@jlstevens
Copy link
Contributor Author

jlstevens commented Feb 15, 2021

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.

@jbednar
Copy link
Member

jbednar commented Feb 15, 2021

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.

@jlstevens
Copy link
Contributor Author

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...

@jbednar
Copy link
Member

jbednar commented Feb 18, 2021

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 ?

@droumis
Copy link
Member

droumis commented Apr 2, 2024

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: #3603

@droumis droumis assigned ahuang11 and unassigned philippjfr Apr 2, 2024
@droumis droumis added the czi label Apr 2, 2024
@ahuang11
Copy link
Collaborator

ahuang11 commented Apr 2, 2024

Wanted to drop some feature ideas:

tools=[{"hover": ["{index.0f}", "{x:.1f}", {"y:.1f}"]}]
tools=[{"hover": {"index": "Index", "x": "X-Coordinate"}}
  • renaming & formatting (dict of dict of tuple)?
tools=[{"hover": {"index": ("Index", ".0f"), "x": ("X-Coordinate", ".1f")}}
tools=[{"hover": {[
    ("index", "$index"),
    ("(x,y)", "(x=$x{0[.]00000}, y=$y{0[.]00000})"),
]}}]

Questions:

  1. Since bokeh tooltip formatting is different from f-strings, I'm wondering how to reconcile that; do we support both, or just Bokeh style? Leaning towards just bokeh style to keep it simple
  2. Should we go with nested dict/list/tuple or should we go for separate opts, e.g. (hover_format)

@jlstevens
Copy link
Contributor Author

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).

@droumis
Copy link
Member

droumis commented Apr 3, 2024

@jlstevens could you expand on why you've become l hesitant to support the nested approach?

@jlstevens
Copy link
Contributor Author

These nested representations are often opaque, hard to manipulate correctly and brittle (more chance for syntax errors among other things).

@jbednar
Copy link
Member

jbednar commented Apr 3, 2024

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!

@ahuang11
Copy link
Collaborator

ahuang11 commented Apr 8, 2024

A nested dict is indeed hard to work with, and since most people agreed that tile_opts would be the better option in holoviz/hvplot#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

@ahuang11
Copy link
Collaborator

ahuang11 commented Apr 9, 2024

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.""")
image

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.

@jlstevens
Copy link
Contributor Author

jlstevens commented Apr 9, 2024

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).

@philippjfr
Copy link
Member

I'm +1 as well. Python string formats sound nice, but in practice may not be straightforward.

@ahuang11
Copy link
Collaborator

ahuang11 commented Apr 9, 2024

Okay I started implementing it in #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

  1. 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}")]
  1. 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.

  2. If hover not in tools, but hover_tooltips is defined, then automatically add hover to tools.

Screen.Recording.2024-04-09.at.3.29.35.PM.mov

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}"]

@philippjfr
Copy link
Member

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.

@ahuang11
Copy link
Collaborator

ahuang11 commented Apr 10, 2024

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

@jlstevens
Copy link
Contributor Author

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!

@ahuang11
Copy link
Collaborator

ahuang11 commented Apr 10, 2024

Okay, I think #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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
czi type: feature A major new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants