Bokeh无法设置初始范围问题求助(附代码)
问题描述
我是Bokeh绘图初学者,若问题表述浅显还请见谅。尝试用DataFrame中的数据绘制折线图,x、y轴以列表形式提供,但y轴数据中存在None值:
- 当datapoints列为None时,对应的datapoint_count列是[1]
- 正常情况下datapoints列应为20个浮点数的列表,datapoint_count列应为1-20的数字列表
期望x轴范围1-20,y轴范围90.0-180.0。运行代码无Python错误,但浏览器开发者工具提示bokeh could not set initial ranges,相关代码如下:
data=df random_figure = figure(title='random', x_axis_label="Index", y_axis_label="random [ms]", plot_width=800, plot_height=400, output_backend="webgl") random_figure.add_tools(random_hover) id_values = data['testcase_id'].drop_duplicates() data_temp= data[['id', 'datapoints']].copy() data_temp['datapoint_count'] = None data_temp['datapoint_count'] = data_temp['datapoint_count'].astype(object) for indexes, item in data_temp.iterrows(): if item['datapoints'] is None or str(item['datapoints']) == '[]': # this has nonetype or strings item['datapoints'] = [0] else: item['datapoints'] = [float(x) for x in item['datapoints'].strip('[').strip(']').split(',')] iter_nr = 0 raw_data_count = [] for each in item['datapoints']: iter_nr += 1 datapoint_count.append(iter_nr) data_temp.at[indexes, 'datapoint_count'] = datapoint_count name_dict_random = {'name': [], 'legend': [], 'label': []} logging.info('START OF DRAWINGS') for ind, id in enumerate(id_values): it_color = Turbo256[random.randint(0, 255)] name_glyph_random = random_figure.line(x='datapoint_count', y='datapoints', line_width=2, legend_label=str(id), source=data_temp.where( data_temp['id'] == id).dropna(), color=it_color) name_dict_random['name'].append(name_glyph_random) name_dict_random['label'].append(str(id)) logging.info('AFTER DRAWINGS LOOP') for label in range(len(data.id.unique())): name_dict_random['legend'].append(random_figure.legend.items[label]) initial_value = [] options = list(data.id.unique()) for i, name in enumerate(options): options[i] = str(name) for i in range(len(options)): if name_dict_random['label'][i] in initial_value: name_dict_random['name'][i].visible = True name_dict_random['legend'][i].visible = True else: name_dict_random['name'][i].visible = False name_dict_random['legend'][i].visible = False
解决方案
1. 修复数据处理的变量错误
代码里误用了未定义的datapoint_count变量,应该用循环前定义的raw_data_count,否则会导致所有行的计数列表累加,数据彻底混乱:
# 修正后的数据计数逻辑 iter_nr = 0 raw_data_count = [] for each in item['datapoints']: iter_nr += 1 raw_data_count.append(iter_nr) data_temp.at[indexes, 'datapoint_count'] = raw_data_count
2. 手动指定坐标轴范围
Bokeh自动计算范围失败时,直接显式设置x、y轴范围,从根源解决无法设置初始范围的提示:
random_figure = figure(title='random', x_axis_label="Index", y_axis_label="random [ms]", plot_width=800, plot_height=400, output_backend="webgl", x_range=(1, 20), y_range=(90.0, 180.0)) # 新增固定范围
3. 优化无效数据的处理
当datapoints为None时,你设置的[0]不在期望的y轴范围内,会导致数据点被截断,建议用NaN替代,既不影响范围计算,也不会显示异常点:
if item['datapoints'] is None or str(item['datapoints']) == '[]': item['datapoints'] = [float('nan')] # 用NaN替代0 else: item['datapoints'] = [float(x) for x in item['datapoints'].strip('[').strip(']').split(',')]
4. 简化数据源筛选
用直接索引替代where+dropna(),避免不必要的数据缺失,同时建议用ColumnDataSource包装数据源,符合Bokeh最佳实践:
from bokeh.models import ColumnDataSource # 绘图时的数据源替换 source=ColumnDataSource(data_temp[data_temp['id'] == id])
5. 调整图例初始可见性
initial_value是空列表,导致所有图形默认隐藏,可根据需求设置初始显示的id,比如默认显示第一个:
initial_value = [options[0]] # 默认显示第一个id的折线
内容的提问来源于stack exchange,提问作者noob
相关产品推荐
相关产品推荐

