添加标注时数据消失问题求助(Plotly分面柱状图)
Plotly分面柱状图添加子图标注问题
问题场景
- 使用Plotly绘制同时设置
facet_row和facet_col的分面柱状图,需要为每个子图添加对应facet_row的标注 - 尝试
xref=paper时,标注位置偏差明显;且facet_col数量随数据集动态变化,进一步加剧位置偏移问题 - 希望通过遍历
facet_col和facet_row值,基于子图轴域(xref=xn)添加标注(标注位于子图上方),但该方法报错 - 尝试某方法后标注位置稳定,但图表所有数据消失,相关代码如下:
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()
解决方案
问题核心是标注的坐标参考系错误:原代码中xref="xN"指向的是子图的数据轴,使用x=0.5会被解析为数据值0.5而非子图的相对位置,导致标注偏离预期甚至干扰图表渲染。
只需将xref和yref修改为子图轴的domain域(坐标范围0-1,对应子图的整体宽高),即可稳定在每个子图上方添加标注:
# 替换原标注循环代码 for i, metric_name in enumerate(metric_names): for j, market in enumerate(markets): # 计算子图轴索引:行优先,从1开始 subplot_idx = i * len(markets) + j + 1 fig.add_annotation( x=0.5, # 子图水平居中位置 y=1.05, # 子图顶部上方5%位置 text=metric_name, # 使用子图的domain作为坐标参考 xref=f"x{subplot_idx} domain", yref=f"y{subplot_idx} domain", showarrow=False, font=dict(size=10, color="black"), xanchor='center', yanchor='bottom' )
修改后,标注会准确显示在对应子图的顶部居中位置,同时不会影响原有图表数据的渲染,且适配facet_col数量动态变化的场景。
内容的提问来源于stack exchange,提问作者Matt G
相关产品推荐
相关产品推荐

