踩坑记录:相同数据,两次plt画图结果不一致
使用完全相同的数据,plt画图却能得到不同的图像。
问题
笔者使用plt
画柱状图,代码如下:
def plot_activation_frequencies():
if not os.path.exists("img"):
os.makedirs("img")
for layer_name, activations in layer_activations.items():
input_data = flatten_activations(activations["inputs"])
output_data = flatten_activations(activations["outputs"])
input_activation_freq = (input_data > 0).mean(axis=0)
output_activation_freq = (output_data > 0).mean(axis=0)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.bar(
range(len(input_activation_freq)),
input_activation_freq,
color="blue",
alpha=0.7,
)
plt.title(f"{layer_name} Input Activation Frequency")
plt.xlabel("Index")
plt.ylabel("Frequency")
plt.subplot(1, 2, 2)
plt.bar(
range(len(output_activation_freq)),
output_activation_freq,
color="green",
alpha=0.7,
)
plt.title(f"{layer_name} Output Activation Frequency")
plt.xlabel("Index")
plt.ylabel("Frequency")
plt.tight_layout()
plt.savefig(f"img/{layer_name}_activation_frequency.png")
plt.close()
通过print
打印中间数据,可得到input_activation_freq
和output_activation_freq
的内容完全一样。也就是说,两次plt.bar
的参数除了颜色都是一样的。但是,画出来的两个图像却长得不一样!
解决过程
- 笔者又直接把第二个
plt.bar
的参数也换成input_activation_freq
,也就是说直接用相同的input_activation_freq
连续画两次图,可得到的两个图仍然不一样。 - 笔者又注释掉第二次
plt.bar
,只画一次图,结果得到的图甚至和之前得到的两种图都不一样。 - 笔者尝试把
input_activation_freq
换成np.arange(0, 3000, 6)
,两边画的图一样了 - 笔者尝试把
input_activation_freq
换成input_activation_freq[:2]
,两边画的图一样。 - 笔者尝试把
input_activation_freq
换成input_activation_freq[:100]
,两边画的图一样。 - 笔者尝试把
input_activation_freq
换成input_activation_freq[:1000]
,两边画的图又不一样了(重要)。
也就是说,两次画图得到的图是否一样,竟然和数据量有关系?
原因
原因其实是画的图横坐标太长(3072),也就是说有三千多条柱子,而图又太小(plt.figure(figsize=(12, 6))
),而一条柱子的宽度起码要占一个像素点,就导致这么小的图其实无法完全展示所有的柱子。而左右两个plt.subplot
画图时可能对柱子采的样不同(毕竟要在这么小的图内显示这么多柱子是不可能的,其实只能展示一部分柱子),就导致相同数据左右画的图不一致。
解决方案
可以扩大图的大小,即调整plt.figure
的参数大小。
更好的方式是把png
换成使用pdf
存储,即可解决问题。