Start Marker and End Markers on a Snail (scatter line) chart

I’m really happy how my snail charts have come along.

Any advice on how I could mark my starting point with a green circle and my end with a red square?

I’m looking into transforms and aggregation? but struggling to implement

Thanks

Extract of code below

    html.Div([
        dcc.Graph(
            id="pdf-graph-snail_2",
            config={'displayModeBar': False},
            figure={
                'data':[{
                    'x': snail_data['rolling_te'][snail_data['product_name'] == j],
                    'y': snail_data['rolling_er'][snail_data['product_name'] == j],
                    'text': snail_data['snail_chart_dates'][snail_data['product_name'] == j],  
                    'type': 'scatter',
                    'mode': 'lines', 
                    'name': j,
                    'hoverinfo': 'x+y+name+text',
                    'hoverlabel': {
                        'namelength': -1
                    },
                    'marker': {
                        'color': colour[i]
                    },
                    'line': {
                        'shape': 'spline',
                        'smoothing': 0
                    }
                } for i,j in enumerate(sorted(snail_data['product_name'].unique()))],
                'layout': generate_pdf_snail_chart_layout(title=f"{rolling_val}Yr Rolling Excess Return vs Tracking Error", y_range=snail_data['rolling_er'], x_range=snail_data['rolling_te'], percent=True)
            }
        )
    ], className="pdf-graph"),
], style={'display': 'flex', 'justifyContent': 'space-evenly', 'height': '200px'}),

layout method

def generate_pdf_snail_chart_layout(title, y_range=None, x_range=None, percent=True):
    
    y_range_max = max(abs(y_range)) * 1.1
    y_range_min = y_range_max * -1

    x_range_max = max(abs(x_range)) * 1.1
    x_range_min = x_range_max * -1

    layout = {
        'title': {
            'text': f'<b>{title}</b>',
            'font': {
                'family': 'Calibri',
                'size': 11
            }
        },
        'showlegend': False,
        'hovermode': 'closest',
        'margin': {
            "r": 10,
            "t": 14,
            "b": 20,
            "l": 30,
            "pad": 2,
        },
        'xaxis': {
            'range': [x_range_min, x_range_max],
            'showline': True,
            'showgrid': False,
            'tickformat': '%',
            'tickfont': {
                'size': 8
            }
        },
        'yaxis': {
            'range': [y_range_min, y_range_max],
            'showline': True,
            'showgrid': False,
            'tickformat': '%',
            'hoverformat': constants.SYM_PERCENT_HOVER,
            'tickfont': {
                'size': 8
            }
        }
    }

    return layout

not the most elegant of solutions, but gets the job done

    html.Div([
        dcc.Graph(
            id="pdf-graph-snail_2",
            config={'displayModeBar': False},
            figure={
                'data':[{
                    'x': snail_data['rolling_te'][snail_data['product_name'] == j],
                    'y': snail_data['rolling_er'][snail_data['product_name'] == j],
                    'text': snail_data['snail_chart_dates'][snail_data['product_name'] == j],  
                    'type': 'scatter',
                    'mode': 'lines', 
                    'name': j,
                    'hoverinfo': 'x+y+name+text',
                    'hoverlabel': {
                        'namelength': -1
                    },
                    'marker': {
                        'color': colour[i]
                    },
                    'line': {
                        'shape': 'spline',
                        'smoothing': 0
                    }
                } for i,j in enumerate(sorted(snail_data['product_name'].unique()))]
                
                +
                [{
                    'x': snail_data['rolling_te'][snail_data['product_name'] == j].tail(1),
                    'y': snail_data['rolling_er'][snail_data['product_name'] == j].tail(1),    
                    'type': 'scatter',
                    'mode': 'marker', 
                    'xaxis': 'x',
                    'yaxis': 'y',
                    'name': i,
                    'marker': {
                        'color': '#07b034',
                        'symbol': 'circle',
                        'size': 8, 
                    },
                } for i,j in enumerate(sorted(snail_data['product_name'].unique()))]     

                +
                [{
                    'x': snail_data['rolling_te'][snail_data['product_name'] == j].head(1),
                    'y': snail_data['rolling_er'][snail_data['product_name'] == j].head(1),    
                    'type': 'scatter',
                    'mode': 'marker', 
                    'xaxis': 'x',
                    'yaxis': 'y',
                    'name': i,
                    'marker': {
                        'color': '#e80918',
                        'symbol': 'square',
                        'size': 8, 
                    },
                } for i,j in enumerate(sorted(snail_data['product_name'].unique()))]
                ,
                'layout': generate_pdf_snail_chart_layout(title=f"{rolling_val}Yr Rolling Excess Return vs Tracking Error", y_range=snail_data['rolling_er'], x_range=snail_data['rolling_te'], percent=True)