pythonpython-3.xplotlyplotly-python

Using plotly, how to hide specific color code?


I'm plotting a bunch of different systems but I will group them together into only 2 or 3 different colors. So with the example below, after plotting I want to also be able to hide or show the systems based on their color and not only their names. Is that possible? So in addition to clicking "System 4" and hide that one, is it possible to click one button and hide all blue?

enter image description here

import plotly.express as px
import pandas as pd
import numpy as np

# Data
data = {
    "System": ["System 1", "System 1", "System 1", "System 2", "System 2", "System 3", "System 3", "System 3", "System 4", "System 4"],
    "Year": [2020, 2020, 2020, 2021, 2020, 2020, 2020, 2021, 2019, 2021]
}

# Convert to DataFrame
df = pd.DataFrame(data)

# Define color mapping for systems
color_map = {
    "System 1": '#1f77b4',
    "System 2": '#1f77b4',
    "System 3": '#ff7f0e',
    "System 4": '#ff7f0e'
}

max_n = 2022
min_n = 2016
bins = 7
step = (max_n - min_n) / bins

arr_div = np.arange(min_n + step / 2, max_n + step / 2, step=step)
arr_div_r = np.round(arr_div, 0).astype(int)

# Define order of legend
legend_order = ["System 1", "System 2", "System 3", "System 4"]

# Create histogram with Plotly Express and specify custom color sequence
fig = px.histogram(df, x="Year", color="System", category_orders={"System": legend_order}, nbins=bins, barmode='stack', color_discrete_map=color_map)

# Add black border to each bar
fig.update_traces(marker_line_color='black', marker_line_width=2)

# Update layout
fig.update_layout(
    title='Histogram',
    xaxis_title='Year',
    yaxis_title='Amount',
    xaxis=dict(
        tickmode='array',
        tickvals=np.arange(min_n, max_n+1, 1)
    )
)

# Move x-axis tick labels outside the plot area
fig.update_xaxes(ticklabelposition='outside bottom')

# Show plot
fig.show()

Solution

  • You could add this right at the bottom, right before fig.show():

    for trace in fig.data:
        trace['legendgroup'] = trace['marker']['color']