为啥我的 pyplot.plot 数字没有正确保存?

Posted

技术标签:

【中文标题】为啥我的 pyplot.plot 数字没有正确保存?【英文标题】:Why aren't my pyplot.plot figures saved correctly?为什么我的 pyplot.plot 数字没有正确保存? 【发布时间】:2020-07-22 08:45:15 【问题描述】:

我一直在使用 matplotlib 和 scipy 绘制频谱图和波形。频谱图(用matplotlib.pyplot.pcolormesh() 绘制)被正确保存,正如我显示的here,使用以下代码:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
from matplotlib import cm
from scipy import signal
from scipy.io import wavfile

sample_rate, samples = wavfile.read('audio-mono.wav')
frequencies, times, spectrogram = signal.spectrogram(samples[:700000], sample_rate)

cMap = cm.get_cmap('gray', 3000)

new_colors = cMap(np.linspace(0.5, 1, 3000))
black = [0, 0, 0, 1]
new_colors[0, :] = black
new_cmp = ListedColormap(new_colors)

fig = plt.figure(figsize=(4,2), dpi=400, frameon=False)
plt.pcolormesh(times, frequencies, spectrogram, cmap=cMap)
plt.savefig('spectrogram.png')

但是,当我尝试绘制波形并保存图形时,我在绘图窗格中得到了绘图(我使用的是 Spyder),但该图被保存为空白。如果我在 Spyder 的绘图窗格中单击与该图对应的保存按钮,我可以成功保存并看到它,但我需要知道为什么我的代码无法正确保存它。这里是:

import matplotlib.pyplot as plt
from scipy.io import wavfile

sample_rate, samples = wavfile.read('audio-mono.wav')

fig = plt.figure(figsize=(4,1), dpi=500, frameon=False)
ax = plt.Axes(fig, [2, 2, 2, 2])
ax.set_facecolor((0,0,0))
fig.add_axes(ax)
plt.tick_params(axis='both', which='both', bottom=False,
                top=False, left=False, right=False,
                labelbottom=False, labeltop=False,
                labelright=False, labelleft=False)
plt.plot(samples)
plt.savefig('waveform.png')

提前致谢。

编辑 1

请注意,我将图形大小设置为 4x1(英寸)。正在保存的空白图形为 2000x500(像素),实际上与正确保存的频谱图的大小完全相同。我认为这意味着我正在保存使用plt.figure() 创建的图形,但不知何故,轴并没有出现在那里。

编辑 2

根据作为解决方案接受的答案,我发布了两个相同图的图形,其中不同的矩形传递给Axes 实例。

首先,我最初使用上面发布的代码创建的图像(使用 IDE 的“保存”按钮保存)。

其次,使用不同矩形创建的Axes 对象保存的图形(解决方案中提出的那个)。 ax = plt.Axes(fig, [0, 0, 1, 1])

正如已接受答案的评论中所说,我选择将此矩形传递给 Axes 对象的实例,因为它似乎给了我更好的分辨率。

【问题讨论】:

【参考方案1】:

您作为坐标区位置传递的矩形不在图中。来自documentation:

plt.axes(rect, projection=None, polar=False, **kwargs)

4 元组浮点数 rect = [左、下、宽、高]。 在当前图上使用add_axes 添加了一个新轴,其尺寸为归一化 (0, 1) 单位的矩形

因此,你需要证明一个矩形,从图形坐标的(0, 0)开始,一直到图形的边缘,这意味着高度和宽度都是1。

所以改变:

ax = plt.Axes(fig, [2, 2, 2, 2])

ax = plt.Axes(fig, [0, 0, 1, 1])

【讨论】:

那行得通。非常感谢你。现在,我已经对同一行感到困惑,我正在考虑将其作为另一个问题发布,但这个解决方案引发了另一个疑问。我不明白rect 的元素是什么。为什么left = 2bottom = 2 使矩形不在图中?我选择了[2, 2, 2, 2],因为在玩弄这些值时,我意识到它们在绘图窗格中给了我一个非常好的“分辨率”。请参阅问题中的编辑以了解我的意思。

以上是关于为啥我的 pyplot.plot 数字没有正确保存?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的动态分配的数组没有保存正确的值?

matplotlib.pyplot.plot详解

Matplotlib.pyplot.plot 绘图

Qt会话管理错误与matplotlib.pyplot.plot

为啥 Python 不使用对象 .save() 将我的模型保存到数据库?

为啥 Google BigQuery 在使用视图时没有正确使用分区日期