Matplotlib多柱状图合并需求:同图展示并旋转x轴标签
Solution: Combine Three Histograms into One Plot with Rotated X-Labels
Got it, let's fix this up for you! The main issue with your original code is that it creates a new figure for each distribution—we'll adjust it to plot all three datasets on the same axes, space the bars so they don't overlap, and rotate those x-axis labels to avoid clutter. Here's the step-by-step solution:
Key Changes Made:
- Single Axes for All Plots: We'll create one axes object upfront and plot all three distributions on it instead of generating separate figures.
- Offset Bars: Shift each group of bars left, center, or right to prevent overlap.
- Legend: Add a legend to distinguish between the three intensity distributions.
- Rotated X-Labels: Set x-axis labels to rotate 90 degrees for readability.
- Layout Fix: Use
tight_layout()to ensure labels and titles aren't cut off.
Modified Full Code:
import matplotlib.pyplot as plt plt.rcParams['figure.figsize'] = (13,6) # Define your distribution data distribution_1 = {221: 0.360416255051639, 238: 0.19880422092501124, 204: 0.08321239335428827, 187: 0.05222900763358779, 170: 0.048701841041760216, 153: 0.04666771441400988, 136: 0.04238796587337225, 119: 0.03527929950606197, 255: 0.008626852267624607, 102: 0.029128423888639426, 85: 0.025297709923664122, 68: 0.025161652447238437, 51: 0.02414683430624158, 34: 0.015194881005837449, 17: 0.004271216883700045, 0: 0.00047373147732375395} distribution_2 = {221: 0.4157265379434216, 238: 0.19262191288729233, 204: 0.07130848675348002, 187: 0.04102649303996408, 170: 0.041006286484059275, 153: 0.04099775482712169, 136: 0.03805253704535249, 119: 0.03213920071845532, 102: 0.0272240682532555, 255: 0.007630893578805568, 85: 0.024198473282442748, 68: 0.024454422990570275, 51: 0.023817691962281097, 34: 0.015106870229007634, 17: 0.004220925011225864, 0: 0.00046744499326448137} distribution_3 = {255: 0.4824301751234845, 221: 0.0699272563987427, 187: 0.06918679838347552, 170: 0.050990121239335426, 153: 0.04777503367759318, 238: 0.024907049842837897, 136: 0.04586124831612034, 119: 0.041772339470139204, 102: 0.034856757970363715, 85: 0.022533453075886844, 68: 0.03175348001796138, 51: 0.025796587337224966, 34: 0.02501930848675348, 17: 0.015535698248765155, 0: 0.008881903906600808, 204: 0.002772788504714863} def generate_histogram(ax, distribucion, label, width=4): values = list(distribucion.values()) intensities = list(distribucion.keys()) # Calculate offset positions for each distribution's bars x_positions = [x - width for x in intensities] if label == "Distribution 1" else \ [x for x in intensities] if label == "Distribution 2" else \ [x + width for x in intensities] # Plot bars with unique label for legend histogram = ax.bar(x_positions, values, width=width, label=label) # Add value labels above bars (retaining your original logic) def autolabel(rects): for rect in rects: height = round(float(rect.get_height()), 4) ax.annotate(f'{height}', xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), # 3 points vertical offset textcoords="offset points", ha='center', va='bottom', fontsize=10) autolabel(histogram) # Create a single figure and axes for all plots fig, ax = plt.subplots() # Plot all three distributions on the same axes generate_histogram(ax, distribution_1, "Distribution 1") generate_histogram(ax, distribution_2, "Distribution 2") generate_histogram(ax, distribution_3, "Distribution 3") # Configure plot labels and scale ax.set_title('Intensity Distribution Comparison') ax.set_xlabel('Intensity (0 to 255)') ax.set_ylabel('Probability') ax.set_ylim(0, 0.55) # Rotate x-axis labels 90 degrees to avoid overlap ax.tick_params(axis='x', rotation=90) # Add legend to identify each distribution ax.legend() # Adjust layout to prevent label cutoff plt.tight_layout() # Display the combined plot plt.show()
Quick Breakdown of Critical Adjustments:
- Shared Axes: We create one
fig, axpair upfront and pass it to thegenerate_histogramfunction, ensuring all data plots on the same chart. - Bar Spacing: Each distribution's bars are shifted by a small width value to sit side-by-side without overlapping.
- Rotated Labels:
ax.tick_params(axis='x', rotation=90)rotates x-labels 90 degrees, eliminating overlap while keeping intensity values readable. - Legend & Layout: The legend helps distinguish datasets, and
tight_layout()ensures no text gets cut off at the edges of the plot.
内容的提问来源于stack exchange,提问作者Mattii
相关产品推荐
相关产品推荐

