散景:绘制频谱图

时间:2018-06-28 19:40:49

标签: python bokeh

我是Bookeh的新手,我有一项任务是在bokeh中绘制频谱图。

我正在使用https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html 得到光谱图。 在上面的示例中,他们使用matplotlib的pcolormesh()绘制频谱图。如何在bokeh中获得相同(或等效)的频谱图。

我试图通过使用以下代码绘制热图来完成此任务:

    f, t, Sxx = spectrogram(raw_data, fs)
    i=0
    for freq in range(f.shape[0]):
        for time in range(t.shape[0]):
            df_spectogram.loc[i] = [f[freq],t[time],Sxx[freq][time]]
            i = i+1

    TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
    PALETTE = ['#081d58', '#253494', '#225ea8', '#1d91c0', '#41b6c4', '#7fcdbb', '#c7e9b4', '#edf8b1', '#ffffd9']
    mapper = LinearColorMapper(palette=PALETTE, low=numpy.min(Sxx), high=numpy.max(Sxx))
    spectogram_figure = figure(title="Spectogram",x_axis_location="below", plot_width=900, plot_height=400,
               tools=TOOLS)
    spectogram_figure.background_fill_color = "#eaeaea"
    spectrogram_source = ColumnDataSource(data=dict(Sxx=df_spectogram['Sxx'],Frequency=df_spectogram['Frequency'],Time=df_spectogram['Time']))
    spectogram_figure.circle(x="Time", y="Frequency", source=spectrogram_source, fill_color={'field': 'Sxx', 'transform': mapper}, line_color=None)

2 个答案:

答案 0 :(得分:0)

我通过更改使其以所需的方式工作

spectogram_figure.circle(x="Time", y="Frequency", source=spectrogram_source, fill_color={'field': 'Sxx', 'transform': mapper}, line_color=None)

绘制一个宽度等于分段时间和频率高度的矩形。

答案 1 :(得分:0)

这是我的答案,在这里我尝试从scipy复制示例频谱图代码:https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html

Bokeh Spectrogram Screenshot

要先生成matplotlib频谱图,然后生成bokeh频谱图:

from scipy import signal
from scipy.fftpack import fft
from scipy.fftpack import fftshift
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

from bokeh.io import show
from bokeh.models import BasicTicker, ColorBar, LinearColorMapper, PrintfTickFormatter
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource

fs = 10e3
N = 1e5
amp = 2 * np.sqrt(2) 
noise_power = 0.01 * fs / 2
time = np.arange(N) / float(fs)
mod = 500*np.cos(2*np.pi*0.25*time) 
carrier = amp * np.sin(2*np.pi*3e3*time + mod)
noise = np.random.normal(scale=np.sqrt(noise_power), size=time.shape)
noise *= np.exp(-time/5)
x = carrier + noise

f, t, Sxx = signal.spectrogram(x, fs)
df_spectogram = pd.DataFrame(columns = ["Frequency","Time","Sxx"])

time = list(t)
freq = list(f)

df = pd.DataFrame(index = freq ,data = Sxx, columns = time)

plt.pcolormesh(t, f, Sxx)

df = pd.DataFrame(df.stack(), columns=['amp']).reset_index()

plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')

colors = ['#440154', '#404387', '#29788E', '#22A784', '#79D151', '#FDE724']
mapper = LinearColorMapper(palette=colors, low=df.amp.min(), high=df.amp.max())

TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"

p = figure(title="Spectrogram",
           # x_range=time, y_range=freq,
            plot_width=1000, plot_height=600,
           tools=TOOLS, toolbar_location='below',
           tooltips=[('amp', '@amp%')])

p.circle(x="level_1", y="level_0", size=5,
       source=df,
       fill_color={'field': 'amp', 'transform': mapper},
       line_color=None)

show(p)
plt.show()