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

Bokeh 1.4.0生成HTML无可视化内容问题求助

Fix for Bokeh 1.4.0 Interactive Visualization Not Displaying in HTML

From your code and issue description, the blank HTML output is caused by several critical mismatches and errors in your implementation. Let's break down the problems and fix them step by step:

Key Issues Identified

  1. Missing x/y Fields in Initial Data Source
    Your figure.circle call references x="x" and y="y", but the initial ColumnDataSource (built from data_loaded) doesn't contain these columns. Bokeh fails to render when it can't find required fields.

  2. Incorrect Data Type for fill_alpha
    You set alpha as string values ('0.9'/'0.25'), but Bokeh's fill_alpha expects numeric (float) values. String types will break rendering.

  3. Mixed Workflow: Bokeh Server vs Static HTML
    Using curdoc().add_root(l) is for Bokeh Server applications. If you're generating a static HTML file, this method won't work—you need to use output_file and show instead.

  4. Unbound Controls & Missing Filter Logic
    Your x_axis and y_axis dropdowns weren't bound to the update function, and the xVal_maximun_slider had no filtering logic to affect the data.


Corrected Code

from os.path import join, dirname
import pandas as pd
import numpy as np
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, Slider, Div, Select
from bokeh.models.tools import HoverTool
from bokeh.layouts import layout, column

# Synthetic data setup (unchanged)
syntetic_columns = ['id_pieza', 'xVar', 'yVar', 'zVar', 'N', 'P', 'vv', 'v']
syntetic_data = [
    ['001', 1, 1, 1, 1, 10, 12, 15],
    ['004', 7.5, 7.1, 5.1, 1, 12, 12, 1.5],
    ['005', .1, 1, 1.54, 2, 9, 1.2, 1.5],
    ['006', .51, 1, 1.45, 1, 8.5, 12, 15]
]
data_loaded = pd.DataFrame(data=syntetic_data, columns=syntetic_columns)

# Fix 1: Use numeric values for alpha instead of strings
data_loaded['color'] = np.where(data_loaded['N'] == 1, 'orange', 'grey')
data_loaded['alpha'] = np.where(data_loaded['N'] == 1, 0.9, 0.25)

# Axis mapping (unchanged)
axis_map = {
 'Number of pieces': 'N',
 'Cost of one unit': 'P',
 'X maximum value': 'xVar',
 'Y maximum value': 'yVar',
 'Z maximum value': 'zVar',
}

# Controls setup (unchanged)
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Number of pieces")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Cost of one unit")
xVal_maximun_slider = Slider(
    start=0, 
    end=max(data_loaded['xVar'].values), 
    value=max(data_loaded['xVar'].values), 
    step=0.1, 
    title='X maximum value'
)

# Tooltips (unchanged)
TOOLTIPS = [
 ('Cost per unit', '@P'),
 ('Number of pieces', '@N'),
 ('id', '@id_pieza'),
 ('x value', '@xVar'),
 ('y value', '@yVar'),
 ('z value', '@zVar'),
 ('Volumen de viruta', '@vv')
]

# Fix 2: Initialize figure without hardcoding x/y (update will populate them)
p = figure(
    plot_height=600, 
    plot_width=700, 
    title="Interactive Data Visualization", 
    toolbar_location=None, 
    tooltips=TOOLTIPS, 
    sizing_mode="scale_both"
)
# Placeholder circle - data will be updated via the update function
p.circle(x="x", y="y", source=None, size=7, color="color", line_color=None, fill_alpha="alpha")

# Fix 3: Add slider filtering logic
def select_data():
    selected = data_loaded.copy()
    # Apply filter from x max slider
    selected = selected[selected['xVar'] <= xVal_maximun_slider.value]
    return selected

# Fix 4: Update function with complete data source
def update():
    df = select_data()
    x_name = axis_map[x_axis.value]
    y_name = axis_map[y_axis.value]
    
    p.xaxis.axis_label = x_axis.value
    p.yaxis.axis_label = y_axis.value
    
    # Create full data source including tooltip fields
    new_source = ColumnDataSource(data=dict(
        x = df[x_name],
        y = df[y_name],
        color=df['color'],
        alpha=df['alpha'],
        P=df['P'],
        N=df['N'],
        id_pieza=df['id_pieza'],
        xVar=df['xVar'],
        yVar=df['yVar'],
        zVar=df['zVar'],
        vv=df['vv']
    ))
    # Update the circle renderer's data source
    p.renderers[0].data_source = new_source

# Fix 5: Bind all controls to the update function
controls = [xVal_maximun_slider, x_axis, y_axis]
for control in controls:
    control.on_change('value', lambda attr, old, new: update())

# Layout setup
desc = Div(text=open(join(dirname(__file__), "description.html")).read(), sizing_mode="stretch_width")
inputs = column(*controls, width=320, height=1000)
inputs.sizing_mode = "fixed"

l = layout([
 [desc],
 [inputs, p],
], sizing_mode="scale_both")

# Initialize data
update()

# Fix 6: Generate static HTML file
output_file("interactive_data_plot.html")
show(l)

What Each Fix Does

  1. Alpha Type Correction: Converts string transparency values to floats so Bokeh can parse them correctly.
  2. Dynamic Data Source: The update function creates a complete ColumnDataSource with all required fields (including tooltip data) instead of relying on missing initial columns.
  3. Control Binding: Adds x_axis and y_axis to the control list so dropdown selections trigger updates.
  4. Slider Filter Logic: Makes the xVal_maximun_slider actually filter the data based on the selected maximum x value.
  5. Static HTML Workflow: Uses output_file and show instead of curdoc to generate a standalone HTML file that works in Chrome.

Testing Steps

  1. Ensure description.html exists (replace it with static text like <h2>Interactive Data Plot</h2> if you don't need the external file).
  2. Run the corrected script—it will generate interactive_data_plot.html.
  3. Open the file in Chrome; you should see the visualization with fully functional controls.

If you still see console errors, verify:

  • The path to description.html is correct.
  • Bokeh 1.4.0 is properly installed (run pip show bokeh to confirm).

内容的提问来源于stack exchange,提问作者Manuel Gijón

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:23:14