Вы можете добавить цвет к источнику columndatasource и изменить его при вызове функции обратного вызова и, если условие истинно. Добавил несколько комментариев к коду, чтобы объяснить, что я изменил.
from bokeh.plotting import figure
import numpy as np
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import Button
from bokeh.layouts import widgetbox
from bokeh.plotting import ColumnDataSource
button = Button(label='Update Data')
def generate_time_differences(n=1000, skew_p=0.1, mean=0, std=1, skew_mean=1, skew_std=6):
normal_dist = np.random.normal(loc=mean, scale=std, size=int(n * (1 - skew_p)))
skewed_dist = np.random.normal(loc=skew_mean, scale=skew_std, size=int(n * skew_p))
return np.append(normal_dist, skewed_dist)
def generate_plot_data(data, density=True, bins=50):
hist, edges = np.histogram(data, density=density, bins=bins)
df = pd.DataFrame({'top': hist,
'left': edges[:-1],
'right': edges[1:]}
)
df['mean'] = [np.mean(data) for i in range(len(df))]
df['std'] = [np.std(data) for i in range(len(df))]
df['n'] = [len(data) for i in range(len(df))]
return ColumnDataSource(df)
def create_histogram(plot_data_control, plot_data_observed, title, x_axis_label='Milliseconds',
y_axis_label='Frequency'):
mean_control = np.mean(plot_data_control.data['mean'])
mean_observed = np.mean(plot_data_observed.data['mean'])
#Change color if mean_observed > mean_control
if mean_observed > mean_control:
color_observed = 'yellow'
else:
color_observed = 'green'
#Generate a list with the right color
colorlst = []
for i in range(len(plot_data_observed.data['top'])):
colorlst.append(color_observed)
#Add color list to sourcedata
plot_data_observed.data['color'] = colorlst
p = figure(plot_height=150, plot_width=600,
title=title,
x_axis_label=x_axis_label,
y_axis_label=y_axis_label)
# Add a quad glyph for plot_data
p.quad(source=plot_data_control, bottom=0, top='top', left='left', right='right',
fill_color='gray', line_color='gray', fill_alpha=0.5, line_alpha=0.5, legend='Control')
# Add another quad glyph for plot_data2
#Get color from source
p.quad(source=plot_data_observed, bottom=0, top='top', left='left', right='right',
fill_color='color', line_color='color', fill_alpha=0.5, line_alpha=0.5, legend='Observed')
p.legend.click_policy="hide"
return p
def update():
mean = np.random.randint(500,1500)
std = 100
skew_mean = 2000
skew_std = 500
new_plot_data = generate_time_differences(n=100, skew_p=0.1, mean=mean, std=std, skew_mean=skew_mean, skew_std=skew_std)
obs_data = generate_plot_data(new_plot_data).data
#Get means
mean_control = plot_data.data['mean'][0]
mean_observed = obs_data['mean'][0]
#Change color if mean_observed > mean_control
if mean_observed > mean_control:
color_observed = 'yellow'
else:
color_observed = 'green'
#Generate a list with the right color
colorlst = []
for i in range(len(obs_data['top'])):
colorlst.append(color_observed)
#Add list to dictionary
obs_data['color'] = colorlst
#Set dictionary as sourcedata
plot_data2.data = obs_data
data = generate_time_differences(n=1000, skew_p=0.1, mean=1000, std=100, skew_mean=2000, skew_std=500)
data2 = generate_time_differences(n=100, skew_p=0.1, mean=1050, std=100, skew_mean=2100, skew_std=500)
plot_data = generate_plot_data(data)
plot_data2 = generate_plot_data(data2)
p1 = create_histogram(plot_data, plot_data2, 'Status1 to Status2')
button.on_click(update)
layout = column(widgetbox(button), p1)
curdoc().add_root(layout)