【问题标题】:Reordering Bokeh Legend重新排序散景图例
【发布时间】:2021-07-05 20:39:13
【问题描述】:

我对以下情节的图例有一个明显的问题:

我理解这个问题,python 正在评估 '2A' > '10 B' 为 True,但我不知道如何解决它(也许使用 natsort 包?)。我想强调重新排序过程必须是自动的,因为我不知道我将来会有多少样品。 代码在这里:

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

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.add_layout(p.legend[0], 'right')
p.add_layout(labels)
    
show(p)

【问题讨论】:

    标签: plot bokeh scatter-plot legend-properties


    【解决方案1】:

    我猜有多种方法:

    一种方法是手动对图例进行排序。在您的情况下,图例是图形对象pright 侧的第一项[0]。图例本身是一个列表,因此您可以 popappend 移动您要移动的元素。在您的情况下,列表的第二个和第一个元素。在致电 show(p) 之前,请先执行此操作。

    _11 = p.right[0].items.pop(2)
    _10 = p.right[0].items.pop(1)
    p.right[0].items.append(_10)
    p.right[0].items.append(_11)
    

    编辑

    另一个可能的选择是以正确排序的方式修改您的变量ID。这将导致图例的顺序正确但条目错误。

    ID = ['{:>02d} {}'.format(i+1,j) for i,j in enumerate(df.Muestra)]
    >>>
    ['01 A',
     '02 A',
     '03 A',
     '04 A',
     '05 A',
     '06 A',
     '07 B',
     '08 B',
     '09 B',
     '10 B',
     '11 B']
    

    show(p) 调用之前,您可以遍历每个项目并删除之前需要的零。

    for i in range(len(p.right[0].items)):
        p.right[0].items[i].label['value'] = re.sub('^[0]+', '', p.right[0].items[i].label['value'])
    

    对于我的解决方案,您必须 import re 这是一个负面影响。也许其他一些解决方案没有额外的包就退出了。

    【讨论】:

    • 我必须使用 natsort 包来自动化这个过程。我不知道我将来会有多少物品。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 2021-05-22
    相关资源
    最近更新 更多