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

如何在Matplotlib中制作双向对比条形图并解决绘制问题?

How to Create a Proper Two-Way Bar Chart in Matplotlib (With Correct Proportions & Bidirectional Bars)

Hey there! I’ve run into this exact issue before—getting those bars to face opposite directions and keep their relative lengths proportional can feel tricky at first, but once you know the core trick, it’s totally straightforward. Let’s break it down step by step.

Core Idea Behind Bidirectional Bars

The secret to left/right-facing bars is simple: make one dataset negative. Matplotlib plots negative values to the left of the y-axis and positive values to the right. We just tweak the x-axis labels afterward to show positive numbers for both sides, so the final chart looks clean and intuitive.

Step-by-Step Implementation

Let’s use a concrete example—say we’re comparing male and female preferences across 5 categories:

import matplotlib.pyplot as plt

# Sample dataset
categories = ["Sports", "Reading", "Gaming", "Cooking", "Hiking"]
male_responses = [25, 15, 30, 10, 20]
female_responses = [20, 25, 15, 30, 18]

# Set up figure and axis
fig, ax = plt.subplots(figsize=(8, 5))

# Define bar width to avoid overlap
bar_width = 0.35

# Position of y-axis ticks
y_positions = range(len(categories))

# Plot right-facing bars (male data, positive values)
ax.barh(y_positions, male_responses, height=bar_width, label="Male", color="#1f77b4")

# Plot left-facing bars (female data, converted to negatives)
ax.barh(y_positions, [-val for val in female_responses], height=bar_width, label="Female", color="#ff7f0e")

# --- Fixing Proportional Lengths ---
# Find the maximum value across both datasets to set symmetric x-axis limits
max_response = max(max(male_responses), max(female_responses))
ax.set_xlim(-max_response - 2, max_response + 2)  # Add small padding for readability

# --- Clean Up X-Axis Labels ---
# Replace negative tick labels with positive numbers
ax.set_xticks([-max_response, -max_response//2, 0, max_response//2, max_response])
ax.set_xticklabels([max_response, max_response//2, 0, max_response//2, max_response])

# --- Final Polishing ---
# Set axis labels and title
ax.set_yticks(y_positions)
ax.set_yticklabels(categories)
ax.set_xlabel("Number of Respondents")
ax.set_title("Preference Comparison by Gender")

# Add legend and adjust layout to prevent clipping
ax.legend()
plt.tight_layout()

plt.show()

Key Explanations:

  • Bidirectional Bars: Converting female_responses to negatives ([-val for val in female_responses]) forces those bars to extend leftward, while positive male values stay right-facing.
  • Proportional Lengths: Setting xlim to a symmetric range (-max_response to max_response) ensures a value of 20 on the left takes up exactly the same horizontal space as 20 on the right—no stretched or squashed bars.
  • Intuitive Labeling: Overwriting x-tick labels turns negative numbers back to positive, so readers don’t get confused by the underlying negative values we used for plotting.

Bonus Tips:

  • If your datasets have wildly different ranges, normalize both to a shared scale (e.g., 0-100 for percentages) to keep proportions consistent.
  • Adjust bar_width (try 0.2-0.4) to fine-tune spacing between bars.
  • Remove unnecessary borders with ax.spines['right'].set_visible(False) and ax.spines['top'].set_visible(False) for a cleaner look.

This method should give you a perfectly aligned, proportional two-way bar chart just like the one you’re aiming for!

内容的提问来源于stack exchange,提问作者brown_mamba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:03:42