Matplotlib文本位置异常问题:多次运行绘图函数位置变动
问题原因分析
你遇到的文本位置混乱问题,核心根源是代码里引用了未定义的ax变量,导致文本的坐标变换逻辑完全出错:
在你的函数中,明明创建了两个独立子图ax1和ax2,但调用ax1.text()和ax2.text()时,却错误地写了transform=ax.transAxes——这里的ax在函数内部根本没有定义,Python会自动去全局命名空间里找这个变量:
- 重启内核后,全局命名空间里没有
ax,此时Python会默认绑定到当前活动的Axes对象(但和你当前要绘制的子图不匹配),直接导致文本被画到子图范围外; - 重复运行单元格时,全局的
ax可能被之前的运行覆盖成了其他Axes对象,所以文本位置会跟着乱变; - 运气差的时候还会直接抛出
NameError,因为全局也找不到ax。
另外还有个小bug:函数参数是_df,但函数内部直接用了df,这会导致如果全局没有df变量的话,函数直接报错,得把参数名统一才行。
修正后的代码
把未定义的ax替换成对应的子图对象ax1/ax2,同时修正参数名问题,还优化了代码可读性:
import matplotlib.pyplot as plt import pandas as pd def critics_and_users_score_corr_with_total_sales(df, platform): # 筛选对应平台且评分非空的数据 critic_mask = df['critic_score'].notna() & (df['platform'] == platform) sales_critic = df[critic_mask]['total_sales'] score_critic = df[critic_mask]['critic_score'] user_mask = df['user_score'].notna() & (df['platform'] == platform) sales_user = df[user_mask]['total_sales'] score_user = df[user_mask]['user_score'] info_bbox = dict(boxstyle='round', facecolor='white', alpha=0.2) fig = plt.figure(figsize=(16, 7)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) # 绘制媒体评分与销量的散点图 ax1.grid(True) ax1.set_xlim(0,25) ax1.set_title(f'{platform} Critics score & Total sales correlation') ax1.set_xlabel('Total sales') ax1.set_ylabel('Critics score') ax1.scatter(sales_critic, score_critic, s=10) # 修正:绑定当前子图的transAxes坐标系统 corr_critic = sales_critic.corr(score_critic) ax1.text(0.345, 0.88, f'Correlation: {corr_critic:.2f}', transform=ax1.transAxes, verticalalignment='top', horizontalalignment='right', bbox=info_bbox) # 绘制用户评分与销量的散点图 ax2.grid(True) ax2.set_xlim(0,25) ax2.set_title(f'{platform} Users score & Total sales correlation') ax2.set_xlabel('Total sales') ax2.set_ylabel('Users score') ax2.scatter(sales_user, score_user, s=10) # 修正:绑定当前子图的transAxes坐标系统 corr_user = sales_user.corr(score_user) ax2.text(0.892, 0.88, f'Correlation: {corr_user:.2f}', transform=ax2.transAxes, verticalalignment='top', horizontalalignment='right', bbox=info_bbox) plt.show()
额外说明
transAxes是Matplotlib里的归一化坐标变换,范围是子图左下角(0,0)到右上角(1,1),必须绑定到当前子图的Axes对象,才能保证文本位置始终相对于子图正确显示。我还把字符串格式化改成了更简洁的f-string,提前计算相关系数也让代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者Ivan Dembicki
相关产品推荐
相关产品推荐

