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

如何设置非等间距yticks?解决类别不平衡可视化难题

Hey there! Let's tackle this problem step by step—sounds like you've got an imbalanced dataset where one group's values are way smaller than the other, making it impossible to visualize both clearly on a standard linear axis. Switching to a logarithmic y-axis is exactly the right call here, and we can easily customize the ticks to match that 1, 10, 100, 1000,... pattern you want.

Solution: Custom Logarithmic Y-Axis for Imbalanced Data

I'll use Matplotlib (the most common Python plotting library) to walk you through this, with optional notes for Seaborn users too.

Step 1: Import Required Tools

First, grab the libraries we'll need:

import matplotlib.pyplot as plt
import numpy as np

Step 2: Mimic Your Imbalanced Data

Let's create sample data that matches your scenario (Group 0 has large values, Group 1 has tiny ones):

# Example imbalanced groups
group_0 = [600, 1400, 950, 2200, 1600]
group_1 = [3, 6, 4, 9, 5]
x_positions = np.arange(len(group_0))  # X-axis positions for each sample
bar_width = 0.35  # Width for grouped bars

Step 3: Build the Plot with Custom Log Ticks

Here's the core code to fix your visualization:

# Create figure and axis
fig, ax = plt.subplots()

# Plot the two groups as bars
ax.bar(x_positions - bar_width/2, group_0, bar_width, label='Group 0')
ax.bar(x_positions + bar_width/2, group_1, bar_width, label='Group 1')

# Switch y-axis to logarithmic scale
ax.set_yscale('log')

# Generate your desired tick pattern: 1, 10, 100, 1000,...
max_value = max(max(group_0), max(group_1))
# Calculate how many powers of 10 we need to cover the data
power_count = int(np.log10(max_value)) + 2
y_ticks = [10**i for i in range(0, power_count)]
ax.set_yticks(y_ticks)

# Optional: Format ticks as plain integers (no scientific notation like 1e3)
ax.get_yaxis().set_major_formatter(plt.ScalarFormatter())
ax.get_yaxis().set_minor_formatter(plt.ScalarFormatter())
plt.ticklabel_format(axis='y', style='plain')

# Add labels and legend for clarity
ax.set_ylabel('Value')
ax.set_xlabel('Sample')
ax.set_title('Imbalanced Groups on Custom Logarithmic Y-Axis')
ax.set_xticks(x_positions)
ax.set_xticklabels(['Sample 1', 'Sample 2', 'Sample 3', 'Sample 4', 'Sample 5'])
ax.legend()

plt.show()

Key Details to Understand

  • ax.set_yscale('log'): This transforms the y-axis to use logarithmic spacing, which naturally makes your 1,10,100,... ticks evenly spaced visually.
  • Custom tick generation: We calculate the highest power of 10 needed to cover your largest data point, then generate ticks from 10^0 up to that power. This ensures the ticks perfectly match your requested pattern.
  • The formatter lines: These prevent Matplotlib from showing tick labels in scientific notation (like 1e3 instead of 1000), making the plot easier to read at a glance.

Alternative for Seaborn Users

If you prefer Seaborn for plotting, the logic stays the same—you just access the Matplotlib axis to adjust the scale and ticks:

import seaborn as sns
import pandas as pd

# Convert data to a DataFrame for Seaborn
df = pd.DataFrame({
    'Value': group_0 + group_1,
    'Group': ['0']*len(group_0) + ['1']*len(group_1),
    'Sample': ['Sample 1','Sample 2','Sample 3','Sample 4','Sample 5']*2
})

# Create the bar plot
sns.barplot(data=df, x='Sample', y='Value', hue='Group')
plt.yscale('log')

# Set custom ticks
max_val = df['Value'].max()
power_count = int(np.log10(max_val)) + 2
y_ticks = [10**i for i in range(0, power_count)]
plt.yticks(y_ticks)
plt.ticklabel_format(axis='y', style='plain')

plt.title('Imbalanced Groups with Custom Log Y-Ticks (Seaborn)')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:24:02