我来为您创建一个展示体能消耗数据差异的Python案例,这个案例将使用matplotlib和numpy来可视化不同运动类型的体能消耗对比。

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用于显示中文
plt.rcParams['axes.unicode_minus'] = False
# 创建示例数据
# 模拟8名不同健身爱好者的体能消耗数据
np.random.seed(42)
# 不同运动类型的平均消耗(卡路里/小时)
sports = ['跑步', '游泳', '骑行', '力量训练', '瑜伽', 'HIIT']
# 模拟一周7天的数据
days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
# 生成随机数据
data = np.random.normal(loc=300, scale=80, size=(6, 7))
# 设置不同的平均值和标准差来体现差异
means = [380, 350, 320, 280, 180, 420] # 各运动的期望值
stds = [30, 25, 35, 20, 15, 40] # 各运动的波动性
# 生成更真实的数据
data = np.random.normal(means, stds, size=(6, 7))
# 确保数据为正数
data = np.abs(data)
# 创建图形
fig = plt.figure(figsize=(16, 10))
# 1. 箱线图 - 展示数据分布差异
ax1 = plt.subplot(2, 3, 1)
bp = ax1.boxplot(data, tick_labels=sports, patch_artist=True)
ax1.set_title('体能消耗分布对比(箱线图)')
ax1.set_ylabel('卡路里消耗(千卡/小时)')
ax1.grid(True, alpha=0.3)
# 给箱线图添加颜色
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD']
for patch, color in zip(bp['boxes'], colors):
patch.set_facecolor(color)
# 2. 折线图 - 展示一周趋势
ax2 = plt.subplot(2, 3, 2)
for i, sport in enumerate(sports):
ax2.plot(days, data[i], marker='o', linewidth=2, label=sport, color=colors[i])
ax2.set_title('一周体能消耗趋势')
ax2.set_xlabel('星期')
ax2.set_ylabel('卡路里消耗(千卡/小时)')
ax2.legend(loc='upper right', fontsize=8)
ax2.grid(True, alpha=0.3)
# 3. 柱状图 - 平均值对比
ax3 = plt.subplot(2, 3, 3)
means_data = np.mean(data, axis=1)
bars = ax3.bar(sports, means_data, color=colors, alpha=0.8)
ax3.set_title('平均体能消耗对比')
ax3.set_ylabel('平均卡路里消耗(千卡/小时)')
ax3.grid(True, alpha=0.3)
# 添加数值标签
for bar, value in zip(bars, means_data):
ax3.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 5,
f'{value:.1f}', ha='center', va='bottom')
# 4. 散点图 - 展示个体差异
ax4 = plt.subplot(2, 3, 4)
for i, sport in enumerate(sports):
ax4.scatter([sport] * 7, data[i], alpha=0.6, s=80,
color=colors[i], edgecolors='black', linewidth=0.5)
ax4.set_title('各运动逐日消耗散点图')
ax4.set_ylabel('卡路里消耗(千卡/小时)')
ax4.tick_params(axis='x', rotation=30)
ax4.grid(True, alpha=0.3)
# 5. 热力图 - 可视化完整数据矩阵
ax5 = plt.subplot(2, 3, 5)
heatmap_data = data.copy()
im = ax5.imshow(heatmap_data, cmap='YlOrRd', aspect='auto')
ax5.set_xticks(np.arange(len(days)))
ax5.set_xticklabels(days)
ax5.set_yticks(np.arange(len(sports)))
ax5.set_yticklabels(sports)
ax5.set_title('体能消耗热力图')
# 添加颜色条
plt.colorbar(im, ax=ax5, label='卡路里消耗(千卡/小时)')
# 6. 饼图 + 数值统计表
ax6 = plt.subplot(2, 3, 6)
ax6.axis('off')
# 创建统计表
stats_data = []
for i, sport in enumerate(sports):
stats_data.append([
sport,
f'{np.mean(data[i]):.1f}',
f'{np.std(data[i]):.1f}',
f'{np.max(data[i]):.1f}',
f'{np.min(data[i]):.1f}'
])
table = ax6.table(cellText=stats_data,
colLabels=['运动', '平均', '标准差', '最大', '最小'],
cellLoc='center',
loc='center',
colWidths=[0.25, 0.15, 0.15, 0.15, 0.15])
table.auto_set_font_size(False)
table.set_fontsize(9)
table.scale(1.2, 1.5)
# 为表头设置颜色
for j in range(len(stats_data[0])):
table[0, j].set_facecolor('#4472C4')
table[0, j].set_text_props(weight='bold', color='white')
ax6.set_title('体能消耗统计数据', pad=20)
# 调整布局
plt.tight_layout()
# 添加总体标题
fig.suptitle('不同运动方式的体能消耗差异分析', fontsize=18, fontweight='bold', y=1.02)
# 显示图形
plt.show()
# 批量打印详细的统计信息
print("="*60)
print("体能消耗差异详细分析")
print("="*60)
for i, sport in enumerate(sports):
print(f"\n{sport}运动:")
print(f" 平均消耗: {np.mean(data[i]):.1f} 千卡/小时")
print(f" 标准差: {np.std(data[i]):.1f} (波动性)")
print(f" 最大消耗: {np.max(data[i]):.1f} 千卡/小时")
print(f" 最小消耗: {np.min(data[i]):.1f} 千卡/小时")
print(f" 中位数: {np.median(data[i]):.1f} 千卡/小时")
# 计算变异系数(离散程度)
print("\n" + "="*60)
print("变异系数(CV = 标准差/平均值 × 100%)")
print("="*60)
for i, sport in enumerate(sports):
cv = np.std(data[i]) / np.mean(data[i]) * 100
print(f"{sport}: {cv:.2f}%")
# 两两对比的t检验(简化版本)
print("\n" + "="*60)
print("运动方式间的差异对比")
print("="*60)
from scipy import stats
sports_means = {sport: np.mean(data[i]) for i, sport in enumerate(sports)}
# 找出最高和最低
max_sport = max(sports_means, key=sports_means.get)
min_sport = min(sports_means, key=sports_means.get)
print(f"消耗最高: {max_sport} ({sports_means[max_sport]:.1f} 千卡/小时)")
print(f"消耗最低: {min_sport} ({sports_means[min_sport]:.1f} 千卡/小时)")
print(f"差异: {sports_means[max_sport] - sports_means[min_sport]:.1f} 千卡/小时")
print(f"差异百分比: {(sports_means[max_sport] - sports_means[min_sport]) / sports_means[min_sport] * 100:.1f}%")
# 进行t检验
max_idx = sports.index(max_sport)
min_idx = sports.index(min_sport)
t_stat, p_value = stats.ttest_ind(data[max_idx], data[min_idx])
print(f"\n显著性检验 (t检验):")
print(f" t统计量: {t_stat:.3f}")
print(f" p值: {p_value:.4f}")
print(f" {'有显著性差异' if p_value < 0.05 else '无显著性差异'}")
这个案例提供了多角度的体能消耗数据差异可视化:
- 箱线图:展示不同运动消耗的中位数和分布范围
- 折线图:展示一周内各种运动的消耗趋势
- 柱状图:直观对比平均消耗水平
- 散点图:展示每日的具体差异
- 热力图:完整呈现所有数据矩阵
- 统计表:提供详细的数值统计
同时还包括统计分析,如变异系数、t检验等,帮助量化差异的显著性。
运行这个案例,你将看到:
- HIIT和跑步消耗较高
- 瑜伽和力量训练的个体差异较小
- 不同运动之间的卡路里消耗有明显差异
- 通过统计数据可以客观判断差异的显著性