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

Matplotlib图表条形尺寸不一致问题及标准化图表实现咨询

我之前也踩过这个Matplotlib条形图尺寸不一致的坑!核心问题确实是缺失日期没补零,导致Matplotlib把现有数据点强行均匀分布在整个时间轴上,条形自然就被拉伸变形了。下面给你两个具体的实现方案,亲测好用:

1. 补全缺失日期的工具函数

我通常用Pandas来处理日期补全,因为它的时间序列工具太方便了。这个函数会自动生成完整的日期序列,然后把原数据合并进去,缺失的数值直接填0:

import pandas as pd

def fill_missing_dates(df, date_column, value_column, frequency='D'):
    # 生成从数据中最小到最大日期的完整序列,frequency可以是'D'(日)、'W'(周)、'M'(月)等
    full_date_range = pd.date_range(
        start=df[date_column].min(),
        end=df[date_column].max(),
        freq=frequency
    )
    # 转换成DataFrame用于合并
    full_dates_df = pd.DataFrame({date_column: full_date_range})
    # 左合并原数据,缺失值用0填充
    filled_data = pd.merge(full_dates_df, df, on=date_column, how='left').fillna({value_column: 0})
    return filled_data

使用示例

假设你的原始数据是这样的:

raw_data = pd.DataFrame({
    'sale_date': ['2024-01-01', '2024-01-03', '2024-01-04'],
    'sales': [120, 90, 150]
})
raw_data['sale_date'] = pd.to_datetime(raw_data['sale_date'])

# 补全缺失的2024-01-02
filled_data = fill_missing_dates(raw_data, 'sale_date', 'sales')

用filled_data去画条形图,每个条形的宽度就完全一致了!

2. 统一风格的Matplotlib图表类

如果需要批量生成风格一致的图表,把样式和绘图逻辑封装成类是最高效的方式。这个类可以固定字体、颜色、轴格式等,避免每次重复写样式代码:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

class ConsistentBarChart:
    def __init__(self, fig_size=(12, 6), font='Segoe UI', bar_color='#3498db'):
        # 初始化全局样式
        self.fig_size = fig_size
        self.font = font
        self.bar_color = bar_color
        # 设置全局Matplotlib参数,让所有图表默认用这个风格
        plt.rcParams.update({
            'font.family': self.font,
            'axes.titlesize': 14,
            'axes.titleweight': 'bold',
            'axes.labelsize': 12,
            'xtick.labelsize': 10,
            'ytick.labelsize': 10,
            'grid.alpha': 0.7,
            'grid.linestyle': '--'
        })

    def draw_chart(self, data, date_col, value_col, chart_title, x_label='Date', y_label='Amount'):
        fig, ax = plt.subplots(figsize=self.fig_size)
        # 绘制条形图,固定宽度避免变形
        ax.bar(data[date_col], data[value_col], color=self.bar_color, width=0.8)
        # 优化日期轴显示,避免标签重叠
        ax.xaxis.set_major_locator(mdates.AutoDateLocator())
        ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
        plt.xticks(rotation=45, ha='right')
        # 设置标题和标签
        ax.set_title(chart_title)
        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)
        # 只显示y轴网格
        ax.grid(axis='y')
        plt.tight_layout()
        return fig, ax

    def batch_draw(self, data_list, configs):
        # 批量生成图表:data_list是补全后的DataFrame列表,configs是每个图表的参数字典
        chart_list = []
        for data, config in zip(data_list, configs):
            fig, _ = self.draw_chart(data, **config)
            chart_list.append(fig)
        return chart_list

使用示例

# 创建图表生成器实例,自定义颜色和字体
chart_gen = ConsistentBarChart(bar_color='#e74c3c', font='Arial')

# 单个图表绘制
fig, ax = chart_gen.draw_chart(
    filled_data,
    date_col='sale_date',
    value_col='sales',
    chart_title='Daily Sales Trend',
    y_label='Sales Amount'
)
plt.show()

# 批量绘制示例
batch_data = [filled_data, filled_data]  # 假设有两个数据集
batch_configs = [
    {'date_col':'sale_date', 'value_col':'sales', 'chart_title':'Jan Sales'},
    {'date_col':'sale_date', 'value_col':'sales', 'chart_title':'Feb Sales'}
]
batch_figs = chart_gen.batch_draw(batch_data, batch_configs)

额外小提示

  • 如果不想用Pandas,也可以用datetime模块手动生成日期序列,遍历每个日期并检查是否在原始数据中,缺失的话就添加(日期, 0)的条目。
  • 条形宽度可以根据日期频率调整:比如日数据用width=0.8,周数据可以设为width=5,这样和轴的间隔更匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:32:56