用频率(kHz)替换imshow的x轴索引

huangapple go评论140阅读模式
英文:

Replace x-axis index of imshow with frequency (kHz)

问题

以下是您提供的代码的翻译部分:

  1. 我有以下绘图
  2. 导入numpynp
  3. 导入matplotlib.pyplotplt
  4. fs = 1000
  5. t = np.arange(0, 0.1, 1/fs)
  6. N = len(t)
  7. f_bin = fs / N
  8. f = np.arange(0, fs, f_bin)
  9. X = [np.fft.fft(np.sin(2 * np.pi * 100 * t)), np.fft.fft(np.sin(2 * np.pi * 200 * t)), np.fft.fft(np.sin(2 * np.pi * 300 * t))]
  10. M = np.absolute(X)
  11. fig, ax = plt.subplots()
  12. im = ax.imshow(M[:,:len(M[0,:]) // 2], cmap='viridis', aspect=1)
  13. clb = fig.colorbar(im, ax=ax)
  14. clb.ax.set_title("Magnitude")
  15. ax.set_xlabel(f"Index (f[{round(100/f_bin)}] = {f[round(100/f_bin)]} Hz)")
  16. ax.set_ylabel("# FFT")
  17. ax.set_title("Built-in FFT")
  18. plt.show()

这段代码产生了以下结果:

用频率(kHz)替换imshow的x轴索引

是否有一种(好的)方法可以使用f_binf将“Index”转换为实际的“frequency bin”?

用频率(kHz)替换imshow的x轴索引

我希望我没有忽略在Stack Overflow中已经存在的解决方案。

  1. <details>
  2. <summary>英文:</summary>
  3. I have following plot
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. fs = 1000
  7. t = np.arange(0, 0.1, 1/fs)
  8. N = len(t)
  9. f_bin = fs / N
  10. f = np.arange(0, fs, f_bin)
  11. X = [np.fft.fft(np.sin(2 * np.pi * 100 * t)), np.fft.fft(np.sin(2 * np.pi * 200 * t)), np.fft.fft(np.sin(2 * np.pi * 300 * t))]
  12. M = np.absolute(X)
  13. fig, ax = plt.subplots()
  14. im = ax.imshow(M[:,:len(M[0,:]) // 2], cmap=&#39;viridis&#39;, aspect=1)
  15. clb = fig.colorbar(im, ax=ax)
  16. clb.ax.set_title(&quot;Magnitude&quot;)
  17. ax.set_xlabel(f&quot;Index (f[{round(100/f_bin)}] = {f[round(100/f_bin)]} Hz)&quot;)
  18. ax.set_ylabel(&quot;# FFT&quot;)
  19. ax.set_title(f&quot;Built-in FFT&quot;)
  20. plt.show()
  21. which results in
  22. [![enter image description here][2]][2]
  23. Is there a (nice) solution to transform the &quot;Index&quot; into the actual &quot;frequency bin&quot; by using `f_bin` and `f`
  24. [![enter image description here][1]][1]
  25. I hope I haven&#39;t overlooked some already existing solutions in `Stack Overflow`.
  26. [1]: https://i.stack.imgur.com/cM1ck.png
  27. [2]: https://i.stack.imgur.com/ZKsSi.png
  28. </details>
  29. # 答案1
  30. **得分**: 1
  31. 你可以使用`ax.set_xticklabels`为你的xtick标签设置新值:
  32. ```python
  33. import numpy as np
  34. import matplotlib.pyplot as plt
  35. fs = 1000
  36. t = np.arange(0, 0.1, 1/fs)
  37. N = len(t)
  38. f_bin = fs / N
  39. f = np.arange(0, fs, f_bin)
  40. X = [np.fft.fft(np.sin(2 * np.pi * 100 * t)), np.fft.fft(np.sin(2 * np.pi * 200 * t)), np.fft.fft(np.sin(2 * np.pi * 300 * t))]
  41. M = np.absolute(X)
  42. fig, ax = plt.subplots()
  43. im = ax.imshow(M[:,:len(M[0,:]) // 2], cmap='viridis', aspect=1)
  44. clb = fig.colorbar(im, ax=ax)
  45. clb.ax.set_title("Magnitude")
  46. ax.set_xlabel(f"Frequency (kHz)")
  47. ax.set_ylabel("# FFT")
  48. ax.set_title(f"Built-in FFT")
  49. ax.set_xticklabels([x/100 for x in ax.get_xticks()])
  50. plt.show()

输出:

用频率(kHz)替换imshow的x轴索引

英文:

You can set new values for your xtick labels with ax.set_xticklabels:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. fs = 1000
  4. t = np.arange(0, 0.1, 1/fs)
  5. N = len(t)
  6. f_bin = fs / N
  7. f = np.arange(0, fs, f_bin)
  8. X = [np.fft.fft(np.sin(2 * np.pi * 100 * t)), np.fft.fft(np.sin(2 * np.pi * 200 * t)), np.fft.fft(np.sin(2 * np.pi * 300 * t))]
  9. M = np.absolute(X)
  10. fig, ax = plt.subplots()
  11. im = ax.imshow(M[:,:len(M[0,:]) // 2], cmap=&#39;viridis&#39;, aspect=1)
  12. clb = fig.colorbar(im, ax=ax)
  13. clb.ax.set_title(&quot;Magnitude&quot;)
  14. ax.set_xlabel(f&quot;Frequency (kHz)&quot;)
  15. ax.set_ylabel(&quot;# FFT&quot;)
  16. ax.set_title(f&quot;Built-in FFT&quot;)
  17. ax.set_xticklabels([x/100 for x in ax.get_xticks()])
  18. plt.show()

Output:

用频率(kHz)替换imshow的x轴索引

答案2

得分: 1

关于显示类似这样的二维数据并设置坐标轴时,你应该使用 pcolormesh。在这种情况下,你的 x 值由 f/1000 设置,y 值由 M 中的行数枚举(在这种情况下为 3)。假设你仍然想要一个宽图,你可以设置纵横比以实现这一点。我还将 y 刻度更改为只显示 y 值。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. plt.close("all")
  4. fs = 1000
  5. t = np.arange(0, 0.1, 1/fs)
  6. f_bin = fs/len(t)
  7. f = np.arange(0, fs, f_bin)
  8. X = [np.fft.fft(np.sin(2*np.pi*100*t)),
  9. np.fft.fft(np.sin(2*np.pi*200*t)),
  10. np.fft.fft(np.sin(2*np.pi*300*t))]
  11. M = np.absolute(X)
  12. fig, ax = plt.subplots()
  13. s = np.s_[:, :len(M[0, :]) // 2]
  14. x = f
    展开收缩
    ]/1000
  15. y = np.arange(M.shape[0])
  16. p = ax.pcolormesh(x, y, M
    展开收缩
    , cmap="viridis")
  17. fig.colorbar(p, ax=ax, label="Magnitude")
  18. ax.set_yticks(y)
  19. ax.set_aspect(10*y.max()/fs)
  20. ax.set_xlabel("Frequency [kHz]")
  21. ax.set_ylabel("# FFT")
  22. ax.set_title("Built-in FFT")
  23. fig.show()

用频率(kHz)替换imshow的x轴索引

  1. [1]: https://i.stack.imgur.com/yKcGU.png
英文:

When it comes to showing 2D data like this while setting the axes, you should use pcolormesh. In this case, your x values are set by f/1000 and your y values are enumerated by the number of rows in M (in this case: 3). Assuming you still want a fat plot, you can set the aspect ratio to achieve that. I also changed the y-ticks to just be the y values.

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. plt.close(&quot;all&quot;)
  4. fs = 1000
  5. t = np.arange(0, 0.1, 1/fs)
  6. f_bin = fs/len(t)
  7. f = np.arange(0, fs, f_bin)
  8. X = [np.fft.fft(np.sin(2*np.pi*100*t)),
  9. np.fft.fft(np.sin(2*np.pi*200*t)),
  10. np.fft.fft(np.sin(2*np.pi*300*t))]
  11. M = np.absolute(X)
  12. fig, ax = plt.subplots()
  13. s = np.s_[:, :len(M[0, :]) // 2]
  14. x = f
    展开收缩
    ]/1000
  15. y = np.arange(M.shape[0])
  16. p = ax.pcolormesh(x, y, M
    展开收缩
    , cmap=&quot;viridis&quot;)
  17. fig.colorbar(p, ax=ax, label=&quot;Magnitude&quot;)
  18. ax.set_yticks(y)
  19. ax.set_aspect(10*y.max()/fs)
  20. ax.set_xlabel(&quot;Frequency [kHz]&quot;)
  21. ax.set_ylabel(&quot;# FFT&quot;)
  22. ax.set_title(&quot;Built-in FFT&quot;)
  23. fig.show()

用频率(kHz)替换imshow的x轴索引

huangapple
  • 本文由 发表于 2023年8月10日 14:04:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定