Jupyter中Bokeh绘图报'str' object is not callable错误排查
Jupyter环境Bokeh绘图报
TypeError: 'str' object is not callable解决 问题场景
在Jupyter Notebooks中读取Pandas DataFrame,基于Pandas、Bokeh库绘制多幅图表时触发类型错误,初步排查特征如下:
- 同类报错常见诱因为
plt.title = "Title"这类赋值语句覆盖原生绘图方法,但排查自身代码未发现此类写法,所有图表标题均按照Bokeh官方文档规范在figure()参数中配置 - 将报错代码段提取为独立Python脚本运行无异常,问题仅在Notebook环境中可复现
- 单独重新导入
matplotlib.pyplot无法解决问题,重新执行全量依赖导入语句后报错会临时消失
涉及的绘图核心代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from bokeh.plotting import figure, show, output_notebook, ColumnDataSource from bokeh.io import output_notebook from bokeh.layouts import column, gridplot from bokeh.models import Label, Title from bokeh.models import Div data = df output_notebook() # 全局图表总标题 abovetitle = ("This should be the overall title of all graphs") # 图表1 s1 = figure(width = 250, plot_height = 250, title="Graph 1", x_axis_label = "axis title 1", y_axis_label = 'µs') s1.line(x, y, width=1, color="black", alpha=1, source = data) # s1.title.text = "Title With Options" # 测试title属性配置写法,无法解决问题 # 图表2 s2 = figure(width = 250, plot_height = 250, title="Graph 2", x_axis_label = "axis title 2, y_axis_label = 'µs') s2.line(x, y, width=1, color="blue", alpha=1, source = data) #s2.title.text = "Title With Options" # 测试title属性配置写法,无法解决问题 # 渲染图表 p = gridplot([[s1, s2]]) show(column(Div(text=abovetitle), p))
触发的报错信息:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-24-33e4828b986d> in <module> 31 # 渲染图表 32 p = gridplot([[s1, s2]]) ---> 33 show(column(Div(text=title), p)) TypeError: 'str' object is not callable
根因分析
报错本质是Jupyter内核全局命名空间内的Bokeh API被同名变量覆盖:
前置单元格编写数据处理逻辑时,误将Bokeh布局函数名作为循环变量使用,遍历DataFrame列的for column in x_df语句执行后,原本从bokeh.layouts导入的column布局函数,被覆盖为循环最后一次迭代得到的列名字符串值,后续调用column()组合组件时,实际是尝试对字符串对象做函数调用,因此触发类型错误。
导致问题的前置代码如下:
############################# # 定义XData二进制部分的列名 header = ["Col1","Col2","Col3"] # 将空格分隔的XData字段拆分为多列 x_df = selected_df.XData.str.split(' ', expand=True) x_df.drop(0, inplace=True, axis=1) x_df.columns = header # 二进制格式XData转整数 # 注意:不要用column作为循环变量!会覆盖Bokeh的column API,建议替换为col等其他名称 for column in x_df: x_df[column] = x_df[column].apply(int, base=16)
解决方案
将循环变量替换为非Bokeh API保留名称即可,比如把循环语句修改为for col in x_df:,同步替换循环内部的列引用变量名,避免和导入的bokeh.layouts.column函数重名。
提示:Jupyter Notebook所有单元格共享同一个内核命名空间,之前运行过的单元格定义的临时变量会一直保留直到内核重启,遇到
'XXX' object is not callable类报错时,可以优先排查是否存在同名变量覆盖了导入的函数、类。
内容的提问来源于stack exchange,提问作者Swawa
相关产品推荐
相关产品推荐

