【问题标题】:Python: How to get data from linked brushes in mlpd3, Bokeh, Plotly?Python:如何从 mlpd3、Bokeh、Plotly 中的链接画笔获取数据?
【发布时间】:2017-06-13 20:46:24
【问题描述】:

使用下面的代码,我可以得到一个包含 4 个图的 2x2 图形。使用画笔,我可以选择一些数据点。我的问题是如何将选定的数据点作为 JSON 数组或 cvs 获取。此代码使用 mlpd3,但散景可以使用画笔进行类似的选择。但没有选择数据点的示例。我正在尝试将选定的数据作为对象继续使用 python 处理。很高兴看到单元格中的数据。

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mat
import mpld3

mpld3.enable_notebook()


from mpld3 import plugins

fig, ax = plt.subplots(2, 2, figsize=(10, 8))
fig.subplots_adjust(hspace=0.1, wspace=0.1)
ax = ax[::-1]

X = np.random.normal(size=(2, 100))
for i in range(2):
    for j in range(2):
        ax[i, j].xaxis.set_major_formatter(plt.NullFormatter())
        ax[i, j].yaxis.set_major_formatter(plt.NullFormatter())
        points = ax[i, j].scatter(X[j], X[i])

plugins.connect(fig, plugins.LinkedBrush(points))

散景在 CustomJS for Selections 中具有类似的行为

http://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html#userguide-interaction-jscallbacks-customjs-interactions

哪个更容易提取所选项目 - 可以工作。如果有一个 Plotly 解决方案,那也可以工作。

【问题讨论】:

  • 在 mpld3 中没有办法做到这一点:mpld3 的输出是一个静态的 javascript 可视化,不需要(或知道)Python 后端。出于这个原因,前端和后端之间的这种通信将需要几乎完全重写库。我建议使用散景。
  • @jakevdp 谢谢!改变问题。

标签: python json plotly bokeh mpld3


【解决方案1】:

您可以使用 Plotly 的新 Dash framework 从 Plotly 图表中获取所选数据。

在“Graph Crossfiltering”https://plot.ly/dash/getting-started-part-2 下的文档中有一个示例

我在下面粘贴了完整的示例,只是为了保存历史。

在下面的每个回调中,您都可以访问选定的点、刚刚悬停的点或刚刚单击的点。此应用程序仅显示应用程序中点的值,但您可以对点执行任何操作(例如计算其他内容)。

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import json

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Graph(
        id='basic-interactions',
        figure={
            'data': [
                {
                    'x': [1, 2, 3, 4],
                    'y': [4, 1, 3, 5],
                    'text': ['a', 'b', 'c', 'd'],
                    'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
                    'name': 'Trace 1',
                    'mode': 'markers',
                    'marker': {'size': 12}
                },
                {
                    'x': [1, 2, 3, 4],
                    'y': [9, 4, 1, 4],
                    'text': ['w', 'x', 'y', 'z'],
                    'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
                    'name': 'Trace 2',
                    'mode': 'markers',
                    'marker': {'size': 12}
                }
            ]
        }
    ),

    html.Div([
        dcc.Markdown("""
            **Hover Data**

            Mouse over values in the graph.
        """.replace('   ', '')),
        html.Pre(id='hover-data')
    ], style=styles['column']),

    html.Div([
        dcc.Markdown("""
            **Click Data**

            Click on points in the graph.
        """.replace('    ', '')),
        html.Pre(id='click-data'),
    ], style=styles['column']),

    html.Div([
        dcc.Markdown("""
            **Selection Data**

            Choose the lasso or rectangle tool in the graph's menu
            bar and then select points in the graph.
        """.replace('    ', '')),
        html.Pre(id='selected-data'),
    ])
])


@app.callback(
    Output('hover-data', 'children'),
    [Input('basic-interactions', 'hoverData')])
def display_hover_data(hoverData):
    #
    # This is where you can access the hover data
    # This function will get called automatically when you hover over points
    # hoverData will be equal to an object with that data
    # You can compute something off of this data, and return it to the front-end UI
    # 


    return json.dumps(hoverData, indent=2)


@app.callback(
    Output('click-data', 'children'),
    [Input('basic-interactions', 'clickData')])
def display_click_data(clickData):
    # Similarly for data when you click on a point
    return json.dumps(clickData, indent=2)


@app.callback(
    Output('selected-data', 'children'),
    [Input('basic-interactions', 'selectedData')])
def display_selected_data(selectedData):
    # Similarly for data when you select a region
    return json.dumps(selectedData, indent=2)


if __name__ == '__main__':
    app.run_server(debug=True)

【讨论】:

  • 您可以在 jupyter 中编写此代码并逐个单元格地执行它,但最终它不会以其他方式绑定到 jupyter 内核。以下是使用 Jupyter 开发的 Dash 应用程序示例:plot.ly/~jackp/17610
  • 能否请您隔离为 jupyter notebook 回答上述问题的代码并添加到答案中。看起来有很多不需要的代码。
  • 当然 - 我刚刚删除了样式变量。我还添加了一些 cmets,以便您在悬停、单击或选择事件时访问数据。
【解决方案2】:

这在 ipython 之外,但您可以运行 flaskdjangod3.jsjquery 一起将数据返回到 python。

【讨论】:

  • FWIW - 这是 Dash 采用的一般方法,使用 flask 作为 Python 服务器,Plotly.js 作为前端图形库,fetch 作为 HTTP 请求库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 2018-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
相关资源
最近更新 更多