You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly甘特图同一子图添加多轨迹导致条形尺寸异常的解决方法咨询

Fixing Bar Height & Text Display Issues in Plotly Subplot Gantt Charts with Multiple Colors

I’ve run into exactly this issue before—when combining multiple color-coded traces from px.timeline into a single subplot, Plotly’s default grouping behavior messes up bar heights and pushes text out of view. Let’s break down why this happens and how to fix it.

Why This Happens

When you generate a timeline with multiple colors (using the color parameter), px.timeline creates a separate trace for each color. Each trace treats your ProdName values as distinct y-axis categories by default. When you add these traces to the same subplot, Plotly stacks or spaces them out instead of aligning them under the same product category, which distorts bar heights and breaks text display.

The Fix: Manual Y-Coordinate Alignment

We need to force all traces to use the same y-axis positions for matching ProdName values, and set a consistent bar height. Here’s your modified code with these changes:

Modified Code

def create_plot(self, date_start, date_end):
    df = self.filtered_df
    customers = df['Customer'].unique()
    pixel = 35
    customer_plots = dict()
    heights = []

    for customer in customers:
        customer_df = df.loc[df['Customer'] == customer]
        # Create a fixed order and numeric mapping for ProdName values
        prod_order = customer_df['ProdName'].unique()
        prod_to_y = {prod: idx for idx, prod in enumerate(prod_order)}
        total_products = len(prod_order)
        
        # Generate the timeline as before
        fig = px.timeline(
            customer_df, 
            x_start='StartDate', 
            y='ProdName', 
            x_end='DueDate', 
            text='DocNum', 
            color='Estat'
        )
        fig.update_traces(textposition="inside")
        
        # Standardize y-values and bar height across all traces
        for trace in fig['data']:
            # Replace string ProdName values with our fixed numeric y-coordinates
            trace['y'] = [prod_to_y[prod] for prod in trace['y']]
            # Set a consistent bar height (adjust this value to your preference)
            trace['width'] = 0.8
        
        customer_plots[customer] = fig
        heights.append(5 + total_products * pixel)

    # Build subplots as before
    fig_sub = make_subplots(
        rows=len(customer_plots), 
        row_heights=heights, 
        subplot_titles=list(customer_plots.keys())
    )
    fig_sub.update_xaxes(type='date')

    for i, (customer, plot) in enumerate(customer_plots.items()):
        # Recreate the ProdName mapping for this customer
        prod_order = df.loc[df['Customer'] == customer]['ProdName'].unique()
        prod_to_y = {prod: idx for idx, prod in enumerate(prod_order)}
        
        for trace in plot['data']:
            fig_sub.add_trace(trace, row=i+1, col=1)
        
        # Customize y-axis to show ProdName labels instead of numbers
        fig_sub.update_yaxes(
            tickmode='array',
            tickvals=list(prod_to_y.values()),
            ticktext=list(prod_to_y.keys()),
            row=i+1, col=1
        )

    # Final layout adjustments
    fig_sub.update_layout(
        autosize=False,
        height=sum(heights),
        width=1500
    )

    for ax in fig_sub['layout']:
        if ax[:5] == 'xaxis':
            fig_sub['layout'][ax]['range'] = [date_start, date_end]
            fig_sub['layout'][ax]['dtick'] = 86400000.0 * 7

    self.plot = fig_sub

Key Changes Explained

  • Fixed Y-Coordinate Mapping: We create a numeric mapping for each customer’s ProdName values. This ensures that every trace uses the same y-position for the same product, so bars align correctly instead of being spaced out.
  • Consistent Bar Height: Setting trace['width'] (since it’s a horizontal bar, width controls vertical height) ensures all bars have the same size, so text fits inside as expected. Tweak the 0.8 value if you need taller/shorter bars.
  • Custom Y-Axis Labels: We manually map the numeric y-values back to the original ProdName strings, so the subplot axes remain readable.

Quick Tweaks to Try

  • If text still doesn’t fit, adjust the pixel value used to calculate row heights (increase it slightly to give more vertical space).
  • Play with the trace['width'] value—values between 0.7 and 0.9 usually work best for most cases.

内容的提问来源于stack exchange,提问作者Ferran Capallera Guirado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:57:41