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

基于Matplotlib绘制棒球投球数据50%好球带等高线图问题求助

问题排查

你现有代码的错误主要集中在3个位置:

  • 直接使用原始散点坐标生成网格:np.meshgrid(df2_array[:,0], df2_array[:,1]) 会生成10000×10000的超大冗余网格,且原始散点无序、存在大量重复值,会导致插值结果混乱
  • 未明确指定等高线阈值:levels=2 是将插值后的Z值范围自动均分2段生成等高线,不会固定对应你需要的50%好球概率(Z=0.5)边界
  • 二元离散值直接用线性插值容易出现边界空值,对于这类概率类的等高线绘制,也可以先做二维分箱统计好球概率再画图,结果更稳定

修正后代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

df2_array = df2[['plate_x', 'plate_z', 'strike']].to_numpy()
x = df2_array[:, 0]
y = df2_array[:, 1]
z = df2_array[:, 2]

# 1. 生成规整的等间隔网格,步长可根据你的坐标范围调整
xi = np.linspace(x.min(), x.max(), 100)
yi = np.linspace(y.min(), y.max(), 100)
X, Y = np.meshgrid(xi, yi)

# 2. 插值得到网格点的好球概率,可选method='nearest'/'cubic'避免边界NaN
Z = griddata((x, y), z, (X, Y), method='cubic')
# 可选:填补边界的NaN值
Z = np.nan_to_num(Z, nan=np.nanmean(z))

# 3. 明确指定仅绘制Z=0.5的等高线,即50%好球概率边界
plt.contour(X, Y, Z, levels=[0.5], alpha=0.5, colors='red')
# 如果需要同时显示热图可以加这行
# plt.contourf(X, Y, Z, cmap='RdBu', alpha=0.3)
plt.xlabel('plate_x')
plt.ylabel('plate_z')
plt.show()

可选优化方案

如果希望结果更符合实际比赛的好球带统计规律,可以先做二维分箱计算平均好球率再画图,避免插值带来的平滑偏差:

# 二维分箱统计
H, xedges, yedges = np.histogram2d(x, y, bins=50, weights=z)
counts, _, _ = np.histogram2d(x, y, bins=50)
# 计算每个分箱的好球概率,避免除以0
Z_prob = np.divide(H, counts, out=np.zeros_like(H), where=counts!=0)
# 取分箱中点做网格
X_bin, Y_bin = np.meshgrid((xedges[:-1] + xedges[1:])/2, (yedges[:-1] + yedges[1:])/2)
plt.contour(X_bin, Y_bin, Z_prob.T, levels=[0.5], alpha=0.5)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:15:07