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

问题


我想创建一个交互式 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



杨魅力
浏览 124回答 1
1回答

阿波罗的战车

在评论中回答您的问题,更改data不会更改范围,因为y_range=some_thing这只是为了方便创建在幕后完成的适当范围类。以下是您可以手动执行此操作的方法。请注意,我根本不碰x_range- 默认情况下它会DataRange1d自动计算其开始/结束值。from bokeh.io import curdocfrom bokeh.layouts import columnfrom bokeh.models import Select, ColumnDataSourcefrom bokeh.plotting import figured1 = 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))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python