如何解决傅里叶变换可视化代码中图表压缩模糊的问题?
傅里叶变换可视化图表压缩问题解决
问题描述
我正在做傅里叶变换的入门可视化,展示不同频率值下余弦函数绕复指数函数(e^{2\pi ft})旋转的图像。参考相关代码实现后,运行生成的图表出现严重压缩,无法清晰查看细节。
原代码
import matplotlib.pyplot as plt import numpy as np import seaborn as sns sns.set() f = 3.0 t = np.arange(0,2,0.001) cos_wave = np.cos(2*np.pi*f*t) # cos_wave = 2*m.cos(2*np.pi*f*t) + 5*m.cos(2*np.pi*f*2*t) plt.rcParams["figure.figsize"] = (12,12) plt.plot(t,cos_wave) plt.title("Cosine Wave with 3 Hz frequency") plt.ylabel("Amplitude") plt.xlabel('Time (in seconds)'); r_cord = [] min_freq_range = 0.0 max_freq_range = 10.0 sf_list = np.arange(min_freq_range, max_freq_range, 0.1) for sf in sf_list: r_cord.append( [(cos_wave[i], t[i]*sf*2*np.pi) for i in range(len(t)) ] ) x_cord , y_cord = [], [] for l in range(len(r_cord)): x_cord.append( [amp*np.cos(theta) for (amp,theta) in r_cord[l]] ) y_cord.append( [amp*np.sin(theta) for (amp,theta) in r_cord[l]] ) mean_list = [] plt.rcParams["figure.figsize"] = (30,110) for l in range(len(r_cord)): plt.subplot(int(len(r_cord)/4)+1, 4, int(l+1)) plt.plot(x_cord[l], y_cord[l]) plt.plot(np.mean(x_cord[l]), np.mean(y_cord[l]), 'or' ) plt.title("Sampling Freq = "+str(round(sf_list[l], 2))+" Hz") plt.show(block=True) # Storing the COM for plotting later x_mean = np.sum(x_cord[l]) mean_list.append(x_mean)
问题原因分析
- 循环内频繁调用
plt.show(block=True):每次调用都会单独弹出窗口显示当前子图,破坏整体子图布局,导致后续子图被强制压缩。 - 不合理的画布尺寸设置:
(30,110)的尺寸过于夸张,让子图在超大画布上失去比例,出现拉伸或压缩。 - 子图行数计算不准确:
int(len(r_cord)/4)+1会多算一行,导致子图分布稀疏或错位。
修改后的代码
import matplotlib.pyplot as plt import numpy as np import seaborn as sns import math sns.set() f = 3.0 t = np.arange(0, 2, 0.001) cos_wave = np.cos(2*np.pi*f*t) # 绘制原始余弦波 plt.rcParams["figure.figsize"] = (12, 6) plt.plot(t, cos_wave) plt.title("3Hz 余弦波") plt.ylabel("振幅") plt.xlabel("时间(秒)") plt.show() # 计算极坐标转换后的坐标 r_cord = [] min_freq_range = 0.0 max_freq_range = 10.0 sf_list = np.arange(min_freq_range, max_freq_range, 0.1) for sf in sf_list: r_cord.append([(cos_wave[i], t[i]*sf*2*np.pi) for i in range(len(t))]) x_cord, y_cord = [], [] for l in range(len(r_cord)): x_cord.append([amp*np.cos(theta) for (amp, theta) in r_cord[l]]) y_cord.append([amp*np.sin(theta) for (amp, theta) in r_cord[l]]) # 绘制所有子图 mean_list = [] total_plots = len(r_cord) cols = 4 rows = math.ceil(total_plots / cols) # 准确计算所需行数 plt.rcParams["figure.figsize"] = (20, rows * 4) # 按行数动态设置画布高度 for l in range(total_plots): plt.subplot(rows, cols, l+1) plt.plot(x_cord[l], y_cord[l]) plt.plot(np.mean(x_cord[l]), np.mean(y_cord[l]), 'or') plt.title(f"采样频率 = {round(sf_list[l], 2)} Hz") plt.axis('equal') # 保持坐标轴比例一致,避免图形变形 plt.tight_layout() # 自动调整子图间距,避免标题重叠 plt.show() # 存储质心信息 for l in range(total_plots): x_mean = np.sum(x_cord[l]) mean_list.append(x_mean)
关键修改说明
- 将
plt.show(block=True)移到循环外,一次性渲染所有子图,保证布局完整性。 - 用
math.ceil(total_plots / cols)准确计算子图行数,避免布局错位。 - 动态设置画布高度:
rows * 4,让每个子图有足够的显示空间。 - 添加
plt.axis('equal')保证每个子图的坐标轴比例一致,防止图形变形。 - 使用
plt.tight_layout()自动调整子图间距,避免标题、标签互相遮挡。
内容的提问来源于stack exchange,提问作者Curliness7530
相关产品推荐
相关产品推荐

