I am trying to add upper
and lower
limits red dashed horizontal lines
to each facet Line plot based on respective column values but dashed lines are not formed at correct yaxis values of the facets.
I have tried below code and made several attempts but it is not creating the right yaxis dashed lines for the facets
and gives a wrong chart output.
Code I have tried:
dataframe
import polars as pl
import datetime
import plotly.express as px
df_stack = pl.DataFrame({'Category': ['CATG1', 'CATG1', 'CATG1', 'CATG2', 'CATG2', 'CATG2', 'CATG3', 'CATG3', 'CATG3', 'CATG4', 'CATG4', 'CATG4', 'CATG5', 'CATG5', 'CATG5', 'CATG6', 'CATG6', 'CATG6', 'CATG7', 'CATG7'],
'Value': [39.7, 29.0, 32.7, 19.0, 14.0, 15.0, 1.28, 1.2, 1.14, 5.6, 6.9, 4.9, 31.02, 24.17, 28.68, 14.49, 11.29, 13.4, 3.81, 3.5],
'Lower Range': [12.0, 12.0, 12.0, 6.0, 6.0, 6.0, 0.9, 0.9, 0.9, 3.5, 3.5, 3.5, 23.0, 23.0, 23.0, 5.5, 5.5, 5.5, 2.5, 2.5],
'Upper Range': [43.0, 43.0, 43.0, 21.0, 21.0, 21.0, 1.3, 1.3, 1.3, 7.2, 7.2, 7.2, 33.0, 33.0, 33.0, 19.2, 19.2, 19.2, 4.5, 4.5],
'Date': [datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9),
datetime.date(2023, 5, 15),
datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9),
datetime.date(2023, 5, 15),
datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9),
datetime.date(2023, 5, 15),
datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9),
datetime.date(2023, 5, 15),
datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9),
datetime.date(2023, 5, 15),
datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9),
datetime.date(2023, 5, 15),
datetime.date(2022, 4, 1),
datetime.date(2022, 9, 9)],
'Color_flag': ['Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal', 'Normal']}
)
Plot Code
# creating line plot
fig_facet_catg_31 = px.line(df_stack.to_pandas(), x='Date', y='Value', facet_row="Category",
facet_col_wrap=2,facet_row_spacing=0.035)
# creating scatter plot
fig_facet_catg_3 = (px.scatter(df_stack.to_pandas(),
x='Date', y='Value', color = 'Color_flag',
color_discrete_sequence=["red", "green"], facet_row="Category"
, facet_row_spacing=0.035 )
.add_traces(fig_facet_catg_31.data)
.update_yaxes(matches=None,showticklabels=True)
.update_layout(height=600)
.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
)
# Getting unique values of each category & converting it into a list
category_list = df_stack.sort('Category').get_column('Category').unique(maintain_order=True).to_list()
# Looping with index & value of category list
for i,elem in enumerate(category_list):
print(i,elem)
# filter for each category 1 by 1 in loop
data = df_stack.filter(pl.col('Category')==elem)
# Extract Upper & lower range values for respective category
upper = data.item(0,"Upper Range")
lower = data.item(0,"Lower Range")
print(lower,upper)
# Adding h_line() to each facet based on row index & range values inside loop.
fig_facet_catg_3 = (fig_facet_catg_3.add_hline(y=upper, row=i, line_dash="dash", line_color = 'red')
.add_hline(y=lower, row=i, line_dash="dash", line_color = 'red'))
fig_facet_catg_3
Output Incorrect Plot as each facet is not aligned to its upper lower limits:
Desired output: Ideally the lines should be within the dashed
marking red lines but dashed lines are not using the correct y values.
Annotations for facet plots are created from left to right, and bottom to top (as explained in my answer here). In your case, since there's only one row, then your annotations are created bottom to top, so you need to index by n-i
where n is the number of categories.
# Looping with index & value of category list
# annotations for facet plots are created left to right
n_categories = len(category_list)
for i,elem in enumerate(category_list):
print(i,elem)
# filter for each category 1 by 1 in loop
data = df_stack.filter(pl.col('Category')==elem)
# Extract Upper & lower range values for respective category
upper = data.item(0,"Upper Range")
lower = data.item(0,"Lower Range")
print(lower,upper)
# Adding h_line() to each facet based on row index & range values inside loop.
fig_facet_catg_3 = (fig_facet_catg_3.add_hline(y=upper, row=n_categories-i, line_dash="dash", line_color = 'red')
.add_hline(y=lower, row=n_categories-i, line_dash="dash", line_color = 'red'))