如何在Plotly(Python)中为条形子图设置统一色阶
Alright, I see exactly what's going on here—each of your 8 bar subplots is using its own local min/max for the RdBu color scale, which means the same AEP value might look different across years. Let's fix this by setting a global color range that applies to all subplots, so color mappings stay consistent.
Step-by-Step Solution
First, we need to calculate the overall minimum and maximum values from your entire AEP dataset—this will be our fixed color scale range. Then, we'll apply this range to every trace's marker settings, and optionally add a single global colorbar for clarity.
Here's the refactored, working code:
def aep_turbine_subplot_fig(years, AEP): # Calculate global min/max for unified color scale global_min = AEP.min().min() global_max = AEP.max().max() fig = make_subplots(rows=4, cols=2, subplot_titles=years) # Use a loop to add traces instead of repeating code (cleaner and less error-prone) for i in range(len(years)): row = (i // 2) + 1 # Calculate row number (0-1 → row1, 2-3→row2, etc.) col = (i % 2) + 1 # Calculate column number (even→col1, odd→col2) fig.add_trace( go.Bar( x=get_turbine_names(), y=AEP.iloc[i,:], name=years[i], marker={ 'color': AEP.iloc[i,:], 'colorscale': 'RdBu', 'cmin': global_min, # Lock color scale to global min 'cmax': global_max, # Lock color scale to global max 'coloraxis': 'coloraxis' # Tie to global color axis } ), row=row, col=col ) # Update y-axes (we can loop this too for brevity) y_axis_titles = [f'AEP [GWh] in {year.split(" ")[0]}' for year in years] for i in range(len(years)): row = (i // 2) + 1 col = (i % 2) + 1 fig.update_yaxes( title_text=y_axis_titles[i], title_font=dict(size=14), row=row, col=col, range=[0, 8.2] ) # LAYOUT with global colorbar fig.update_layout( title='AEP per turbine', xaxis_tickfont_size=14, barmode='group', bargap=0.15, bargroupgap=0.1, showlegend=False, plot_bgcolor='rgb(160,160,160)', # Add global color axis for unified colorbar coloraxis=dict( colorscale='RdBu', cmin=global_min, cmax=global_max, colorbar=dict(title='AEP [GWh]') # Label the colorbar ) ) fig.write_image(get_fig_dir() + 'AEP_perTurbine.png', width=800, height=800) fig.show(renderer='png', width=800, height=1000) return plot(fig, auto_open=True)
Key Changes Explained
- Global Min/Max Calculation:
global_min = AEP.min().min()andglobal_max = AEP.max().max()grab the smallest and largest values across all years and turbines—this ensures the color scale covers every data point in your dataset. - Unified Color Axis: By setting
marker.coloraxis='coloraxis'on each trace and defining acoloraxisin the layout, all subplots share the same color scale and a single colorbar (instead of one per subplot, which would clutter the chart). - Loop Refactoring: Replaced the 8 repeated trace and y-axis update blocks with loops—this makes the code shorter, easier to maintain, and reduces the chance of typos if you ever add/remove years later.
Now when you run this, the same AEP value will map to the exact same color across all 8 subplots, making it much easier to compare turbine performance year-over-year!
内容的提问来源于stack exchange,提问作者user10415648

