Bokeh图例重排序:如何解决字符串比较导致的排序异常问题
Bokeh图例自然排序解决方案
使用natsort包实现自然排序的方案完全可行,且可以自动适配任意样本数量,无需提前预知样本规模。
操作步骤
- 首先安装natsort依赖:
pip install natsort
- 仅需对原有代码做两处调整即可生效:
- 导入natsort库的natsorted方法
- 在渲染图例前对图例项做自然排序
修改后的完整代码
from bokeh.models import ColumnDataSource, Label, LabelSet, Range1d from bokeh.plotting import figure, output_file, show from bokeh.models import HoverTool import pandas as pd from natsort import natsorted df = pd.DataFrame( { "pc1": range(11), "pc2": range(10, -1, -1), "Muestra": ["A"] * 6 + ["B"] * 5, "color": ["#cf0c0c"] * 6 + ["#0dab51"] * 5, }, index=range(11), ) ID = ["{} {}".format(i + 1, j) for i, j in enumerate(df.Muestra)] # Tools TOOLS = "hover,crosshair,pan,wheel_zoom,zoom_in,zoom_out,box_zoom,undo,redo,reset,tap,save,box_select,poly_select,lasso_select" source = ColumnDataSource( data=dict(pc1=df.pc1, pc2=df.pc2, color=df.color, ID=ID, names=df.index) ) x_min, x_max = ( min(df.pc1) - abs(min(df.pc1)) * 0.1, max(df.pc1) + abs(max(df.pc1)) * 0.1, ) y_min, y_max = ( min(df.pc2) - abs(min(df.pc2)) * 0.1, max(df.pc2) + abs(max(df.pc2)) * 0.1, ) p = figure( title="Principal Component Analysis", x_range=Range1d(x_min, x_max), y_range=Range1d(y_min, y_max), tools=TOOLS, height=650, width=1000, ) p.scatter( x="pc1", y="pc2", size=15, fill_color="color", fill_alpha=0.6, line_color=None, legend_group="ID", source=source, ) p.xaxis[0].axis_label = "Principal Component 1" p.yaxis[0].axis_label = "Principal Component 2" labels = LabelSet( x="pc1", y="pc2", text="names", x_offset=5, y_offset=5, source=source, render_mode="canvas", ) # 新增排序逻辑:对图例项做自然排序 p.legend[0].items = natsorted(p.legend[0].items, key=lambda x: x.label["value"]) p.add_layout(p.legend[0], "right") p.add_layout(labels) show(p)
实现原理
natsort的自然排序逻辑会自动识别字符串中的数字部分,按照数值大小而非字符编码排序,完美解决'2 A'排在'10 A'之前的异常问题,不管后续新增多少样本、编号到多少位,都能自动适配排序规则。
内容的提问来源于stack exchange,提问作者Federico Vega
相关产品推荐
相关产品推荐

