踩坑记录:相同数据,两次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_freqoutput_activation_freq的内容完全一样。也就是说,两次plt.bar的参数除了颜色都是一样的。但是,画出来的两个图像却长得不一样!

解决过程

  1. 笔者又直接把第二个plt.bar的参数也换成input_activation_freq,也就是说直接用相同的input_activation_freq连续画两次图,可得到的两个图仍然不一样。
  2. 笔者又注释掉第二次plt.bar,只画一次图,结果得到的图甚至和之前得到的两种图都不一样。
  3. 笔者尝试把input_activation_freq换成np.arange(0, 3000, 6),两边画的图一样了
  4. 笔者尝试把input_activation_freq换成input_activation_freq[:2],两边画的图一样。
  5. 笔者尝试把input_activation_freq换成input_activation_freq[:100],两边画的图一样。
  6. 笔者尝试把input_activation_freq换成input_activation_freq[:1000],两边画的图又不一样了(重要)。

也就是说,两次画图得到的图是否一样,竟然和数据量有关系?

原因

原因其实是画的图横坐标太长(3072),也就是说有三千多条柱子,而图又太小(plt.figure(figsize=(12, 6))),而一条柱子的宽度起码要占一个像素点,就导致这么小的图其实无法完全展示所有的柱子。而左右两个plt.subplot画图时可能对柱子采的样不同(毕竟要在这么小的图内显示这么多柱子是不可能的,其实只能展示一部分柱子),就导致相同数据左右画的图不一致。

解决方案

可以扩大图的大小,即调整plt.figure的参数大小。
更好的方式是把png换成使用pdf存储,即可解决问题。