You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现Pandas列交互式图表:自定义Hover及优化实现方案

Great question! Let's tackle both the hover tool customization and making your code more Pythonic, plus cover a direct Bokeh implementation for good measure.

1. Improved Holoviews + Bokeh Implementation (Cleaner & Hover with Week Number)

Your original approach using reduce to combine curves works, but Holoviews offers more intuitive ways to group multiple lines, and we can easily tweak the hover tool to show the week number.

Here's a more Pythonic implementation that fixes the hover issue:

import holoviews as hv
import pandas as pd
import numpy as np

# Regenerate your DataFrame (for reproducibility)
np.random.seed(42)
df = pd.DataFrame(np.random.randint(0, 1000, size=(24,53)))
df['hour'] = range(24)
df.rename(columns={col: str(col) for col in df.columns[:-1]}, inplace=True)

hv.extension('bokeh')

# Use NdOverlay to organize curves by week - hover will auto-include week info
hv.NdOverlay({week: hv.Curve(df, 'hour', week, label=f'Week {week}') 
              for week in df.columns[:-1]}, kdims='Week')\
    .opts(
        hv.opts.Curve(tools=['hover'], line_width=1),
        hv.opts.NdOverlay(legend_position='right')
    )

Key improvements:

  • Cleaner syntax: The dictionary comprehension for NdOverlay is far more readable than using reduce to merge curves one by one.
  • Hover shows week number: By using NdOverlay with kdims='Week', the hover tool automatically displays the corresponding week for each point, along with the hour and value.

If you prefer Overlay instead, this also works (and is still cleaner than reduce):

hv.Overlay([hv.Curve(df, 'hour', week, label=f'Week {week}') 
            for week in df.columns[:-1]])\
    .opts(
        hv.opts.Curve(tools=['hover'], line_width=1),
        hv.opts.Overlay(legend_position='right')
    )

The hover tool will pull the week number directly from the curve's label here.


2. Direct Bokeh Implementation

If you want to skip Holoviews entirely, you can build this directly with Bokeh's native API. We'll manually add each curve and configure the hover tool to show all three pieces of info: hour, value, and week.

from bokeh.plotting import figure, show
from bokeh.models import HoverTool, ColumnDataSource
import pandas as pd
import numpy as np

# Regenerate your DataFrame
np.random.seed(42)
df = pd.DataFrame(np.random.randint(0, 1000, size=(24,53)))
df['hour'] = range(24)
df.rename(columns={col: str(col) for col in df.columns[:-1]}, inplace=True)

# Create base figure
p = figure(title='Hourly Values by Week', x_axis_label='Hour', y_axis_label='Value',
           tools='pan,box_zoom,reset,save')

# Loop through each week column to add curves and hover tools
for week in df.columns[:-1]:
    # Create a data source with explicit week info for hover
    source = ColumnDataSource(data=dict(
        hour=df['hour'],
        value=df[week],
        week=[week]*len(df)
    ))
    # Add the line to the figure
    p.line('hour', 'value', source=source, legend_label=f'Week {week}', line_width=1)
    
    # Add a hover tool specific to this line
    hover = HoverTool(renderers=[p.renderers[-1]],
                      tooltips=[
                          ('Hour', '@hour'),
                          ('Value', '@value'),
                          ('Week', '@week')
                      ])
    p.add_tools(hover)

# Tweak legend for better usability
p.legend.location = 'top_right'
p.legend.click_policy = 'hide'  # Optional: let users click legend to hide/show lines

show(p)

This gives you full control over the plot and hover behavior, plus added interactivity like hiding lines via the legend.

内容的提问来源于stack exchange,提问作者Dror

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:39:05