如何在Matplotlib中缩短跨赛季间隔日期点的距离?
解决跨赛季绘图休赛期连线过长的问题
方法1:插入空白断开跨赛季连线
要保留date类型同时避免休赛期的长连线,最直接的方式是在每个赛季末尾插入一行NaN值的表现数据,让matplotlib自动跳过这些点,断开跨赛季的连线。
步骤:
- 按赛季对数据分组(比如WNBA按年份划分赛季)
- 在每个赛季的最后一条数据后,添加一行日期(可取赛季末日期后几天)、表现为
NaN的记录 - 最终绘图时,
plt.plot()会自动忽略NaN点,不会画出休赛期的连线
示例代码:
import pandas as pd import matplotlib.pyplot as plt # 假设原始数据已整理为包含date和performance的DataFrame df = pd.DataFrame({'date': pd.to_datetime(date_list), 'performance': performance_list}) df['season'] = df['date'].dt.year # 生成带分隔的数据集 split_data = [] for season in df['season'].unique(): season_df = df[df['season'] == season] # 添加分隔行:日期取赛季最后一天+2天,表现设为NaN last_date = season_df['date'].max() split_row = pd.DataFrame({ 'date': [last_date + pd.Timedelta(days=2)], 'performance': [float('nan')], 'season': [season] }) split_data.append(season_df) split_data.append(split_row) final_df = pd.concat(split_data).reset_index(drop=True) plt.plot(final_df['date'], final_df['performance']) plt.gcf().autofmt_xdate() plt.show()
方法2:自定义时间缩放,压缩休赛期间隔
如果希望主动压缩休赛期的视觉间隔、拉长赛季内的间隔,可以通过自定义坐标映射实现,同时保留date类型的刻度标签。
核心思路:
- 将赛季内的日期按实际天数映射,休赛期则按比例压缩(比如把180天的休赛期压缩为10天的视觉间隔)
- 用原始日期作为x轴刻度标签,确保时间信息准确
示例代码:
import pandas as pd import matplotlib.pyplot as plt from matplotlib.ticker import FixedLocator, FixedFormatter df = pd.DataFrame({'date': pd.to_datetime(date_list), 'performance': performance_list}) df['season'] = df['date'].dt.year scaled_x = [] prev_season_end = None for season in df['season'].unique(): season_df = df[df['season'] == season] season_start = season_df['date'].min() season_end = season_df['date'].max() # 计算赛季内日期相对赛季开始的天数 season_days = (season_df['date'] - season_start).dt.days if prev_season_end is not None: # 休赛期实际天数压缩为10天的视觉间隔 base = scaled_x[-1] + 10 else: base = 0 scaled_x.extend(base + season_days.tolist()) prev_season_end = season_end # 绘制缩放后的折线 plt.plot(scaled_x, df['performance']) # 设置自定义刻度:用关键日期(赛季起止)作为标签 key_dates = df.groupby('season')['date'].agg(['min', 'max']).stack().tolist() key_scaled_x = [scaled_x[df[df['date'] == d].index[0]] for d in key_dates] plt.gca().xaxis.set_major_locator(FixedLocator(key_scaled_x)) plt.gca().xaxis.set_major_formatter(FixedFormatter([d.strftime('%Y-%m-%d') for d in key_dates])) plt.gcf().autofmt_xdate() plt.show()
方法3:分赛季独立绘制折线
直接按赛季拆分数据,每个赛季单独绘制折线,彻底避免跨赛季连线,同时x轴保留date类型。
示例代码:
import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame({'date': pd.to_datetime(date_list), 'performance': performance_list}) df['season'] = df['date'].dt.year fig, ax = plt.subplots() # 遍历每个赛季绘制折线 for season in df['season'].unique(): season_df = df[df['season'] == season] ax.plot(season_df['date'], season_df['performance'], label=f'Season {season}') # 调整x轴刻度数量,避免拥挤 ax.xaxis.set_major_locator(plt.MaxNLocator(20)) plt.gcf().autofmt_xdate() plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者babeimi
相关产品推荐
相关产品推荐

