Matplotlib绘制直方图技术求助:基于新加坡机动车燃油数据集
解决Matplotlib绘制车辆燃料类型频次直方图的问题
我看了你当前的代码,发现不仅重复代码太多,还没完全实现你想要的两类需求——各车型不同燃料类型的使用频次统计(这里分两种场景:一是各燃料的总使用量统计,二是各燃料使用量的分布直方图)和特定车型(如出租车)的燃料类型频次统计。下面我给你优化后的代码,同时覆盖这两种场景:
先明确需求场景
首先要区分两个常见的统计方向:
- 类型频次统计:展示不同燃料类型对应的总使用量(用柱状图更直观)
- 分布直方图:展示某类燃料使用量在时间维度的分布情况(比如各年份数量的频次)
下面的代码会同时实现这两个方向的需求:
完整代码实现
import numpy as np import matplotlib.pyplot as plt import pandas as pd # 读取数据集,pandas处理表格数据更高效 df = pd.read_csv("data/motor-vehicle-population-statistics-by-type-of-fuel-used.csv") # 转换日期列,提取年份用于时间维度分析 df['year'] = pd.to_datetime(df['month']).dt.year # -------------------------- # 场景1:各车型不同燃料类型的总使用量统计(柱状图) # -------------------------- plt.figure(figsize=(14, 8)) categories = df['category'].unique() fuel_types = df['type'].unique() bar_width = 0.15 x = np.arange(len(categories)) # 循环绘制每种燃料的柱状图 for idx, fuel in enumerate(fuel_types): # 按车型分组,计算该燃料的总使用量 grouped_data = df[df['type'] == fuel].groupby('category')['number'].sum() # 填充缺失车型的数据为0,避免图表断层 grouped_data = grouped_data.reindex(categories, fill_value=0) plt.bar(x + idx*bar_width, grouped_data.values, width=bar_width, alpha=0.7, label=fuel) plt.title('各车型不同燃料类型总使用量统计', fontsize=16) plt.xlabel('车型', fontsize=12) plt.ylabel('总使用量', fontsize=12) plt.xticks(x + bar_width*(len(fuel_types)-1)/2, categories, rotation=45) plt.legend(title='燃料类型', bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() # -------------------------- # 场景2:各车型不同燃料类型的使用量分布直方图 # -------------------------- plt.figure(figsize=(14, 8)) # 选几个主要车型展示,避免图表太拥挤 selected_categories = ['Cars', 'Taxis', 'Buses'] for cat in selected_categories: cat_data = df[df['category'] == cat] # 获取该车型的所有燃料类型 cat_fuels = cat_data['type'].unique() for fuel in cat_fuels: fuel_values = cat_data[cat_data['type'] == fuel]['number'].values plt.hist(fuel_values, alpha=0.4, label=f"{cat}-{fuel}", bins=8) plt.title('各车型不同燃料类型使用量分布直方图', fontsize=16) plt.xlabel('使用量', fontsize=12) plt.ylabel('频次(年份数量)', fontsize=12) plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() # -------------------------- # 场景3:特定车型(出租车)的燃料类型总使用量统计(柱状图) # -------------------------- plt.figure(figsize=(10, 6)) taxi_grouped = df[df['category'] == 'Taxis'].groupby('type')['number'].sum() taxi_grouped.plot(kind='bar', alpha=0.7, colormap='viridis') plt.title('出租车不同燃料类型总使用量统计', fontsize=16) plt.xlabel('燃料类型', fontsize=12) plt.ylabel('总使用量', fontsize=12) plt.xticks(rotation=45) plt.tight_layout() # -------------------------- # 场景4:特定车型(出租车)的燃料类型使用量分布直方图 # -------------------------- plt.figure(figsize=(10, 6)) taxi_fuels = df[df['category'] == 'Taxis']['type'].unique() for fuel in taxi_fuels: fuel_values = df[(df['category'] == 'Taxis') & (df['type'] == fuel)]['number'].values plt.hist(fuel_values, alpha=0.5, label=fuel, bins=8) plt.title('出租车各燃料类型使用量分布直方图', fontsize=16) plt.xlabel('使用量', fontsize=12) plt.ylabel('频次(年份数量)', fontsize=12) plt.legend() plt.tight_layout() plt.show()
代码优化点说明
- 减少重复代码:用循环和分组代替原来逐个手动筛选的方式,大幅简化代码,也方便后续扩展更多车型/燃料类型
- 数据预处理:用
pandas处理日期和分组,比numpy更适合表格数据,还能自动填充缺失值 - 图表可读性优化:调整图尺寸、坐标轴标签、图例位置,添加旋转的x轴标签避免重叠,用
tight_layout()自动调整布局 - 覆盖两种统计场景:既实现了总使用量的对比(柱状图),也实现了使用量的分布直方图,完全匹配你的需求
额外小技巧
- 如果只想看最新年份的数据,可以添加筛选条件:
df = df[df['year'] == df['year'].max()] - 可以调整
bins参数来改变直方图的区间数量,让分布展示更合理 - 如果需要保存图表,只需要在
plt.show()前添加plt.savefig('图表名称.png', dpi=300, bbox_inches='tight')
内容的提问来源于stack exchange,提问作者coder121
相关产品推荐
相关产品推荐

