【问题标题】:Optimization of matplotlib stem plotmatplotlib 茎图的优化
【发布时间】:2018-06-26 07:55:32
【问题描述】:

我正在尝试使用“matplotlib.pyplot.stem”函数生成一个 Stem 图。该代码有效,但处理时间超过 5 分钟。

我在 Matlab 中有一个类似的代码,几乎可以立即用相同的输入数据生成相同的绘图。

有没有办法优化此代码以提高速度或我可以使用的更好的功能?

茎图“H”和“plotdata”的参数是 16384 x 1 数组。

def stemplot():

    import numpy as np
    from scipy.fftpack import fft
    import matplotlib.pyplot as plt

    ################################################
    # Code to set up the plot data

    N=2048
    dr = 100

    k = np.arange(0,N)

    cos = np.cos
    pi = np.pi

    w = 1-1.932617*cos(2*pi*k/(N-1))+1.286133*cos(4*pi*k/(N-1))-0.387695*cos(6*pi*k/(N-1))+0.0322227*cos(8*pi*k/(N-1))

    y = np.concatenate([w, np.zeros((7*N))])

    H = abs(fft(y, axis = 0))
    H = np.fft.fftshift(H)
    H = H/max(H)
    H = 20*np.log10(H)
    H = dr+H 
    H[H < 0] = 0        # Set all negative values in dr+H to 0

    plotdata = ((np.arange(1,(8*N)+1,1))-1-4*N)/8
    #################################################

    # Plotting Code

    plt.figure
    plt.stem(plotdata,H,markerfmt = " ")

    plt.axis([(-4*N)/8, (4*N)/8, 0, dr])    
    plt.grid()
    plt.ylabel('decibels')
    plt.xlabel('DFT bins')
    plt.title('Frequency response (Flat top)')
    plt.show()


    return

这里也是matlab代码供参考:

N=2048;
dr = 100;
k=0:N-1

w = 1 - 1.932617*cos(2*pi*k/(N-1)) + 1.286133*cos(4*pi*k/(N-1)) -0.387695*cos(6*pi*k/(N-1)) +0.0322227*cos(8*pi*k/(N-1));

H = abs(fft([w zeros(1,7*N)]));
H = fftshift(H);
H = H/max(H);
H = 20*log10(H);
H = max(0,dr+H); % Sets negative numbers in dr+H to 0


figure
stem(([1:(8*N)]-1-4*N)/8,H,'-');
set(findobj('Type','line'),'Marker','none','Color',[.871 .49 0])
xlim([-4*N 4*N]/8)
ylim([0 dr])
set(gca,'YTickLabel','-100|-90|-80|-70|-60|-50|-40|-30|-20|-10|0')
grid on
ylabel('decibels')
xlabel('DFT bins')
title('Frequency response (Flat top)')

【问题讨论】:

  • 你能把它设为minimal reproducible example 吗?在不知道您的w 是什么的情况下,无法运行此代码。
  • 另外,return 是一个语句,而不是一个函数。后面不需要()
  • 在这种特殊情况下根本不需要它;-)
  • 看看thisthis github 问题。这似乎是一个已知问题。
  • 我可以重复第二期中的一个cmets:16384分,你确定你想要一个茎图吗?

标签: python matlab matplotlib optimization plot


【解决方案1】:

您可以使用ax.vlines 以您想要的格式模拟一个茎图。写一个小函数,

def make_stem(ax, x, y, **kwargs):
    ax.axhline(x[0],x[-1],0, color='r')

    ax.vlines(x, 0, y, color='b')

    ax.set_ylim([1.05*y.min(), 1.05*y.max()])

然后将示例中的相关行更改如下:

    # Plotting Code

##    plt.figure
##    plt.stem(plotdata,H,markerfmt = " ")

##    plt.axis([(-4*N)/8, (4*N)/8, 0, dr])

    fig, ax = plt.subplots()
    make_stem(ax, plotdata, H)

或多或少会立即产生情节。但是,我不知道这是否比@ImportanceOfBeingErnest 的答案更快或更慢。

【讨论】:

  • 下面my answer的解决方案需要0.25秒,而这个解决方案在我的电脑上需要0.23秒。差别不大,但显然还是快了一点。
  • @Thomas 感谢您的回复,我测试了这段代码,它的运行速度与上述代码一样快,任何一种方法都适用。
  • @StevenGoddard 然后您就可以轻松地拥有两个工作解决方案了。你可以选择你更喜欢的accept
【解决方案2】:

这里似乎不需要stem 图,因为标记无论如何都是不可见的,并且由于点数很多而没有意义。

使用 LineCollection 可能更有意义。无论如何,这是how matplotlib will do it in a future version - 请参阅this PR。下面的代码对我来说在 0.25 秒内运行。 (这仍然比使用plot 稍长,因为行数较多。)

import numpy as np
from scipy.fftpack import fft
import matplotlib.pyplot as plt
import time
import matplotlib.collections as mcoll

N=2048
k = np.arange(0,N)
dr = 100

cos = np.cos
pi = np.pi

w = 1-1.932617*cos(2*pi*k/(N-1))+1.286133*cos(4*pi*k/(N-1))-0.387695*cos(6*pi*k/(N-1))+0.0322227*cos(8*pi*k/(N-1))

y = np.concatenate([w, np.zeros((7*N))])

H = abs(fft(y, axis = 0))
H = np.fft.fftshift(H)
H = H/max(H)
H = 20*np.log10(H)
H = dr+H 
H[H < 0] = 0        # Set all negative values in dr+H to 0

plotdata = ((np.arange(1,(8*N)+1,1))-1-4*N)/8


lines = []
for thisx, thisy in zip(plotdata,H):
    lines.append(((thisx, 0), (thisx, thisy)))
stemlines = mcoll.LineCollection(lines, linestyles="-",
                    colors="C0", label='_nolegend_')
plt.gca().add_collection(stemlines)


plt.axis([(-4*N)/8, (4*N)/8, 0, dr])    
plt.grid()
plt.ylabel('decibels')
plt.xlabel('DFT bins')
plt.title('Frequency response (Flat top)')

plt.show()

【讨论】:

  • 你又打败了我 :) 我有一个使用 vlines 的解决方案,速度也非常快。
  • @Thomas 如果您的解决方案使用 LineCollection 以外的其他东西,并且如果它明显快于问题的 5 秒,为什么不在这里发布呢?
  • 完成。不过,我不知道更快。
  • 感谢您的回复,代码比 .stem 方法好很多!我想最初我只是想直接翻译 matlab 代码,在这种情况下直接比较并不是最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 2014-10-14
相关资源
最近更新 更多