0

I am trying to dynamically modify my y-axis tick formatting and tooltip formatting based on what is selected in a Holoviews dropdown. I figured I could do this in finalize_hooks. Since I don't know how to test for what has been selected in the dropdown, I used the title value to determine that. This seems to work ok though I am sure there could be a more elegant solution that I am not aware of. Also, I am able to change the tick formatter but the hover value doesn't change based on the above method. See example code below. Tooltip always shows Value1, never Value 2 no matter which country I select. Please advise if there is a way to fix this.

%%opts Bars [show_grid=True width=1400 height=400 xrotation=0] {+framewise}
macro_df = pd.read_csv('http://assets.holoviews.org/macro.csv', '\t')

key_dimensions   = [('year', 'Year'), ('country', 'Country')]
value_dimensions = [('unem', 'Unemployment'), ('capmob', 'Capital Mobility'),
                ('gdp', 'GDP Growth'), ('trade', 'Trade')]
macro = hv.Table(macro_df, key_dimensions, value_dimensions)

hover = HoverTool(tooltips=[('year', '@year'),
                        ('Value', '@unem{0.000%}')])

def apply_formatter(plot, element):
    p = plot.handles['plot']
    if 'Austria' in p.title.text:
        plot.handles['yaxis'].formatter = NumeralTickFormatter(format="0")
        p.hover[0].tooltips[1] = ('Value1', '@unem{0.0%}')
    else:
        plot.handles['yaxis'].formatter = NumeralTickFormatter(format="0.0%")
        p.hover[0].tooltips[1] = ('Value2', '@unem{0.00%}')

bars = macro.to(hv.Bars, kdims='year', vdims=['unem']).opts(plot=dict(tools=[hover], finalize_hooks=[apply_formatter]))

bars

pongo30
  • 29
  • 6

1 Answers1

0

This seems to work

from bokeh.models import NumeralTickFormatter
from bokeh.models import HoverTool
macro_df = pd.read_csv('http://assets.holoviews.org/macro.csv', '\t')

key_dimensions   = [('year', 'Year'), ('country', 'Country')]
value_dimensions = [('unem', 'Unemployment'), ('capmob', 'Capital Mobility'),
                ('gdp', 'GDP Growth'), ('trade', 'Trade')]
macro = hv.Table(macro_df, key_dimensions, value_dimensions)


def apply_formatter(plot, element):
    p = plot.state
    global x
    x = p
    if 'Austria' in p.title.text:
        plot.handles['yaxis'].formatter = NumeralTickFormatter(format="0")
        hover = HoverTool(tooltips=[('year', '@year'),
                                    ('Value', '@unem{0%}')])
        p.tools = [hover]
    else:
        plot.handles['yaxis'].formatter = NumeralTickFormatter(format="0.0%")
        hover = HoverTool(tooltips=[('year', '@year'),
                                ('Value', '@unem{0.00%}')])
        p.tools = [hover]

bars = macro.to(hv.Bars, kdims='year', vdims=['unem']).options(
    tools=[], finalize_hooks=[apply_formatter])
bars

Austria Format Belgium Format

Andrew
  • 507
  • 5
  • 16
  • Thanks @Andrew-H. This does seem to work. Two questions: (1) I am not sure what role does global x; x=p plays? Code seems to work without those statements as well. (2) It looks like it is important to define hover object inside the if block. Say, if I defined hover1 and hover 2 outside the apply_formatter function and changed p.tools to p.tools=[hover1] and p.tools=[hover2] in the two places, the code doesn't work. I don't know why... – pongo30 Oct 08 '18 at 21:36
  • Woops, my bad; global x and x=p was just me testing outside the function. – Andrew Oct 09 '18 at 16:17
  • 2. Not sure why it doesn't work for you, but it works for me. – Andrew Oct 09 '18 at 16:23