Trend and Bar Chart with custom hoverinfo AND normal x axis hover label

Is it possible to have custom hoverinfo in addition to having the x axis values show along the axis?

In this example, is seems that that the Y value HAS to show up in the hoverinfo:

…Ideally in this example, when hovering over the orange dots I would only want to show “Text G”, “Text H”, “Text I”, and while doing so, having the black ticker on the x-axis show the value of the x that is aligned.

The reason for separating the x axis value out is because I am trying to build a chart that has several line traces and well as bars… It would be redundant to show the x-axis value in every tracers hoverinfo.

Here’s the code so far to the chart I am trying to put together

Thanks!

    dcc.Graph(id='pmd-chart',
              # Start hoverData with most recent data point for callback to run off of
              hoverData={'points': [{'x': actual.index.max().date(),
                                     'y': latest['CTL'].max()},
                                    {'y': latest['ATL'].max()},
                                    {'y': latest['TSB'].max()}]},
              style={'height': '750', 'marginLeft': '0', 'marginRight': '0'}, figure={
            'data': [
                go.Scatter(
                    name='Fitness (CTL)',
                    x=actual.index,
                    y=round(actual['CTL'], 1),
                    mode='lines',
                    text=actual['ctl_tooltip'],
                    hoverinfo='text',
                    opacity=0.7,
                    line={'shape': 'spline', 'color': ctl_color},
                ),
                go.Scatter(
                    name='Fitness (CTL) Forecast',
                    x=forecast.index,
                    y=round(forecast['CTL'], 1),
                    mode='lines',
                    text=forecast['ctl_tooltip'],
                    hoverinfo='text',
                    opacity=0.7,
                    line={'shape': 'spline', 'color': ctl_color, 'dash': 'dot'},
                    showlegend=False,
                ),
                go.Scatter(
                    name='Fatigue (ATL)',
                    x=actual.index,
                    y=round(actual['ATL'], 1),
                    mode='lines',
                    text=actual['atl_tooltip'],
                    hoverinfo='text',
                    line={'color': atl_color},
                ),
                go.Scatter(
                    name='Fatigue (ATL) Forecast',
                    x=forecast.index,
                    y=round(forecast['ATL'], 1),
                    mode='lines',
                    text=forecast['atl_tooltip'],
                    hoverinfo='text',
                    line={'color': atl_color, 'dash': 'dot'},
                    showlegend=False,
                ),
                go.Scatter(
                    name='Form (TSB)',
                    x=actual.index,
                    y=round(actual['TSB'], 1),
                    mode='lines',
                    text=actual['tsb_tooltip'],
                    hoverinfo='text',
                    opacity=0.7,
                    line={'color': tsb_color},
                    fill='tozeroy',
                    fillcolor=tsb_fill_color,
                ),
                go.Scatter(
                    name='Form (TSB) Forecast',
                    x=forecast.index,
                    y=round(forecast['TSB'], 1),
                    mode='lines',
                    text=forecast['tsb_tooltip'],
                    hoverinfo='text',
                    opacity=0.7,
                    line={'color': tsb_color, 'dash': 'dot'},
                    showlegend=False,
                ),
                go.Bar(
                    name='Stress',
                    x=actual.index,
                    y=round(actual['stress_score'], 1),
                    # mode='markers',
                    yaxis='y2',
                    text=actual['stress_tooltip'],
                    hoverinfo='text',
                    marker={'color': 'rgba(127, 127, 127, 1)'}
                ),
                go.Scatter(
                    name='Ramp Rate',
                    x=actual.index,
                    y=round(actual['Ramp_Rate'], 1),
                    mode='lines',
                    # hoverinfo='text',
                    opacity=0.7,
                    line={'color': '#7F7F7F'},
                    visible='legendonly',
                ),
                go.Scatter(
                    name='Freshness',
                    text=['Freshness' if x == pmd.index.max() else '' for x in pmd.index],
                    textposition='top left',
                    x=pmd.index,
                    y=[25 for x in pmd.index],
                    mode='lines+text',
                    hoverinfo='none',
                    line={'dash': 'dashdot', 'color': 'rgba(127, 127, 127, .35)'},
                    showlegend=False,
                ),
                go.Scatter(
                    name='Neutral',
                    text=['Neutral' if x == pmd.index.max() else '' for x in pmd.index],
                    textposition='top left',
                    x=pmd.index,
                    y=[5 for x in pmd.index],
                    mode='lines+text',
                    hoverinfo='none',
                    line={'dash': 'dashdot', 'color': 'rgba(127, 127, 127, .35)'},
                    showlegend=False,
                ),
                go.Scatter(
                    name='Optimal',
                    text=['Optimal' if x == pmd.index.max() else '' for x in pmd.index],
                    textposition='top left',
                    x=pmd.index,
                    y=[-10 for x in pmd.index],
                    mode='lines+text',
                    hoverinfo='none',
                    line={'dash': 'dashdot', 'color': 'rgba(127, 127, 127, .35)'},
                    showlegend=False,
                ),
                go.Scatter(
                    name='Overload',
                    text=['Overload' if x == pmd.index.max() else '' for x in pmd.index],
                    textposition='top left',
                    x=pmd.index,
                    y=[-30 for x in pmd.index],
                    mode='lines+text',
                    hoverinfo='none',
                    line={'dash': 'dashdot', 'color': 'rgba(127, 127, 127, .35)'},
                    showlegend=False,
                ),
            ],
            'layout': go.Layout(
                xaxis=dict(
                    showgrid=False,
                    showticklabels=True,
                    # Specify range to get rid of auto x-axis padding when using scatter markers
                    range=[pmd.index.max() - timedelta(days=43 + forecast_days), pmd.index.max()],
                    # default L6W
                    rangeselector=dict(
                        buttons=list([
                            # Specify row count to get rid of auto x-axis padding when using scatter markers
                            dict(count=(len(pmd) + 1),
                                 label='Reset',
                                 step='day',
                                 stepmode='backward'),
                            dict(count=1,
                                 label='YTD',
                                 step='year',
                                 stepmode='todate'),
                            dict(count=43 + forecast_days,
                                 label='L6W',
                                 step='day',
                                 stepmode='backward'),
                            dict(count=30 + forecast_days,
                                 label='L30D',
                                 step='day',
                                 stepmode='backward'),
                            dict(count=8 + forecast_days,
                                 label='L7D',
                                 step='day',
                                 stepmode='backward')
                        ]),
                        xanchor='center',
                        x=.5,
                        y=.93,
                    ),
                ),
                yaxis2=dict(
                    showticklabels=False,
                    range=[0, pmd['stress_score'].max() * 5],
                    showgrid=False,
                    type='linear',
                    side='right',
                    anchor='x',
                    overlaying='y',
                    layer='above traces'
                ),
                yaxis3=dict(
                    showticklabels=False,
                    range=[0, df_ftp['ftp'].max() * 5],
                    showgrid=False,
                    type='linear',
                    side='right',
                    anchor='x',
                    overlaying='y',
                    layer='above traces'
                ),

                margin={'l': 40, 'b': 60, 't': 0, 'r': 40},
                showlegend=False,
                autosize=True,
                bargap=.75,
            )
        })