简体   繁体   中英

Display of trace values of all sub plots at the bottom of figure in Plotly

I am working on data visualization using plotly.

I have generated a plot of 3 traces that share the x axis using make_subplots . I need to display the corresponding y value for all traces at the bottom of the figure by hovering somewhere along the x axis.

Below is the code for generating subplots.

import plotly
import plotly.graph_objs as go
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

import pandas as pd
import re

df = pd.read_csv("finance-charts-apple.csv")

fig = make_subplots(
    rows=3, cols=1,
    shared_xaxes=True,
    vertical_spacing=0.0,
    horizontal_spacing = 0.0,
    specs=[[{"type": "scatter"}],
           [{"type": "scatter"}],
           [{"type": "scatter"}]])
    
fig.add_trace(
    go.Scattergl(
        x=df.Date,
        y=df['AAPL.High'],
        mode="lines",
        name="AAPL_high"
    ),
    row=1, col=1
)    

fig.add_trace(
    go.Scattergl(
        x=df.Date,
        y=df['AAPL.Low'],
        mode="lines",
        name="AAPL_low"
    ),
    row=2, col=1
)    

fig.add_trace(
    go.Scattergl(
        x=df.Date,
        y=df['AAPL.Close'],
        mode="lines",
        name="AAPL_Close"
    ),
    row=3, col=1
) 

fig.update_layout(
    height=800,
    showlegend=True,
    title_text="Apple market share",
    hovermode= 'x unified',
    hoverinfo= "x+y",
    spikedistance= -1,
    xaxis = dict(
            showspikes = True,
            spikemode = 'across + toaxis',
            spikesnap = 'cursor',
            showline= True,
            showgrid = True,
            spikedash = 'solid'))

fig.update_xaxes(matches='x')
fig.update_traces(xaxis='x1')
fig.show()
plotly.offline.plot(fig)

As per above code, I am able to plot 3 subplots with vertical hover across all the subplots.

What I want to know is, is there any way to display every trace's y value for a particular x value, at the bottom of the figure, like in the image below?

在此处输入图像描述

I was searching for something similar for my Dash app and ended up passing the hoverData from dcc.Graph to a callback function that displays the values in a seperate div.

import pandas as pd
import dash
from jupyter_dash import JupyterDash
from dash import dcc
from dash import html
from plotly.subplots import make_subplots
import plotly.graph_objects as go


df = pd.read_pickle("freq_simulation_22_03_2022.pkl")

app = JupyterDash(__name__)

server = app.server

## Setup fig
fig = make_subplots(
    rows=3,
    cols=1,
    shared_xaxes=True,
    vertical_spacing=0.01,
    x_title="DDS Frequency [Hz]",
)

## Add the 3 subplots
fig.add_trace(
    go.Scatter(x=df.index, y=df["best_factor"], mode="markers", name="best_factor"),
    row=1,
    col=1,
)

fig.add_trace(
    go.Scatter(x=df.index, y=df["best_divider"], mode="markers", name="best_divider"),
    row=2,
    col=1,
)

fig.add_trace(
    go.Scatter(x=df.index, y=df["error"], mode="markers", name="error"), row=3, col=1
)

fig["layout"]["yaxis1"]["title"] = "Best Undersampling Factor"
fig["layout"]["yaxis2"]["title"] = "Best ADC Divider"
fig["layout"]["yaxis3"]["title"] = "Frequency Error [Hz]"


fig.update_layout(
    height=900,
    title_text="Best Undersampling Factor with remaining Frequency Error over DDS Frequency",
    hovermode="x unified",
    spikedistance=-1,
)
fig.update_xaxes(matches="x2")
fig.update_traces(xaxis="x3")

app.layout = html.Div(
    [
        dcc.Graph(id="testgraph", figure=fig),
        html.Div(
            id="my-output",
            style={
                "font-family": "Helvetica",
                "fontSize": 20,
                "position": "absolute",
                "top": "10vmax",
                "right": "0vmax",
                "white-space": "pre-wrap",
            },
        ),
    ],
    style={"position": "relative"},
)


@app.callback(
    dash.dependencies.Output("my-output", "children"),
    [dash.dependencies.Input("testgraph", "hoverData")],
)
def update_graph(hoverData):
    if not hoverData:
        hoverfreq = df.index[0]
    else:
        hoverfreq = hoverData["points"][0]["x"]
    hover_factor = df["best_factor"][hoverfreq]
    hover_divider = df["best_divider"][hoverfreq]
    hover_error = df["error"][hoverfreq]
    return f"Freq: {hoverfreq}Hz\n -> Factor: {hover_factor}\n -> Divider: {hover_divider}\n -> Error: {hover_error:1.6f}Hz"


app.run_server(port=8010, height=1000)

结果 在此处输入图像描述

As of July 21 2020, unified hovermodes are not yet implemented for plotly subplots (v4.4.x).

There's an open issue on this very feature on their js repository, but it's a valid request for all distributions. You can subscribe to it at https://github.com/plotly/plotly.js/issues/4755 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM