How to get proper legend on a filtered line graph

Currently we are using the following code:

import pandas as pd
import plotly.express as px
data = pd.read_json("""{
    "category": {
        "0": "A",
        "1": "A",
        "2": "A",
        "3": "A",
        "4": "A",
        "5": "A",
        "6": "A",
        "7": "A",
        "8": "A",
        "9": "A",
        "10": "A",
        "11": "A",
        "12": "B",
        "13": "B",
        "14": "B",
        "15": "B",
        "16": "B",
        "17": "B",
        "18": "B",
        "19": "B",
        "20": "B",
        "21": "B",
        "22": "B",
        "23": "B",
        "24": "B",
        "25": "B",
        "26": "B",
        "27": "B",
        "28": "B",
        "29": "B",
        "30": "B",
        "31": "B",
        "32": "B",
        "33": "B",
        "34": "B",
        "35": "B",
        "36": "B",
        "37": "B",
        "38": "B",
        "39": "B",
        "40": "B",
        "41": "B",
        "42": "C",
        "43": "C",
        "44": "C",
        "45": "C",
        "46": "C",
        "47": "C",
        "48": "C",
        "49": "C"
    },
    "year_month": {
        "0": "2020-12",
        "1": "2021-01",
        "2": "2021-05",
        "3": "2021-06",
        "4": "2021-07",
        "5": "2021-08",
        "6": "2021-09",
        "7": "2022-04",
        "8": "2022-05",
        "9": "2022-06",
        "10": "2022-10",
        "11": "2022-11",
        "12": "2019-04",
        "13": "2019-05",
        "14": "2019-06",
        "15": "2019-07",
        "16": "2019-08",
        "17": "2019-09",
        "18": "2019-10",
        "19": "2020-01",
        "20": "2020-02",
        "21": "2020-03",
        "22": "2020-04",
        "23": "2020-05",
        "24": "2020-06",
        "25": "2020-07",
        "26": "2020-08",
        "27": "2020-09",
        "28": "2020-10",
        "29": "2020-11",
        "30": "2020-12",
        "31": "2021-01",
        "32": "2021-05",
        "33": "2021-06",
        "34": "2021-09",
        "35": "2021-10",
        "36": "2021-11",
        "37": "2021-12",
        "38": "2022-03",
        "39": "2022-04",
        "40": "2022-05",
        "41": "2022-06",
        "42": "2020-01",
        "43": "2020-02",
        "44": "2020-03",
        "45": "2020-04",
        "46": "2020-05",
        "47": "2020-06",
        "48": "2020-11",
        "49": "2020-12"
    },
    "Value 1": {
        "0": 39.1645471357,
        "1": 26.8805322353,
        "2": 51.3331040861,
        "3": 53.7175704808,
        "4": 58.458014434,
        "5": 46.114137888,
        "6": 57.9084146505,
        "7": 29.3478515094,
        "8": 35.7352893676,
        "9": 33.5285704923,
        "10": 48.9354379365,
        "11": 62.6528947763,
        "12": 100.0,
        "13": 100.0,
        "14": 100.0,
        "15": 100.0,
        "16": 100.0,
        "17": 94.2214079555,
        "18": 87.7543650919,
        "19": 55.4890535514,
        "20": 38.6233644577,
        "21": 47.702023181,
        "22": 46.4278613636,
        "23": 36.5619650071,
        "24": 36.5669970317,
        "25": 36.6603512604,
        "26": 34.1843478694,
        "27": 31.503494319,
        "28": 55.6889271578,
        "29": 59.7340979669,
        "30": 53.4882647743,
        "31": 66.2118032315,
        "32": 30.968027857,
        "33": 30.9423886124,
        "34": 12.969126844,
        "35": 27.8462355659,
        "36": 42.3209344802,
        "37": 41.917267378,
        "38": 68.4563484851,
        "39": 68.6142101415,
        "40": 79.5224852136,
        "41": 80.0847893941,
        "42": 58.4485561529,
        "43": 38.2736080629,
        "44": 32.4968427957,
        "45": 55.9212386545,
        "46": 59.0719459611,
        "47": 74.7479772116,
        "48": 58.3124840023,
        "49": 45.7744534331
    },
    "Value 2": {
        "0": 3.0444678835,
        "1": 2.7176001896,
        "2": 58.739983357,
        "3": 64.4893688519,
        "4": 68.5828712178,
        "5": 65.539649273,
        "6": 62.7009393368,
        "7": 56.9349966836,
        "8": 56.883557571,
        "9": 57.8769166615,
        "10": 45.1262596589,
        "11": 53.9941401661,
        "12": 52.1703777129,
        "13": 46.7152340697,
        "14": 52.398564338,
        "15": 57.5031942676,
        "16": 55.0508184046,
        "17": 58.2219098141,
        "18": 34.3991828208,
        "19": 26.0121142265,
        "20": 20.2945415811,
        "21": 19.1567614453,
        "22": 20.5892920879,
        "23": 14.4557458223,
        "24": 12.7185208504,
        "25": 12.757753486,
        "26": 13.6386972358,
        "27": 13.8395598188,
        "28": 19.0524343632,
        "29": 21.3082605065,
        "30": 59.0457839271,
        "31": 58.1305400516,
        "32": 32.482397197,
        "33": 34.0296642085,
        "34": 15.9102895623,
        "35": 36.272101859,
        "36": 38.7719859706,
        "37": 36.3181177612,
        "38": 50.0383241509,
        "39": 51.0557819508,
        "40": 53.7143116058,
        "41": 54.9303840024,
        "42": 15.6887093873,
        "43": 23.4903311779,
        "44": 27.8625673105,
        "45": 32.2540885454,
        "46": 41.7239099403,
        "47": 38.1675062308,
        "48": 65.4704807215,
        "49": 66.7326880086
    }
}""")
fig = px.line(data, x="year_month", y=["Value 1", "Value 2"], color="category", title="Val 1 vs Val 2 plot for a Category")
fig.update_layout(
    yaxis_title="Value Comparison",
    updatemenus=[
        {
            "buttons": [
                {
                    "label": c,
                    "method": "update",
                    "args": [{ "visible": [z.name == c for z in fig.data]}],
                }
                for c in data["category"].unique().tolist()
            ]
        }
    ]
)

โ†’ For the above code the legend that we want to display is:
i) Value 1
ii) Value 2
But we are only able to use โ€˜Categoryโ€™ as a legend. If we are trying to use โ€œValue 1โ€ and โ€œValue 2โ€ as legend the code is failing.
โ†’ We want different colors for โ€˜Value 1 line plotโ€™ and โ€˜Value 2 line plotโ€™, but currently we are getting the same color.

HI @Vasu,

I do not have much experience with plotly.express. Here is a possible approach with plotly.graph_objects. It does not work 100% as expected because something gets mixed up. It seems that the axis range and/or the order of the data points still needs some tweaking. It may be a good starting point, however.

import plotly.graph_objects as go

# group in categories
gb = data.groupby('category')

# base figure
fig = go.Figure()

# add traces for each category and value
for cat in data["category"].unique().tolist():
    for val in ['Value 1', 'Value 2']:
        fig.add_scatter(x=data.year_month, y=gb.get_group(cat)[val], meta=cat, name=val, mode='markers+lines')

# create buttons
fig.update_layout(
    yaxis_title="Value Comparison",
    updatemenus=[
        {
            "buttons": [
                {
                    "label": c,
                    "method": "update",
                    "args": [{ "visible": [z.meta == c for z in fig.data]}],
                }
                for c in data["category"].unique().tolist()
            ]
        }
    ]
)
1 Like