python - 将 bupaR 的动画流程图集成到 Python 中的 Bokeh 仪表板中;有办法吗?

标签 python r animation bokeh dashboard

我正在尝试用 Python 开发 Bokeh 仪表板,我想向其中添加流程挖掘功能。我有使用 bupaR 的经验R 中的包,其中包含非常漂亮的动画流程图,这是我想要在我制作的仪表板中实现的内容。
我看过一些关于如何在 Python 中实现 R 代码的文档,即 r2py , 一些 ggplot在 Bokeh 仪表板等中,但我想要的似乎有点小众,我不确定是否可能。 Python 确实有一个 pm4py扩展到 bupaR但到目前为止,我还没有看到一种在 Bokeh 仪表板中实现类似于 R 中的动画流程图的方法。
只是为了提供某种示例(尽管不相关但仅用于演示目的),这里是一些用于集群应用程序 Bokeh 仪表板的 Python 代码:-

#https://raw.githubusercontent.com/bokeh/bokeh/master/examples/app/clustering/main.py

import numpy as np
from sklearn import cluster, datasets
from sklearn.neighbors import kneighbors_graph
from sklearn.preprocessing import StandardScaler

from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Select, Slider
from bokeh.palettes import Spectral6
from bokeh.plotting import figure

np.random.seed(0)



# define some helper functions
def clustering(X, algorithm, n_clusters):
    # normalize dataset for easier parameter selection
    X = StandardScaler().fit_transform(X)

    # estimate bandwidth for mean shift
    bandwidth = cluster.estimate_bandwidth(X, quantile=0.3)

    # connectivity matrix for structured Ward
    connectivity = kneighbors_graph(X, n_neighbors=10, include_self=False)

    # make connectivity symmetric
    connectivity = 0.5 * (connectivity + connectivity.T)

    # Generate the new colors:
    if algorithm=='MiniBatchKMeans':
        model = cluster.MiniBatchKMeans(n_clusters=n_clusters)

    elif algorithm=='Birch':
        model = cluster.Birch(n_clusters=n_clusters)

    elif algorithm=='DBSCAN':
        model = cluster.DBSCAN(eps=.2)

    elif algorithm=='AffinityPropagation':
        model = cluster.AffinityPropagation(damping=.9,
                                            preference=-200)

    elif algorithm=='MeanShift':
        model = cluster.MeanShift(bandwidth=bandwidth,
                                  bin_seeding=True)

    elif algorithm=='SpectralClustering':
        model = cluster.SpectralClustering(n_clusters=n_clusters,
                                           eigen_solver='arpack',
                                           affinity="nearest_neighbors")

    elif algorithm=='Ward':
        model = cluster.AgglomerativeClustering(n_clusters=n_clusters,
                                                linkage='ward',
                                                connectivity=connectivity)

    elif algorithm=='AgglomerativeClustering':
        model = cluster.AgglomerativeClustering(linkage="average",
                                                affinity="cityblock",
                                                n_clusters=n_clusters,
                                                connectivity=connectivity)

    elif algorithm=='KMeans':
        model = cluster.KMeans(n_clusters= n_clusters)                                        

    model.fit(X)

    if hasattr(model, 'labels_'):
            y_pred = model.labels_.astype(int)
    else:
            y_pred = model.predict(X)

    return X, y_pred

def get_dataset(dataset, n_samples):
    if dataset == 'Noisy Circles':
        return datasets.make_circles(n_samples=n_samples,
                                    factor=0.5,
                                    noise=0.05)

    elif dataset == 'Noisy Moons':
        return datasets.make_moons(n_samples=n_samples,
                                   noise=0.05)

    elif dataset == 'Blobs':
        return datasets.make_blobs(n_samples=n_samples,
                                   random_state=8)

    elif dataset == "No Structure":
        return np.random.rand(n_samples, 2), None

# set up initial data
n_samples = 1500
n_clusters = 2
algorithm = 'MiniBatchKMeans'
dataset = 'Noisy Circles'

X, y = get_dataset(dataset, n_samples)
X, y_pred = clustering(X, algorithm, n_clusters)
spectral = np.hstack([Spectral6] * 20)
colors = [spectral[i] for i in y]

# set up plot (styling in theme.yaml)
plot = figure(toolbar_location=None, title=algorithm)
source = ColumnDataSource(data=dict(x=X[:, 0], y=X[:, 1], colors=colors))
plot.circle('x', 'y', fill_color='colors', line_color=None, source=source)

# set up widgets
clustering_algorithms= [
    'MiniBatchKMeans',
    'AffinityPropagation',
    'MeanShift',
    'SpectralClustering',
    'Ward',
    'AgglomerativeClustering',
    'DBSCAN',
    'Birch',
    'KMeans'
]

datasets_names = [
    'Noisy Circles',
    'Noisy Moons',
    'Blobs',
    'No Structure'
]

algorithm_select = Select(value='MiniBatchKMeans',
                          title='Select algorithm:',
                          width=200,
                          options=clustering_algorithms)

dataset_select = Select(value='Noisy Circles',
                        title='Select dataset:',
                        width=200,
                        options=datasets_names)

samples_slider = Slider(title="Number of samples",
                        value=1500.0,
                        start=1000.0,
                        end=3000.0,
                        step=100,
                        width=400)

clusters_slider = Slider(title="Number of clusters",
                         value=2.0,
                         start=2.0,
                         end=10.0,
                         step=1,
                         width=400)

# set up callbacks
def update_algorithm_or_clusters(attrname, old, new):
    global X

    algorithm = algorithm_select.value
    n_clusters = int(clusters_slider.value)

    X, y_pred = clustering(X, algorithm, n_clusters)
    colors = [spectral[i] for i in y_pred]

    source.data = dict(colors=colors, x=X[:, 0], y=X[:, 1])

    plot.title.text = algorithm

def update_samples_or_dataset(attrname, old, new):
    global X, y

    dataset = dataset_select.value
    algorithm = algorithm_select.value
    n_clusters = int(clusters_slider.value)
    n_samples = int(samples_slider.value)

    X, y = get_dataset(dataset, n_samples)
    X, y_pred = clustering(X, algorithm, n_clusters)
    colors = [spectral[i] for i in y_pred]

    source.data = dict(colors=colors, x=X[:, 0], y=X[:, 1])

algorithm_select.on_change('value', update_algorithm_or_clusters)
clusters_slider.on_change('value_throttled', update_algorithm_or_clusters)

dataset_select.on_change('value', update_samples_or_dataset)
samples_slider.on_change('value_throttled', update_samples_or_dataset)

# set up layout
selects = row(dataset_select, algorithm_select, width=420)
inputs = column(selects, samples_slider, clusters_slider)

# add to document
curdoc().add_root(row(inputs, plot))
curdoc().title = "Clustering"
这会给你这样的东西:-
enter image description here
在它下面,我想放来自bupaR的过程挖掘动画。 :-
library(bupaR)
library(processanimateR)
library(eventdataR)
animate_process(patients)

这给了你这样的东西:-
enter image description here
有没有办法在 Bokeh 仪表板中部署这两个功能?或者是否有更直接的替代方法来在更原生于 Python 的 Bokeh 仪表板中创建动画流程图?

最佳答案

是的,您可以在 Bokeh 中创建动画。这实际上就像与小部件的交互。可以使用自动更改值的 add_periodic_callback 功能。
对于您的示例,如果您想更改滑块:>

def animate_update(): # animation only change slider over and over here.
    value= slider.value + 1
    if value> valuesdict[-1]:
        value= valuesdict[0]
    slider.value = value

def animate():
    global callback_id
    callback_id = curdoc().add_periodic_callback(animate_update, 500)

callback_id = None  

关于python - 将 bupaR 的动画流程图集成到 Python 中的 Bokeh 仪表板中;有办法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69250889/

相关文章:

python - 有没有办法将可选参数传递给函数?

Python 无法连接到 MySQL 数据库 : OperationalError

python - 如何将 Pyglet Sprite 与 Pymunk 形状绑定(bind),以便它们一起旋转?

RStudio 与具有可重现代码的 RCpp 一起崩溃

R - 序列颜色和标签问题的 hist3D

iphone - 如何在 iPhone 中从左到右设置动画 View ?

iPhone:如何在没有淡入淡出效果的情况下执行 kCATransitionMoveIn

python - 我可以用 python 生成真实的随机数吗?

r - 如何创建带有数字和字符列的数据框?

android - 如何使动画从屏幕底部移动到顶部?