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

Bokeh多折线图如何将图例置于绘图区外,解决Figure不可下标访问报错

Bokeh多折线图图例外置解决方法

报错原因

你遇到的TypeError: 'Figure' object is not subscriptable报错有两个核心原因:

  • Bokeh的Figure对象不支持p[0]这种下标访问方式,无法直接通过索引获取画布上的元素
  • 你使用multi_line方法一次性绘制了全部7条折线,仅生成了一个渲染器对象,无法像单独绘制的单折线那样逐个获取每条线的渲染器

最简解决方案

不需要手动重构图例,直接将自动生成的内置图例移动到右侧外部即可,只需要在你原有代码的p.multi_line调用后、show(p)前添加两行代码:

# 给画布右侧预留足够空间放置图例,可根据实际显示效果调整数值
p.min_border_right = 130
# 将已生成的图例移动到画布右侧外部
p.add_layout(p.legend[0], 'right')

完整修改后代码参考

import pandas as pd
from bokeh.plotting import figure, show
from bokeh.palettes import Category20c_7
from bokeh.io import output_file
from bokeh.models import SingleIntervalTicker, LinearAxis, ColumnDataSource

output_file("conso_daily.html")

treatcriteria_daily_data = pd.read_csv("treatcriteria_evolution.csv", sep=';')

final_daily_data = treatcriteria_daily_data.groupby(['startdate_weekyear','startdate_dayweek'],as_index = False).sum().pivot('startdate_weekyear','startdate_dayweek').fillna(0)

# keep only integer values in x axis
def interval_integer(plot):
    ticker = SingleIntervalTicker(interval=1, num_minor_ticks=1)
    xaxis = LinearAxis(ticker=ticker)
    plot.add_layout(xaxis, 'below')
    
numlines = len(final_daily_data.columns)
palette = Category20c_7[0:numlines]

# remove the last week if there is not all the data
data_without_last_week = final_daily_data[(final_daily_data != 0).all(1)]

cpu_values_daily = data_without_last_week.values.T.tolist()

weeks = []
for i in range(0,len(data_without_last_week.columns)):
    weeks.append(data_without_last_week.index)

df = {'week': weeks, 
      'day': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], 
      'color': ['red', 'orange', 'yellow', 'green', 'grey', 'pink', 'purple'],
      'HCPU': cpu_values_daily}

source = ColumnDataSource(df)

p = figure(width=800, height=500)
p.multi_line(xs='week', ys='HCPU', legend='day', color='color',
             line_width=5, line_alpha=0.6, hover_line_alpha=1.0,
             source=source)
p.xaxis.visible = False
p.left[0].formatter.use_scientific = False

interval_integer(p)

# 新增的图例移动代码
p.min_border_right = 130
p.add_layout(p.legend[0], 'right')

show(p)

原始效果示意图

效果示意图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:39:03