I have a facetted bar plot using both facet_row and facet_col. I need to have annotations for the value of facet_row on each of the individual facets created.
I have tried using xref=paper, which results in all the annotations being more than slightly askew. This is also complicated by the fact that depending on the selected dataset, the number of facet_cols can change, which seems to further change the position of the annotations I apply.
I have tried looping through facet_col and facet_row values and applying annotations based on xref=xn domain, which just results in an error that I havenโt been able to find a solution for. This would be the preferred method too, because I want the labels ON the resulting facets themselves.
I have tried an additional method where I am able to get the annotations on the facets themselves with reasonably stable position, but then all the data disappears from the plots. Shown below.
import pandas as pd
import numpy as np
import plotly.express as px
# Define the date range and number of days
start_date = '2023-01-01'
end_date = '2023-01-31'
dates = pd.date_range(start=start_date, end=end_date)
# Define the metric names and markets
metric_names = ['Metric1', 'Metric2', 'Metric3', 'Metric4', 'Metric5']
markets = ['Market1', 'Market2', 'Market3', 'Market4', 'Market5']
# Create a product of dates, metric names, and markets
date_metric_market_triples = [(date, metric, market) for date in dates for metric in metric_names for market in markets]
# Create the DataFrame
df = pd.DataFrame(date_metric_market_triples, columns=['Date', 'Metric_Name', 'Market'])
# Add random metric values
df['Metric_Value'] = np.random.randint(0, 100, size=len(df))
# Group and reset the index to make plotting easier
grouped_data = df.groupby(['Date', 'Metric_Name', 'Market']).sum().reset_index()
# Creating the bar plot with Plotly Express
fig = px.bar(grouped_data, x='Date', y='Metric_Value',
facet_col='Market', facet_row='Metric_Name',
category_orders={"Metric_Name": ['Metric1', 'Metric2', 'Metric3', 'Metric4', 'Metric5'],
"Market": ['Market1', 'Market2', 'Market3', 'Market4', 'Market5']},
title='Sum of Metric Values by Date, Metric, and Market')
# Adjust layout for better visibility
fig.update_layout(
height=1200, # Increase figure height for better visibility
width=1600 # Increase figure width to accommodate more facets
)
# Adding annotations for MetricName in each facet without overwriting plot data
for i, metric_name in enumerate(metric_names):
for j, market in enumerate(markets):
fig.add_annotation(
dict(
x=0.5, # Position of the annotation at the middle of the x-axis
y=1.05, # Position slightly above the top of the y-axis within each subplot
text=metric_name, # Text to display (Metric Name)
xref=f"x{len(markets) * i + j + 1}", # Correct axis reference for x-axis
yref=f"y{len(markets) * i + j + 1}", # Correct axis reference for y-axis
showarrow=False,
font=dict(size=10, color="black"),
xanchor='center', # Center align text
yanchor='bottom' # Bottom align text relative to the specified y coordinate
)
)
# Show the figure
fig.show()
Can someone please provide some assistance?
Thanks,
Matt