为了账号安全,请及时绑定邮箱和手机立即绑定

切换散景服务 hbar 图的数据源不起作用:空白图

切换散景服务 hbar 图的数据源不起作用:空白图

杨魅力 2023-10-31 21:28:01
问题我想创建一个交互式 hbar 图,您可以使用选择小部件、Python 回调和本地散景服务在 3 个不同的数据源之间切换。使用默认源的绘图渲染得很好,但是当我切换到不同的源时,y 标签保持不变,并且绘图变为空白。更改回选择小部件上的原始值不会显示我开始时的绘图并保持空白。当我将初始源硬编码为代码中的另一个源时,它呈现得很好,直到我再次使用小部件切换它,因此数据本身似乎单独工作得很好。我错过了什么吗?我阅读了许多线程、文档和教程,但找不到我的代码有任何问题。这是我到目前为止所做的:我读取 .csv 并创建 3 个单独的数据帧,然后转换为列数据源。每个源都有 10 个数据条目,其中包含“species”、“ci_lower”和“ci_upper”列。以下是一个来源的示例(所有三个来源的构建方式完全相同,具有不同的分类单元类别):df = pd.read_csv(os.path.join(os.path.dirname(__file__), "AZA_MLE_Jul2018_utf8.csv",), encoding='utf-8')m_df = df[df["taxon_class"]=="Mammalia"]m_df = m_df.sort_values(by="mle", ascending=False)m_df = m_df.reset_index(drop=True)m_df = m_df.head(10)m_df = m_df.sort_values(by="species", ascending=False)m_df = m_df.reset_index(drop=True)m_source = bp.ColumnDataSource(m_df)我将所有 3 个来源保存在一个字典中:sources_dict={    "Mammalia": m_source,    "Aves": a_source,    "Reptilia": r_source}...然后创建了名为“source”的变量,该变量应与默认的“Mammalia”源交互更改:source = sources_dict["Mammalia"]接下来,我创建了一个图形并添加了带有源变量的 hbar 图,如下所示:plot = bp.figure(x_range=(0, np.amax(source.data["ci_upper"])+5), y_range=source.data["species"])plot.hbar(y="species", right="ci_lower", left="ci_upper", height=0.5, fill_color="#b3de69", source=source)然后我添加了带有 python 回调的选择小部件:def select_handler(attr, old, new):    source.data["species"]=sources_dict[new].data["species"]    source.data["ci_lower"]=sources_dict[new].data["ci_lower"]    source.data["ci_upper"]=sources_dict[new].data["ci_upper"]select = Select(title="Taxonomic Class:", value="Mammalia", options=list(sources_dict.keys()))select.on_change("value", select_handler)curdoc().add_root(bk.layouts.row(plot, select))我试过这个:我怀疑错误出在回调函数中,因此我尝试了许多不同的变体,但都得到了相同的错误结果。我将在这里列出其中一些:我尝试使用 python 本机字典:new_data= {        'species': sources_dict[new].data["species"],        'ci_lower': sources_dict[new].data["ci_lower"],        'ci_upper': sources_dict[new].data["ci_upper"]    }    source.data=new_data
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

在评论中回答您的问题,更改data不会更改范围,因为y_range=some_thing这只是为了方便创建在幕后完成的适当范围类。


以下是您可以手动执行此操作的方法。请注意,我根本不碰x_range- 默认情况下它会DataRange1d自动计算其开始/结束值。


from bokeh.io import curdoc

from bokeh.layouts import column

from bokeh.models import Select, ColumnDataSource

from bokeh.plotting import figure


d1 = dict(x=[0, 1], y=['a', 'b'])

d2 = dict(x=[8, 9], y=['x', 'y'])

ds = ColumnDataSource(d1)



def get_factors(data):

    return sorted(set(data['y']))



p = figure(y_range=get_factors(d1))

p.circle(x='x', y='y', source=ds)


s = Select(options=['1', '2'], value='1')



def update(attr, old, new):

    if new == '1':

        ds.data = d1

    else:

        ds.data = d2

    p.y_range.factors = get_factors(ds.data)



s.on_change('value', update)


curdoc().add_root(column(p, s))


查看完整回答
反对 回复 2023-10-31
  • 1 回答
  • 0 关注
  • 123 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信