Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何加快bokeh中Select/MultiSelect小部件的更新?_Python_Bokeh - Fatal编程技术网

Python 如何加快bokeh中Select/MultiSelect小部件的更新?

Python 如何加快bokeh中Select/MultiSelect小部件的更新?,python,bokeh,Python,Bokeh,我是bokeh的新手,尝试通过Select和MultiSelect小部件与绘制的数据交互。我注意到,当为这些小部件的options参数提供一个长列表(>34k项)时,性能会显著降低。从我看到的情况来看,Select只是充当mylist[mylist.index('selected_值')],而MultiSelect则充当selected_vals.append(mylist[mylist.index('selected_值'))),因此,如果真是这样,我不明白为什么小部件返回值的速度如此之慢,因

我是bokeh的新手,尝试通过Select和MultiSelect小部件与绘制的数据交互。我注意到,当为这些小部件的options参数提供一个长列表(>34k项)时,性能会显著降低。从我看到的情况来看,Select只是充当
mylist[mylist.index('selected_值')]
,而MultiSelect则充当
selected_vals.append(mylist[mylist.index('selected_值')))
,因此,如果真是这样,我不明白为什么小部件返回值的速度如此之慢,因为python可以轻松地用任意长度的列表处理这些操作。尽管我使用的是多维大数据集,但我确信加载的数据并没有真正发挥作用,因为我已经尝试将绘图更新与小部件分离,只打印从下拉菜单中选择的返回值(这可能需要30秒,甚至打开菜单也可能需要几秒钟)。我试图缩短传递给options参数的列表(不改变加载数据的大小),小部件的行为与预期的一样。是否有解决方法/修复方法? 下面是一些代码

import numpy as np
import pandas as pd
from bokeh.layouts import row, column
from bokeh.models import Select, MultiSelect, ColumnDataSource, CDSView, GroupFilter
from bokeh.palettes import Viridis256
from bokeh.plotting import curdoc, figure
from bokeh.transform import log_cmap

data = np.random.rand(11000, 3)
normExpr = np.random.rand(11000, 35000)
gene_names = np.array(np.random.rand(35000), dtype='str')
clusters = list(np.array(range(20), dtype='str'))
normExpr = pd.DataFrame(normExpr, columns=gene_names)
data = pd.DataFrame(data, columns=['PHATE1', 'PHATE2', 'color'])
data['cluster'] = clusters*550
COLORS = Viridis256[::-1]
columns = list(gene_names)[:20]

def first_fig():
    s = slice(len(data['color']))
    source = ColumnDataSource(data)
    kw = dict()
    kw['title'] = "Expression of gene %s in %s" % (gene.value.title(), cluster.value.title())
    p = figure(plot_height=500, plot_width=550, tools='pan,box_zoom,hover,reset',
               toolbar_location="above", output_backend='webgl', **kw)
    p.background_fill_color="#fafafa"
    p.xaxis.axis_label = 'X-values'
    p.yaxis.axis_label = 'Y-values'
    if gene.value != 'None' and cluster.value != 'All tissue':
        view = CDSView(source=source, filters=[GroupFilter(column_name='cluster', group=cluster.value)])
        new = normExpr[gene.value]
        source.patch({'color': [(s, new)]})
        p.circle(x='PHATE1', y='PHATE2', source=source, view=view, radius=0.002, color=log_cmap('color', COLORS, 0, 1),
                 hover_color='white', hover_alpha=0.5)

    elif gene.value == 'None' and cluster.value != 'All tissue':
        view = CDSView(source=source, filters=[GroupFilter(column_name='cluster', group=cluster.value)])
        p.circle(x='PHATE1', y='PHATE2', source=source, view=view, radius=0.002, color="#31AADE",
                 hover_color='white', hover_alpha=0.5)
    elif gene.value != 'None' and cluster.value == 'All tissue':
        new = normExpr[gene.value]
        source.patch({'color': [(s, new)]})
        p.circle(x='PHATE1', y='PHATE2', source=source, radius=0.002, color=log_cmap('color', COLORS, 0, 1),
                 hover_color='white', hover_alpha=0.5)

    else:
        p.circle(x='PHATE1', y='PHATE2', source=source, radius=0.002, color='#31AADE',
                 hover_color='white', hover_alpha=0.5)
    return p


def update(attr, old, new):
    layout.children[1] = first_fig()


cluster = Select(title='Cluster', value='All tissue', options=['All tissue'] + clusters)
cluster.on_change('value', update)
gene = Select(title='Gene', value='None', options=['None'] + columns)
gene.on_change('value', update)


controls = column([cluster, gene], width=100)
layout = row(controls, first_fig())

curdoc().add_root(layout)
curdoc().title = "Gene mapping"
  • 首先,应该强调的是,对于每个新连接,都会完整地执行此代码。特别是,顶部的第一个“数据设置”代码块在我的笔记本电脑上执行几乎需要5秒钟。Bokeh不是魔法,它不能使真正的CPU工作所需的时间少于它所需的时间。但是,如果此数据可以在会话之间共享(理想情况下为只读),则可以使用来确保此初始化仅在服务器启动时发生一次。你可以看到这种技术的具体应用

  • 接下来,值得一提的是通常建议的一般最佳实践:

    在更新中总是尽可能少地更改

    这方面的一个佐证是:

    先建立一次绘图和布局,然后只更改数据

    这是因为Bokeh经过了高度优化,可以处理数据更新(要么是
    ColumnDataSource
    中的列,要么是现有对象上的属性值)。当您像在
    update
    函数中那样“从头开始”重新创建所有内容时,使用Bokeh的效率极低。换句话说,如果一个应用程序看起来像这样,那么它的总体轮廓总是最好的:

    p = figure(...)
    
    view = GroupFilter(...)
    source = ColumnDataSource(...)
    
    # create all the glyphs you will *ever* need up front
    # can set unused ones .visible = False
    
    select = Select(...)
    
    def update(attr, old, new):
        # Update existing source or view here, toggle .visible on glyphs, etc
        # But don't make new objects
    
    curdoc().add_root(column(plot, select)
    
  • 最后,从尝试关闭WebGL开始。它目前没有维护人员,并且存在一些问题。11k点通常应在标准Bokeh画布渲染的范围内,除非可能存在大量重叠和alpha合成。在这种情况下,您可能需要考虑哪些可以驱动BoKh和一起。
不幸的是,对于我来说,根据这些指南重写您的整个示例太复杂了,但希望它们能为您指明正确的方向。

  • 首先,应该强调的是,对于每个新连接,都会完整地执行此代码。特别是,顶部的第一个“数据设置”代码块在我的笔记本电脑上执行几乎需要5秒钟。Bokeh不是魔法,它不能使真正的CPU工作所需的时间少于它所需的时间。但是,如果此数据可以在会话之间共享(理想情况下为只读),则可以使用来确保此初始化仅在服务器启动时发生一次。你可以看到这种技术的具体应用

  • 接下来,值得一提的是通常建议的一般最佳实践:

    在更新中总是尽可能少地更改

    这方面的一个佐证是:

    先建立一次绘图和布局,然后只更改数据

    这是因为Bokeh经过了高度优化,可以处理数据更新(要么是
    ColumnDataSource
    中的列,要么是现有对象上的属性值)。当您像在
    update
    函数中那样“从头开始”重新创建所有内容时,使用Bokeh的效率极低。换句话说,如果一个应用程序看起来像这样,那么它的总体轮廓总是最好的:

    p = figure(...)
    
    view = GroupFilter(...)
    source = ColumnDataSource(...)
    
    # create all the glyphs you will *ever* need up front
    # can set unused ones .visible = False
    
    select = Select(...)
    
    def update(attr, old, new):
        # Update existing source or view here, toggle .visible on glyphs, etc
        # But don't make new objects
    
    curdoc().add_root(column(plot, select)
    
  • 最后,从尝试关闭WebGL开始。它目前没有维护人员,并且存在一些问题。11k点通常应在标准Bokeh画布渲染的范围内,除非可能存在大量重叠和alpha合成。在这种情况下,您可能需要考虑哪些可以驱动BoKh和一起。

不幸的是,我无法根据这些指导方针重写您的整个示例,但希望它们能为您指明正确的方向。

使用Microsoft Edge时,这个问题似乎发生了变化。我将浏览器改为Chrome,脚本工作正常。但仍然无法解释在使用Edge时,性能与提供给select widget的选项列表长度之间的依赖关系。

似乎仅在使用Microsoft Edge时,问题就发生了变化。我将浏览器改为Chrome,脚本工作正常。但是,在使用Edge时,仍然无法解释性能与提供给select小部件的选项列表长度的依赖关系。

Hello@Bruno和welcome on Stack Overflow。你能针对你所面临的问题创建一个焦点吗?嗨,很抱歉给你带来困惑!编辑后的版本应该可以使用。第二个函数和第三个函数不是很重要,可以跳过。如果我在第17行传递完整的gene_名称列表,问题就会出现(正如您现在注意到的,我只传递前20个条目)。有了完整的列表,每一个更改似乎都需要花费很长时间(即使只是点击打开选择小部件的下拉菜单)。你能针对你所面临的问题创建一个焦点吗?嗨,很抱歉给你带来困惑!编辑后的版本应该可以使用。第二个fig()和第三个fi()funti