Search code examples
plotlyplotly-express

How to plot multiple lines on same graph using plotly express (XYXY format data)?


I have an excel file with multiple columns data in XYXY format Data.png. How can I use plotly express to plot multiple lines on same graph? For your reference, I achieved this using the Origin software.Result.png

Comments: (1) different lines with different colors (2) set the name of each column Y as the name of each line (3) both x and y axis have Slider Control to adjust the data range

Thank you so much for your help!


Solution

    • start by generating a dataframe of same structure as your sample data
    • your plot is really multiple sets of X/Y arrays across columns. restructure for all sets of X/Y arrays to be rows, with a column that defines the set (name)
    • then it's a very simple basic use case of Plotly Express
    • have also provided another way in pandas using wide_to_long() to structure dataframe for plotly
    import pandas as pd
    import numpy as np
    import plotly.express as px
    
    # generte smaple data in required structure
    ROWS = 20
    COLS = 5
    df = pd.DataFrame(
        {
            f"{c}{n+1}": a if c == "X" else np.power(a, np.linspace(3, 8, ROWS))
            for n, a in enumerate(np.sort(np.random.uniform(1, 2, (COLS, ROWS))))
            for c in "XY"
        }
    )
    
    # generate line chart.  key is restructuring dataframe to be long with a column that defines name/color
    px.line(
        pd.concat(
            [
                df.loc[:, [f"{c}{n}" for c in "XY"]]
                .pipe(lambda d: d.rename(columns={c: c[0] for c in d.columns}))
                .assign(name=chr(ord("A") + n * 2 - 1))
                for n in range(1, (len(df.columns) // 2) + 1)
            ]
        ),
        x="X",
        y="Y",
        color="name",
    ).update_layout(margin={"r":800})
    

    sample data

    X1 Y1 X2 Y2 X3 Y3 X4 Y4 X5 Y5
    1.05655 1.17941 1.00106 1.00317 1.08131 1.26432 1.02673 1.08236 1.13674 1.46889
    1.12829 1.48273 1.12435 1.4659 1.17564 1.69557 1.05341 1.18507 1.17995 1.71595
    1.23403 2.09918 1.1806 1.79582 1.18304 1.8089 1.11287 1.45807 1.20479 1.92892
    1.25683 2.37794 1.25303 2.35086 1.25923 2.39525 1.11929 1.53275 1.20527 2.02893
    1.26899 2.62586 1.26441 2.58766 1.30377 2.93 1.12895 1.63484 1.31977 3.07846
    1.28209 2.92254 1.28889 2.98997 1.34024 3.53909 1.24893 2.60999 1.33975 3.53352
    1.35852 4.06724 1.37546 4.30467 1.35213 3.9804 1.27209 3.01014 1.35568 4.02851
    1.40013 5.10234 1.45365 6.11857 1.36741 4.55027 1.27662 3.26259 1.35574 4.36531
    1.45668 6.82368 1.48403 7.5034 1.43853 6.40061 1.37053 4.99873 1.36458 4.88892
    1.53722 10.0571 1.50537 8.98814 1.58023 11.6633 1.39912 6.0676 1.38998 5.85774
    1.54932 11.7704 1.5474 11.6885 1.65089 16.8308 1.4697 8.74519 1.44385 7.91331
    1.55716 13.6067 1.5512 13.3024 1.70078 22.8881 1.52104 11.8486 1.46135 9.358
    1.61261 18.9648 1.62567 19.9306 1.71918 28.1241 1.54101 14.3378 1.50292 12.29
    1.65226 25.1355 1.70023 30.207 1.78133 40.7424 1.55464 17.0006 1.61183 21.4393
    1.68557 32.7817 1.72353 38.0429 1.78985 48.9649 1.58977 22.1695 1.67353 31.2474
    1.80329 60.1153 1.76449 51.6846 1.79787 58.8716 1.61254 27.6471 1.68959 38.2362
    1.88719 97.4484 1.88748 97.5572 1.83715 80.2828 1.76924 61.1892 1.78649 65.6223
    1.9383 140.635 1.90963 125.812 1.87891 111.451 1.77838 73.8938 1.826 90.0264
    1.96985 189.662 1.92214 156.894 1.87996 132.145 1.8462 114.857 1.8351 109.622
    1.99305 248.972 1.94302 203.147 1.88243 157.67 1.87284 151.36 1.95582 214.111

    plot

    enter image description here

    wide_to_long()

    px.line(
        pd.wide_to_long(df.reset_index(), stubnames=["X", "Y"], i="index", j="name")
        .reset_index()
        .assign(name=lambda d: d["name"].apply(lambda n: chr(ord("A") + n * 2 - 1))),
        x="X",
        y="Y",
        color="name",
    ).update_layout(margin={"r": 800})