Dynamic tennis points by points graph

Hello,

I am developing the application in Python Dash for tennis statistics and point by point graph. Currently I have issue with the dynamic plotly graph which should show score, all played points, information about each played points and time of play for each point. I already did this via python PIL which generate static picture but I want show this in the dynamic graph in python Dash (Plotly Graph).

There is verticial line which split the graph into 2 parts (left side for home player points, right side for away player points) all points should be showed like dot or small circle and all played points in one game should be connected together via line. On the right side should be showed the score and next to it the points detail and the time of play for each point.

Who has some expirences in dynamic Python Ploty graphs do you think it is possible to show all these informations via dynamic Plotly Graph?

Thank you and Best Regards


My current code in Plotly:

def create_points_graph(stat_events):
    fig = go.Figure()
    # Get the first game of the first set
    first_set = stat_events.get(1, {})
    first_game = first_set.get('games', [{}])[0] if first_set else {}

    points = first_game.get('list', [])
    details = first_game.get('details', [])

    # Define colors for home and away
    home_color = 'blue'
    away_color = 'red'

    # Add vertical line in the middle
    fig.add_shape(type="line",
                  x0=0, y0=0, x1=0, y1=1,
                  line=dict(color="Black", width=2))

    # Calculate the small gap at the top and the constant difference between lines
    top_gap = 0.05  # 5% of the height as a gap
    line_gap = 20 / 800  # 20px gap in the 800px height

    # Add horizontal lines and points
    for i in range(len(points)):
        y = 1 - top_gap - i * line_gap  # Start after top gap, then constant 20px difference
        
        # Add horizontal line
        fig.add_shape(
            type="line",
            x0=-0.5, y0=y, x1=0.5, y1=y,
            line=dict(color="Gray", width=1)
        )

        # Add point
        if points[i] == 'home':
            fig.add_trace(go.Scatter(
                x=[-0.3],  # 30px from center on left side
                y=[y],
                mode='markers',
                marker=dict(size=15, color=home_color),
                showlegend=False
            ))
        else:
            fig.add_trace(go.Scatter(
                x=[0.3],  # 30px from center on right side
                y=[y],
                mode='markers',
                marker=dict(size=15, color=away_color),
                showlegend=False
            ))

        # Add point description
        if i < len(details):
            fig.add_annotation(
                x=0,
                y=y,
                text=details[i]['Point'],
                showarrow=False,
                font=dict(size=12),
                xanchor='center',
                yanchor='middle'
            )

    fig.update_layout(
        width=250,
        height=800,
        xaxis=dict(
            range=[-0.5, 0.5],
            showticklabels=False,
            showgrid=False,
            zeroline=False,
        ),
        yaxis=dict(
            range=[0, 1],
            showticklabels=False,
            showgrid=False,
            zeroline=False,
        ),
        margin=dict(l=10, r=10, t=10, b=10),
        plot_bgcolor='white',
    )

    return fig

List with all Informations for first game for example:

{‘list’: [‘home’, ‘home’, ‘away’, ‘away’, ‘home’, ‘home’], ‘time’: [1700676756, 1700676780, 1700676804, 1700676851, 1700676893, 1700676936], ‘pointtypes’: [‘0’, ‘0’, ‘0’, ‘2’, ‘0’, ‘0’], ‘details’: [{‘Point’: ‘15:0’, ‘Description’: ‘’, ‘Elapsed’: 12}, {‘Point’: ‘30:0’, ‘Description’: ‘’, ‘Elapsed’: 24}, {‘Point’: ‘30:15’, ‘Description’: ‘’, ‘Elapsed’: 24}, {‘Point’: ‘’, ‘Description’: ‘First serve fault’, ‘Elapsed’: 25}, {‘Point’: ‘30:30’, ‘Description’: ‘’, ‘Elapsed’: 22}, {‘Point’: ‘40:30’, ‘Description’: ‘Game point’, ‘Elapsed’: 42}, {‘Point’: ‘’, ‘Description’: ‘First serve fault’, ‘Elapsed’: 27}, {‘Point’: ‘0:0’, ‘Description’: ‘Game’, ‘Elapsed’: 16}], ‘break’: False, ‘server’: ‘home’, ‘game_score’: {‘home’: 1, ‘away’: 0}}