Bokeh无法正确读取排序后的Pandas DataFrame问题求助
Hey there! Let's figure out why your sorted DataFrame isn't being recognized correctly in your Bokeh dual-Y axis bar chart. From my experience with Bokeh, this usually boils down to a few common issues with data indexing, categorical factor ordering, or data source synchronization. Let's break it down step by step:
Common Causes & Fixes
1. Forgetting to Reset Your DataFrame Index After Sorting
When you sort a DataFrame, the original index values stay intact—this can confuse Bokeh, which often relies on consistent indexing to map data to plot elements.
Fix: Reset the index after sorting to ensure a clean, sequential index:
# 假设你的注册人数列名为'注册人数' df_sorted = df.sort_values('注册人数', ascending=False).reset_index(drop=True)
Double-check the sorted output with print(df_sorted.head()) to confirm the order is correct before passing it to Bokeh.
2. Outdated Categorical Factor Range
If your x-axis uses categorical values (like group names, regions, etc.), Bokeh's FactorRange needs to explicitly match the sorted order of your data. If you're still using the original factor list, Bokeh will render bars in the old order, even if your DataFrame is sorted.
Fix: Update the FactorRange with the sorted categorical values:
from bokeh.models import FactorRange, ColumnDataSource # 提取排序后的分类列表 sorted_categories = df_sorted['你的分类列名'].tolist() # 创建基于排序后数据的数据源 source = ColumnDataSource(df_sorted) # 初始化figure时使用更新后的FactorRange p = figure(x_range=FactorRange(factors=sorted_categories), title="双Y轴排序柱状图", width=800)
3. Mismatched Data Sources for Dual Y-Axes
If you're creating two separate vbar glyphs for each Y-axis, make sure both are using the same sorted data source. Using different sources (one sorted, one not) will lead to misaligned bars or unexpected rendering.
Example Working Code Snippet
Here's a complete example tying it all together (adjust column names to match your data):
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource, FactorRange, LinearAxis, Range1d, NumeralTickFormatter # 1. 排序并处理数据 df_sorted = df.sort_values('注册人数', ascending=False).reset_index(drop=True) sorted_names = df_sorted['名称'].tolist() source = ColumnDataSource(df_sorted) # 2. 创建图表 p = figure( x_range=FactorRange(factors=sorted_names), title="按注册人数排序的双Y轴柱状图", width=900, height=500 ) # 第一个Y轴:注册人数 p.vbar( x='名称', top='注册人数', width=0.35, source=source, color='#2c3e50', legend_label='注册人数' ) p.yaxis.axis_label = '注册人数' p.yaxis.formatter = NumeralTickFormatter(format='0,0') # 第二个Y轴:示例其他指标(替换为你的列名) p.extra_y_ranges = {"second_axis": Range1d(start=0, end=df_sorted['其他指标'].max() * 1.1)} p.vbar( x='名称', top='其他指标', width=0.35, source=source, color='#e74c3c', legend_label='其他指标', y_range_name="second_axis" ) p.add_layout( LinearAxis(y_range_name="second_axis", axis_label='其他指标'), 'right' ) # 优化图表样式 p.legend.location = "top_right" p.xaxis.major_label_orientation = 1.2 # 旋转x轴标签避免重叠 p.grid.grid_line_alpha = 0.3 show(p)
Quick Checks to Verify
- Print
df_sortedto confirm your data is sorted correctly by registration count. - Ensure the
x_rangefactors exactly match the order of categories indf_sorted. - Confirm both bar glyphs reference the same
ColumnDataSourcecreated fromdf_sorted.
内容的提问来源于stack exchange,提问作者Tom Slesinger

