Search code examples
pythonplotlyplotly-pythonplotly-express

Not displaying Nan values on markers


I apologize if this is a possible duplicate. Here is my data:

import pandas as pd

data = [
    {'Year': 2015, 'major': None, 'minor': 57.0, 'patch': None},
    {'Year': 2016, 'major': 129.0, 'minor': 107.0, 'patch': 437.0},
    {'Year': 2017, 'major': 109.0, 'minor': 266.0, 'patch': 2622.0},
    {'Year': 2018, 'major': 61.0, 'minor': 3213.0, 'patch': 2989.0},
    {'Year': 2019, 'major': 2906.0, 'minor': 9780.0, 'patch': 16531.0},
    {'Year': 2020, 'major': 421.0, 'minor': 8447.0, 'patch': 9402.0},
    {'Year': 2021, 'major': 1156.0, 'minor': 13102.0, 'patch': 10323.0},
    {'Year': 2022, 'major': 246.0, 'minor': 8770.0, 'patch': 24588.0}
]

df2 = pd.DataFrame(data)

I am trying to plot the count for all the three releases, but for some reason the nan keeps showing up, that too only for major. Is there a way I could fix this? here is my code:

fig = go.Figure()
fig.add_trace(go.Scatter(x=df2['Year'], y=df2['major'], name='Major', mode='lines+markers', marker=dict(color='brown', size=10), line=dict(color='brown', width=1)))
fig.add_trace(go.Scatter(x=df2['Year'], y=df2['minor'], name='Minor', mode='lines+markers', marker=dict(color='orange', size=10), line=dict(color='orange', width=1)))
fig.add_trace(go.Scatter(x=df2['Year'], y=df2['patch'], name='Patch', mode='lines+markers', marker=dict(color='blue', size=10), line=dict(color='blue', width=1)))

for row in df2.itertuples():
    fig.add_annotation(x=row.Year, y=row.major, text=str(row.major), showarrow=False, arrowhead=1, yshift=10)
    fig.add_annotation(x=row.Year, y=row.minor, text=str(row.minor), showarrow=False, arrowhead=1, yshift=20)
    fig.add_annotation(x=row.Year, y=row.patch, text=str(row.patch), showarrow=False, arrowhead=1, yshift=10)



fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True)
fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True)
fig.update_layout(width=1500, height=900,legend_title_text='Type of Change',template='ggplot2', title = 'Evolution of Breaking Changes over all Releases', xaxis_title = 'Year', yaxis_title = 'Number of Breaking Changes')
fig.update_traces(mode='lines+markers')

fig.show()

enter image description here As you can see the annotations in year 2015 being present for major, but not for patch, I am not sure as to why this is happening. Any help would be greatly appreciated.


Solution

  • I think this is happening because plotly doesn't process text for annotations the same way as for traces. Plotly traces are "smarter" in the sense that they often will drop NaN values from displaying for many of the chart types.

    This is a case where I think creating scatter traces with mode='lines+markers+text' and passing the y values as the text would simplify your problem and avoid having to use annotations at all. go.Scatter will handle NaN by dropping the marker as well as the text.

    For example:

    import pandas as pd
    import plotly.graph_objects as go
    
    data = [
        {'Year': 2015, 'major': None, 'minor': 57.0, 'patch': None},
        {'Year': 2016, 'major': 129.0, 'minor': 107.0, 'patch': 437.0},
        {'Year': 2017, 'major': 109.0, 'minor': 266.0, 'patch': 2622.0},
        {'Year': 2018, 'major': 61.0, 'minor': 3213.0, 'patch': 2989.0},
        {'Year': 2019, 'major': 2906.0, 'minor': 9780.0, 'patch': 16531.0},
        {'Year': 2020, 'major': 421.0, 'minor': 8447.0, 'patch': 9402.0},
        {'Year': 2021, 'major': 1156.0, 'minor': 13102.0, 'patch': 10323.0},
        {'Year': 2022, 'major': 246.0, 'minor': 8770.0, 'patch': 24588.0}
    ]
    
    df2 = pd.DataFrame(data)
    
    fig = go.Figure()
    
    fig.add_trace(go.Scatter(
        x=df2['Year'], y=df2['major'], 
        text=df2['major'], textposition="top center",
        name='Major', mode='lines+markers+text', 
        marker=dict(color='brown', size=10), line=dict(color='brown', width=1)
    ))
    fig.add_trace(go.Scatter(
        x=df2['Year'], y=df2['minor'], 
        text=df2['minor'], textposition="top center",
        name='Minor', mode='lines+markers+text', 
        marker=dict(color='orange', size=10), line=dict(color='orange', width=1)
    ))
    fig.add_trace(go.Scatter(
        x=df2['Year'], y=df2['patch'], 
        text=df2['patch'], textposition="top center",
        name='Patch', mode='lines+markers+text', 
        marker=dict(color='blue', size=10), line=dict(color='blue', width=1)
    ))
    
    fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True)
    fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True)
    fig.update_layout(width=1500, height=900,legend_title_text='Type of Change',template='ggplot2', title = 'Evolution of Breaking Changes over all Releases', xaxis_title = 'Year', yaxis_title = 'Number of Breaking Changes')
    fig.update_traces(mode='lines+markers+text')
    
    fig.show()
    

    enter image description here