Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance issue - add_vlines #4965

Open
LeRobert opened this issue Jan 14, 2025 · 0 comments
Open

Performance issue - add_vlines #4965

LeRobert opened this issue Jan 14, 2025 · 0 comments
Labels
bug something broken P2 considered for next cycle performance something is slow

Comments

@LeRobert
Copy link

LeRobert commented Jan 14, 2025

Issue: When vlines are added to a figure with subplots, the performance is much worse than without adding them.

Here is the code to reproduce the problem with 30 vlines vs. no vlines:

import numpy as np
import plotly.graph_objects as go
from dash import Dash, dcc, html
from plotly.subplots import make_subplots
import time

def generate_sample_data(n_traces=30, n_points=1000):

    x = np.linspace(0, 100, n_points)
    traces_data = []
    
    for i in range(n_traces):
        y = np.sin(x + i/10) + np.random.normal(0, 0.1, n_points)
        traces_data.append((x, y))

    vline_positions = np.random.choice(x, size=30, replace=False)
    
    return traces_data, vline_positions

def create_figure(traces_data, vline_positions=None, add_vlines=True):

    fig = make_subplots(
        rows=5, 
        cols=1,
        shared_xaxes=True,
        vertical_spacing=0.02
    )
    
    # add all traces to each subplot
    for row in range(1, 6):
        for i, (x, y) in enumerate(traces_data):
            fig.add_trace(
                go.Scatter(
                    x=x,
                    y=y,
                    name=f'Trace {i+1}',
                    mode='lines',
                    line=dict(width=1),
                    showlegend=False
                ),
                row=row,
                col=1
            )

    # add vertical lines
    if add_vlines and vline_positions is not None:
        for x_pos in vline_positions:
            for row in range(1, 6):
                fig.add_vline(
                    x=x_pos,
                    line_width=1,
                    line_dash="dash",
                    line_color="gray",
                    row=row,
                    col=1
                )
    
    fig.update_layout(
        title="Performance Test: vlines vs no vlines",
        showlegend=False,
        width=1200,
        height=1500,
        template="plotly_white",
    )
    
    # y-axis titles
    for i in range(1, 6):
        fig.update_yaxes(title_text=f"Y Axis {i}", row=i, col=1)
    
    return fig

# initialize data
traces_data, vline_positions = generate_sample_data()

# figure creation without vlines
start_time = time.time()
fig_no_vlines = create_figure(traces_data, vline_positions, add_vlines=False)
time_no_vlines = time.time() - start_time

# figure creation with vlines
start_time = time.time()
fig_with_vlines = create_figure(traces_data, vline_positions, add_vlines=True)
time_with_vlines = time.time() - start_time

app = Dash(__name__)

app.layout = html.Div([
    html.H1("Plotly vlines performance test"),
    html.Div([
        html.P(f"Time to create figure without vlines: {time_no_vlines:.4f} seconds"),
        html.P(f"Time to create figure with vlines: {time_with_vlines:.4f} seconds"),
        html.P(f"Difference: {(time_with_vlines - time_no_vlines):.4f} seconds")
    ]),
    html.H2("Figure with vlines"),
    dcc.Graph(figure=fig_with_vlines),
    html.H2("Figure without vlines"),
    dcc.Graph(figure=fig_no_vlines)
])

if __name__ == '__main__':
    app.run(debug=False)

The results of running it on my laptop are:

Plotly vlines performance test

Time to create figure without vlines: 0.5664 seconds
Time to create figure with vlines: 7.1900 seconds
Difference: 6.6235 seconds

I'm working on a simulator of trading strategies where vlines are important in the situation with subplots (to view vales of indicators easily) - there are many more traces than in this demo code with 34 vlines and the time difference is similar.

I discovered the issue using Python 3.12.8, Plotly 5.24.1 and 6.0.0rc0, running on Windows 11 64-bit.

@gvwilson gvwilson added bug something broken P2 considered for next cycle performance something is slow labels Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P2 considered for next cycle performance something is slow
Projects
None yet
Development

No branches or pull requests

2 participants