【问题标题】:Bokeh - unable to update ColumnDataSource upon change in dropdown menu散景 - 下拉菜单更改后无法更新 ColumnDataSource
【发布时间】:2019-05-22 21:51:05
【问题描述】:

从下拉列表中选择新值时,我在更新基础 ColumnDataSource 时遇到问题。在“update_data”部分,我正在为我的绘图更改底层 ColumnDataSource 的值。误差线在图上得到更新,但绘制的数据不会改变。我已经简化了下面的代码。知道如何更新所有数据,而不仅仅是错误栏吗?

from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Slider, TextInput
from bokeh.plotting import figure
from bokeh.io import output_file, show
from bokeh.models.widgets import Dropdown
import pandas as pd
import numpy as np
from bokeh.io import output_file, show, curdoc
from bokeh.layouts import row, column, widgetbox
from bokeh.models import (
    ColumnDataSource,
    HoverTool,
    LinearColorMapper,
    BasicTicker,
    PrintfTickFormatter,
    ColorBar,
    Legend,
    Whisker,
)
from bokeh.models.widgets import PreText, Select, RadioGroup, TextInput
from bokeh.plotting import figure
from bokeh.transform import dodge, factor_cmap
import bokeh.plotting
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button
import io
import base64
import random
import statistics as stat
from bokeh.models.tickers import SingleIntervalTicker
from bokeh.plotting import figure, show




def sectionize(df, rows, cols):
    rowWise = df.stack()
    colWise = df.transpose().stack()
    rowData = []
    colData = []
    for x in rows:
        rowData.append(list(rowWise[x]))
    for x in range(1, (cols + 1)):
        colData.append(list(colWise[x]))
    print("sectionize has occured")
    return rowData, colData

def getLowerUpper(data):
    lower, upper = [], []
    for x in data:
        if x:
            mean = stat.mean(x)
            std = stat.stdev(x)
            lower.append(mean - std)
            upper.append(mean + std)
        else:
            lower.append(0)
            upper.append(0)
    return lower, upper

def sectionizePlot(source, source_error, type, base):
    print("sectionize plot created with typ: " + type)
    colors = []
    for x in range(0, len(base)):
        colors.append(getRandomColor())
    title = type + "-wise Intensity Distribution"
    p = figure(plot_width=600, plot_height=300, title=title)
    p.add_layout(
        Whisker(source=source_error, base="base", upper="upper", lower="lower"))
    for i, sec in enumerate(source.data['base']):
        p.circle(x=source_error.data["base"][i], y=sec, color=colors[i])
    p.xaxis.axis_label = type
    p.yaxis.axis_label = "Intensity"
    if (type.split()[-1] == "Row"):
        print("hit a row")
        conv = dict(enumerate(list("nABCDEFGHIJKLMNOP")))
        conv.pop(0)
        p.xaxis.major_label_overrides = conv
    p.xaxis.ticker = SingleIntervalTicker(interval=1)
    print("sectionizePlot changed")
    return p

def getRandomColor():
    colors = ['aqua', 'aquamarine', 'black', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate',
         'coral', 'cornflowerblue', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen',
         'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon',
         'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink',
         'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'forestgreen', 'fuchsia', 'gold', 'goldenrod',
         'gray', 'green', 'greenyellow', 'grey', 'hotpink', 'indianred', 'indigo', 'khaki', 'lavender', 'lawngreen', 'lime',
         'limegreen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple',
         'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue',
         'navy', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue',
         'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'sienna', 'silver',
         'skyblue', 'slateblue', 'slategray', 'slategrey', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato',
              'turquoise', 'violet', 'yellow', 'yellowgreen']
    return colors[random.randint(0, 101)]


colBase = list(range(1, 3))
colData = [[1,2,3,4,5,6], [7, 8, 9, 10, 11, 12]]
colData_lower, colData_upper = getLowerUpper(colData)
colSectTotSource = ColumnDataSource(data=dict(base=[]))
colSectTotSource_error = ColumnDataSource(data=dict(base=[], lower=[], upper=[]))
colSectTotSource.data = dict(base=colData)
colSectTotSource_error.data = dict(base=colBase, lower=colData_lower, upper=colData_upper)

menu = [("A", "A"), ("B", "B")]
dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu)
colPlot = sectionizePlot(colSectTotSource, colSectTotSource_error, "Column", colBase)

def update_data(attrname, old, new):
    d = dropdown.value
    if(d == "B"):
        colData = [[11,12,13,14,15,16], [17,18,19,20,21,22]]
    else:
        colData = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]

    colData_lower, colData_upper = getLowerUpper(colData)
    #colSectTotSource = ColumnDataSource(data=dict(base=[]))
    colSectTotSource.data = dict(base=colData)
    colSectTotSource_error.data = dict(base=colBase, lower=colData_lower, upper=colData_upper)

for w in [dropdown]:
    w.on_change('value', update_data)

inputs = column(dropdown)
curdoc().add_root(row(inputs, colPlot, width=800))

【问题讨论】:

    标签: python bokeh


    【解决方案1】:

    圈子没有更新,因为您实际上并未配置对圈子的调用以使用源:

    p.circle(x=source_error.data["base"][i], y=sec, color=colors[i])
    

    当您将实际列表/数组作为xy 等传递时,就像您在上面所做的那样,Bokeh 会创建一个新的 CDS 以供内部使用。如果你想让一个字形使用你传入的源,你实际上必须传入它,并且坐标应该只引用该源的列名:

    my_source = ColumnDataSource(data=dict(foo=[...], bar=[...]))
    p.circle(x="foo", y="bar", source=my_source)
    

    此外,您的 CDS 中的数据格式不适合这种用法:

    {'base': [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]}
    

    顾名思义,ColumnDataSource 包含。每列的值需要是一个一维数组或列表,而不是你这里的列表列表(少数“多”字形接受这一点,但不接受圆形等) . IE。您需要为每个圈子设置一个单独的列,而不是每个圈子都有一个带有“子列表”的列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 2020-03-29
      • 1970-01-01
      相关资源
      最近更新 更多