Matplotlib无法在同一画布绘制三条曲线的问题求助
问题:Matplotlib同画布无法显示FedAvg折线,仅显示两条水平参考线
在Jupyter Notebook中运行以下代码,目标是在同一张图中绘制三条曲线:FedAvg折线、两条水平参考线,但目前仅显示两条水平参考线。单独绘制FedAvg折线时可以正常显示。
代码如下:
import matplotlib.pyplot as plt from pathlib import Path def plot_metric_from_history() -> None: metric_dict = {'accuracy': [('0', '98.82'), ('1', '98.87'), ('2', '98.9'), ('3', '98.91'), ('4', '98.98'), ('5', '98.89'), ('6', '98.99'), ('7', '99.05'), ('8', '99.0'), ('9', '99.03')]} expected_maximum = "0.9924" # Convert values to float metric_dict['accuracy'] = ([(int(round_num), float(accuracy_val)) for round_num, accuracy_val in metric_dict['accuracy']]) rounds, values = zip(*metric_dict["accuracy"]) fig = plt.figure() axis = fig.add_subplot(111) plt.plot(rounds, values, label="FedAvg") # Set the apect ratio to 1.0 xleft, xright = axis.get_xlim() ybottom, ytop = axis.get_ylim() axis.set_aspect(abs((xright - xleft) / (ybottom - ytop)) * 1.0) # Set expected graph for data plt.axhline( y=float(expected_maximum), color="r", linestyle="--", label=f"Paper's best result @{expected_maximum}", ) # Set paper's results plt.axhline( y=0.99, color="silver", label="Paper's baseline @0.9900", ) plt.ylim([0.97, 1]) plt.title(f"Validation - MNIST") plt.xlabel("Rounds") plt.ylabel("Accuracy") plt.legend(loc="lower right") # Set the apect ratio to 1.0 xleft, xright = axis.get_xlim() ybottom, ytop = axis.get_ylim() axis.set_aspect(abs((xright - xleft) / (ybottom - ytop)) * 1.0) plt.show() plot_metric_from_history()
问题原因
- 数值转换错误:metric_dict中的准确率是百分比格式(如
98.82代表98.82%),但代码直接转成float后得到98.82,而后续设置的y轴范围是[0.97, 1](对应97%到100%),导致FedAvg折线的y值远超出可视范围,自然无法显示。 - 重复设置纵横比:在绘制折线后和设置完所有元素后两次设置纵横比,干扰了坐标轴的自动调整逻辑,进一步加剧显示问题。
修复方案
- 将百分比格式的准确率数值除以100,转换为小数格式(如
98.82转为0.9882)。 - 只在所有绘图元素设置完成后统一设置纵横比,避免重复调整干扰。
修复后的代码
import matplotlib.pyplot as plt from pathlib import Path def plot_metric_from_history() -> None: metric_dict = {'accuracy': [('0', '98.82'), ('1', '98.87'), ('2', '98.9'), ('3', '98.91'), ('4', '98.98'), ('5', '98.89'), ('6', '98.99'), ('7', '99.05'), ('8', '99.0'), ('9', '99.03')]} expected_maximum = "0.9924" # 修正:将百分比转换为小数 metric_dict['accuracy'] = ([(int(round_num), float(accuracy_val)/100) for round_num, accuracy_val in metric_dict['accuracy']]) rounds, values = zip(*metric_dict["accuracy"]) fig = plt.figure() axis = fig.add_subplot(111) plt.plot(rounds, values, label="FedAvg") # 绘制水平参考线 plt.axhline( y=float(expected_maximum), color="r", linestyle="--", label=f"Paper's best result @{expected_maximum}", ) plt.axhline( y=0.99, color="silver", label="Paper's baseline @0.9900", ) # 设置坐标轴范围和标签 plt.ylim([0.97, 1]) plt.title(f"Validation - MNIST") plt.xlabel("Rounds") plt.ylabel("Accuracy") plt.legend(loc="lower right") # 统一设置纵横比(放在最后) xleft, xright = axis.get_xlim() ybottom, ytop = axis.get_ylim() axis.set_aspect(abs((xright - xleft) / (ybottom - ytop)) * 1.0) plt.show() plot_metric_from_history()
内容的提问来源于stack exchange,提问作者Catarina Nogueira
相关产品推荐
相关产品推荐

