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

Bokeh甘特图样式堆叠水平条形图空白及JS报错问题

Fix Bokeh Gantt Chart Blank Page & SCRIPT5007 Error

Hey there, let's figure out why your Gantt-style chart is showing up blank and throwing that JS error. The main issues are with how you're handling the data source and misusing the hbar_stack function for this use case. Here's the breakdown and fix:

What's Going Wrong

  1. You can't pass a GroupBy object directly to ColumnDataSource
    When you do source=ColumnDataSource(grouped), you're giving Bokeh a pandas GroupBy object instead of a structured data format it can understand (like a DataFrame or dictionary). This confuses Bokeh's JS rendering, leading to the "Unable to get property 'length' of undefined..." error.

  2. hbar_stack isn't meant for Gantt charts
    hbar_stack is designed to stack numerical values from multiple series (e.g., adding up task durations per org). But a Gantt chart needs to show tasks as time-based segments on each org's row, not stacked values.

Fixed Code & Step-by-Step Explanation

First, Prep Your Data

Make sure your date columns are properly typed, then calculate task durations (or just use start/end dates directly):

import pandas as pd
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, FactorRange

# If you already have your df, skip this sample data setup
sample_data = [
    ["o1", "t1", "2019-11-19", "2019-11-23"],
    ["o1", "t2", "2019-11-23", "2019-11-27"],
    ["o1", "t3", "2019-11-27", "2019-12-01"],
    ["o1", "t4", "2019-12-02", "2019-12-06"],
    ["o2", "t1", "2019-11-20", "2019-11-24"],
    ["o2", "t2", "2019-11-24", "2019-11-28"],
    ["o2", "t3", "2019-12-01", "2019-12-05"],
    ["o2", "t4", "2019-12-05", "2019-12-09"],
    ["o3", "t1", "2019-11-20", "2019-11-24"],
    ["o3", "t2", "2019-11-24", "2019-11-28"],
    ["o3", "t3", "2019-12-01", "2019-12-05"],
    ["o3", "t4", "2019-12-05", "2019-12-09"],
]
df = pd.DataFrame(sample_data, columns=["Org", "Task", "Start", "Finish"])

# Convert date columns to datetime (critical for Bokeh's datetime axis)
df["Start"] = pd.to_datetime(df["Start"])
df["Finish"] = pd.to_datetime(df["Finish"])

Now Build the Gantt Chart

We'll use hbar instead of hbar_stack, since we need to plot each task as a time segment on its org's row:

# Get unique orgs for the y-axis
orgs = df["Org"].unique().tolist()

# Create the figure
p = figure(
    title='Project Schedule',
    x_axis_type='datetime',
    y_range=FactorRange(factors=orgs),  # Ensures y-axis shows org names correctly
    width=800,
    height=450
)

# Plot each task as a horizontal bar using start/end dates
p.hbar(
    y='Org',
    left='Start',
    right='Finish',
    height=0.8,
    source=ColumnDataSource(df),
    legend_field='Task',
    alpha=0.7
)

# Tweak the chart for readability
p.legend.location = "top_right"
p.xaxis.axis_label = "Date"
p.yaxis.axis_label = "Organization"

# Show the chart
show(p)

If You Actually Want Stacked Bars (Not Gantt)

If you meant to stack task durations per org (e.g., total time spent per org across tasks), here's how to use hbar_stack correctly by reshaping your data to wide format:

# Reshape data to wide format (one column per task)
wide_df = df.pivot(index='Org', columns='Task', values=(df["Finish"] - df["Start"]).dt.days).fillna(0)

# Create data source
source = ColumnDataSource(wide_df.reset_index())

# Build stacked bar chart
p = figure(
    title='Total Task Duration per Org',
    y_range=wide_df.index.tolist(),
    x_axis_label='Total Days',
    width=800,
    height=450
)

# Stack the task duration columns
p.hbar_stack(wide_df.columns.tolist(), y='Org', height=0.8, source=source)

show(p)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:44:41