为了账号安全,请及时绑定邮箱和手机立即绑定

散景中的交互式散点高光

散景中的交互式散点高光

素胚勾勒不出你 2022-05-11 15:11:59
我正在尝试可视化与其路径相关的传感器输出。我在一个图中将路径绘制为散点图,在第二个图中绘制一定范围的信号幅度。我需要可视化(突出显示)获取特定读数的路径点。我开始使用散景作为后端,总的来说,我需要的可视化效果非常好。但我被困在这种特殊的互动上。我想要一些标记,例如锚定在图形中间的垂直线。当我移动/滚动幅度图(底部)时,我想突出显示路径图上最接近标记线的读数的点。示例代码:(我想锚定标记线并在红点和垂直线之间添加交互,获取信号的索引,未实现。)import numpy as npimport pandas as pdfrom bokeh.io import output_filefrom bokeh.models import ColumnDataSource, HoverTool, Spanfrom bokeh.plotting import figure, showfrom bokeh.layouts import gridplotoutput_file('interactive_path_sig.html', title="interactive path")class InteractivePath():    def __init__(self):        x = np.arange(0, 1000, 0.5)        self.df = pd.DataFrame({"x": x,                                "y": np.sin(x),                                "z": np.cos(x)})        self.source = ColumnDataSource(self.df)    def plot_path(self):        plt = figure(title = "Sensor Path")        plt.scatter(x="x", y="y",source=self.source,                     line_color=None, size = 6)        # TODO implement interaction instead of hard coded index        index=500    # this is where I think I need to create working callback        print("x={}, y={}".format(self.df['x'][index], self.df['y'][index]))        plt.circle(x=self.df['x'][index], y=self.df['y'][index],                    fill_color="red", size=15)        hover = HoverTool()        hover.tooltips=[("index", "@index"), ("senosr","@z")]        plt.add_tools(hover)        return plt    def plot_signal(self):        plt = figure(x_range=(450, 550), title="Signal Amplitude")        plt.line(x="index", y="z", source=self.source, line_color="black", line_width=2)        # TODO implement interaction instead of hard coded index        index = 500  # I think this needs emit some singal to other plot        vline = Span(location=index, dimension='height', line_color='red', line_width=3)        plt.renderers.extend([vline])        return plt
查看完整描述

1 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

所以有几点建议:

  • 我认为您会希望这两个图都使用相同的方法,因为它们之间的 columndatasource 是通用的,并且如果它们在同一范围内,您可以在它们之间设置 CustomJS 行为。

  • index您正在使用的 已经存在于您的self.df绘图中,一旦它出现在您的绘图中,将更容易与之交互,因为您可以使用 JS 绘图行为来处理它,而不是返回到 python 变量并重新加载数据。

  • 不要为“突出显示”点绘制新字形,而是考虑使用内置的“悬停”或“选定”功能。hover_color='red'例如,可以替换绘制和移动另一类字形。如果您想保持静态选中状态,以便在屏幕截图中无需鼠标即可生成漂亮的报告,请使用的内置selected属性定义回调ColumnDataSource

我可以发布一些带有更具体示例的实际代码块,但如果这些点中的任何一点对于您的实际用例来说是一个硬停止,它将推动解决方案。


编辑:

所以我使用一个类方法非常接近 - 问题是能够从第一个方法编辑第二个图,而不是对它ColumnDataSource本身的实际更改。

def plot_it(self):

    self.plot_signal = figure(x_range=(450, 550), y_range=(-1, 1), title='signal')

    self.plot_signal.line(x='index', y='z', source=self.source)

    self.plot_signal.segment(x0=500, y0=-2, x1=500, y1=2, source=self.source)


    self.plot_path = figure(title='sensor')

    self.plot_path.scatter(x='x', y='y', source=self.source, hover_color='red')


    jscode='''

    var data = source.data;

    var plot_signal = plot_signal;

    var index = cb_data.index['1d'].indices;

    var xmin = 0;

    var xmax = 0;

    if (index > 0) {

        xmin = index[0] - 50;

        xmax = index[0] + 50;

        plot_signal.x_range.end = xmax;

        plot_signal.x_range.start = xmin;

        plot_signal.change.emit();

    }


    hover_callback = CustomJS(args=dict(source=self.source, plot_signal=self.plot_signal), code=jscode)

    hover.tooltips = [('index', '@index'), ('sensor', '@z')]

    self.plot_path.add_tools(hover)


def get_grid(self):

    self.plot_it()

    grid = gridplot([[self.plot_path], [self.plot_signal]])

    return grid

除了移动线段之外,这应该做所有事情。我找不到要添加的段命名约定plot_signal.SOMEOBJECT.x0,.x1但它只会if (index > 0)像使用index[0]. 我去掉了一些样式选项,因为我正在从另一台计算机转录。


这个关于移动线段的问题可能会为您提供段 JSON 对象的语法。


查看完整回答
反对 回复 2022-05-11
  • 1 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信