1

我想在Plotly极坐标图中选择角轴上的范围,我想知道最简单的方法是什么。理想情况下,如果我从 30 度到 90 度单击并拖动,那么我希望有 30 到 90 度的范围;如果我从 330 度到 30 度单击并拖动,那么我想要从 330 度到 30 度的范围。

我不太了解Plotly,但我想知道 relayoutData 是否可以利用。目前它只返回径向轴上的范围(参见图中从relayoutData返回的范围)。我想知道是否有一个参数可以改变使其返回角轴的范围?

在此处输入图像描述

这是生成上图的最少代码

import json

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd

app = dash.Dash(__name__)

df = px.data.wind()
fig = px.scatter_polar(df, r="frequency", theta="direction")

app.layout = html.Div([
    dcc.Graph(
        id='basic-interactions',
        figure=fig
    ),

    html.Div(className='row', children=[
        html.Div([
            dcc.Markdown("""
                **Zoom and Relayout Data**

                Click and drag on the graph to zoom or click on the zoom
                buttons in the graph's menu bar.
                Clicking on legend items will also fire
                this event.
            """),
            html.Pre(id='relayout-data'),
        ])
    ])
])

@app.callback(
    Output('relayout-data', 'children'),
    Input('basic-interactions', 'relayoutData'))
def display_relayout_data(relayoutData):
    return json.dumps(relayoutData, indent=2)


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

1 回答 1

0
  • 类似的想法,但你正在使用的套索点。事件被选中数据
  • 代码加上将罗盘方向解码为下面的角度
import json

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
from jupyter_dash import JupyterDash

# Build App
app = JupyterDash(__name__)
# app = dash.Dash(__name__)

df = px.data.wind()
fig = px.scatter_polar(df, r="frequency", theta="direction")

# data to translate named direction to degrees
dfd = pd.read_html("http://snowfence.umn.edu/Components/winddirectionanddegrees.htm")[1]
dfd.columns = dfd.loc[0]
dfd = (
    dfd.drop([0])
    .dropna()
    .set_index("Cardinal Direction")["Degree Direction"]
    .apply(lambda v: pd.Series(v.split(" - ")).astype(float))
)

app.layout = html.Div(
    [
        dcc.Graph(id="basic-interactions", figure=fig),
        html.Div(
            className="row",
            children=[
                html.Div(
                    [
                        dcc.Markdown(
                            """
                **Selected points**

                Use lasso to select points.  Double-click de-select for reset
            """
                        ),
                        html.Pre(id="relayout-data"),
                    ]
                )
            ],
        ),
    ]
)


@app.callback(
    Output("relayout-data", "children"),
    Input("basic-interactions", "selectedData"),
)
def display_relayout_data(selectedData):
    global dfd

    def degrees(wind_dir):
        return dfd.loc[wind_dir, 0].min(), dfd.loc[wind_dir, 1].max()

    if selectedData:
        wind_dir = [p["theta"] for p in selectedData["points"]]
        return f"{degrees(wind_dir)} {wind_dir}"

    else:
        raise dash.exceptions.PreventUpdate


if __name__ == "__main__":
    # app.run_server(debug=True)
    app.run_server(mode="inline")
于 2021-10-31T19:03:01.637 回答