2017-01-04 3 views
2

matplotlib.pyplot을 사용하여 두 개의 그림이 있습니다. 하나는 오디오 파일의 파형입니다. 두 번째는 동일한 오디오의 스펙트로 그램입니다. 나는 파형이 스펙트로 그램 바로 위에 있기를 원한다. (같은 x 축은 함께 정렬된다.) 나는 또한 스펙트로 그램을위한 컬러 바를 원한다.matplotlib.pyplot 색상 막대가 파형과 specgram 옆에 두 행으로 펼쳐지도록하십시오.

문제점 - 컬러 바를 끼우면 스펙트로 그램 행에 부착되고 파형이 컬러 바 위로 확장됩니다 (즉, 스펙트로 그램과 더 이상 시간이 맞춰지지 않으며 스펙트로 그램보다 넓습니다).

나는 해결책에 가깝다고 생각하지만, 나는 내가 잘못하고있는 일이나 내가 원하는대로 일하도록 바꾸는 것이 무엇인지 알 수 없다. 누군가가 올바른 방향으로 나를 가리킬 수 있기를 바랍니다! 다음 파이썬 코드를 사용

(I 가능한 MWE으로 코드를 만든) :

import matplotlib 
matplotlib.use("TkAgg") 
from scipy.io import wavfile 
from matplotlib import mlab 
from matplotlib import pyplot as plt 
import numpy as np 
from numpy.lib import stride_tricks 

samplerate, data = wavfile.read('FILENAME.wav') 

times = np.arange(len(data))/float(samplerate) 

plt.close("all") 

#### 
#Waveform 
#### 
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(13.6, 7.68)) 

plt.subplot(211) 
plt.plot(times, data, color='k') 

plt.xlabel('time (s)') 
plt.xlim(times[0], times[-1]) 

max_amp = max(abs(np.amin(data)), abs(np.amax(data))) 
min_amp = (max_amp * -1) - abs(np.amin(data) - np.amax(data))/50 
max_amp = max_amp + abs(np.amin(data) - np.amax(data))/50 

plt.ylim(min_amp, max_amp) 

ax = plt.gca() 
ax.set_yticks(np.array([min_amp, min_amp/2, 0, max_amp/2, max_amp])) 

ax.spines['bottom'].set_position('center') 
ax.spines['right'].set_color('none') 
ax.spines['top'].set_color('none') 

ax.xaxis.set_ticks_position('none') 
ax.yaxis.set_ticks_position('none') 

ax.xaxis.set_tick_params(pad=115) 

#### 
#Spectrogram 
#### 

Fs = 5000*2.#10000. 
NFFT = min(512, len(data)) 
noverlap = NFFT/2 
pad_to = NFFT * 16 
dynamicRange = 27.5 
vmin = 20*np.log10(np.max(data)) - dynamicRange 

cmap = plt.get_cmap('inferno') 

plt.subplot(212) 
Pxx, freqs, times, cax = plt.specgram(data, NFFT=NFFT, Fs=samplerate, noverlap=noverlap, mode='magnitude', scale='dB', vmin=vmin, pad_to=pad_to, cmap=cmap) 

axes_spec = plt.gca() 
axes_spec.set_xlim([0., max(times)]) 
axes_spec.set_ylim([0, 5000]) 

plt.xlabel("Time (s)") 
plt.ylabel("Frequency (hz)") 

plt.colorbar(cax, label='(dB)').ax.yaxis.set_label_position('left') 


plt.tight_layout() 
plt.show() 

나는 다음과 같은 플롯 얻을 수 있습니다 : 아래이 약간의 수정을 만들기

Waveform above spectrogram plus colorbar

을, I 음모를 구할 수 거의 내가 원하는 방법. 문제는 컬러 바 옆에 빈 그림이 생성된다는 것입니다. 빈 그림을 뺀이 버전은 내가 만들고자하는 것입니다. 플롯의

#Replace this for waveform 
plt.subplot(221) 
#Replace this for spectrogram 
plt.subplot(223) 
#Add this before colorbar 
plt.subplot(122) 

새로운 버전 :

Waveform above spectrogram - both next to blank figure plus colorbar

편집 : (! 혹은 둘 다 좋은 측정을위한) 나는 또한에 OK입니다 또 다른 가능성이있다 여기에 Waveform above spectrogram plus colorbar (but waveform/spectrogram are time-aligned)

+0

다음 답변을 보았습니까? http://stackoverflow.com/questions/13784201/matplotlib-2-subplots-1-colorbar –

+0

예. 그렇지만이 상황에 어떻게 적응할 수 있는지 알 수 없습니다. 나는 웹과 질문에서 비슷한 것들을 통합하려는 시도를 많이했지만 스펙트로 그램은 다른 비 스펙트로 그램과 통합하는 방법에 대해 약간 혼란 스럽다. – whatisit

+0

@ pablo-reyes 링크에 대한 답변에서 제공된 방법을 시도하면 [색상 막대가 겹치는 두 개의 그림] (http://imgur.com/a/uT9C3) – whatisit

답변

2

matplotlib-2-subplots-1-colorbar의 답변 중 하나를 기반으로하는 색상 막대의 예입니다. pad (fig.colorbar)은 플롯과 컬러 막대 사이의 공백을 지정하는 데 사용되며 aspect은 컬러 막대의 높이와 너비 간의 종횡비를 지정하는 데 사용됩니다. Specgram은 이미지를 4 번째 출력 매개 변수로 출력하므로 색상 막대에 사용합니다.

fig,axs = matplotlib.pyplot.subplots(ncols=1, nrows=2) 
N=1000; fs=10e3 
x = np.sin(np.arange(N))+np.random.random(N) 
spectrum, freqs, t, im = axs[1].specgram(x,Fs=fs, 
        cmap=matplotlib.cm.inferno,noverlap=255) 
axs[0].plot(np.arange(0,N)/fs,x,'-'); 
axs[0].set_xlim(t[0],t[-1]);axs[1].set_xlim(t[0],t[-1]) 
axcb = fig.colorbar(im, ax=axs.ravel().tolist(), pad=0.04, aspect = 30) 

enter image description here

fig.colorbar 기능이 ax 매개 변수를 사용하여 호출 할 때, 원래의 플롯이 colorbar위한 공간을 만들기 위해 크기가 조정됩니다 통지하는 것이 중요하다

. 플롯 중 하나에만 적용되면 해당 축만 크기가 조절됩니다. SE는 아래 : 아래

fig,axs = matplotlib.pyplot.subplots(ncols=1, nrows=2) 
N=1000; fs=10e3 
x = np.sin(np.arange(N))+np.random.random(N) 
spectrum, freqs, t, im = axs[1].specgram(x,Fs=fs, 
        cmap=matplotlib.cm.inferno,noverlap=255) 
axs[0].plot(np.arange(0,N)/fs,x,'-') 
axs[0].set_xlim(t[0],t[-1]);axs[1].set_xlim(t[0],t[-1]) 
axcb = fig.colorbar(im, ax=axs[1], pad=0.04, aspect = 30) 

enter image description here

은 당신의 원본을 더욱 크기를 조정하지 않습니다 cax 매개 변수 fig.colorbar를 사용하여 년 Colorbar위한 공간을 확보하기 위해 원래의 축 크기 조정을 제어하는 ​​방법을 표시됩니다 줄거리.원래 두 개의 플롯의 좌표를 읽어 두 행에 걸쳐 동일한를

fig,axs = matplotlib.pyplot.subplots(ncols=1, nrows=2) 
N=1000; fs=10e3 
x = np.sin(np.arange(N))+np.random.random(N) 
spectrum, freqs, t, im = axs[1].specgram(x,Fs=fs, 
        cmap=matplotlib.cm.inferno,noverlap=255) 
axs[0].plot(np.arange(0,N)/fs,x,'-') 
axs[0].set_xlim(t[0],t[-1]);axs[1].set_xlim(t[0],t[-1]) 
fig.subplots_adjust(right=0.85) # making some room for cbar 
# getting the lower left (x0,y0) and upper right (x1,y1) corners: 
[[x10,y10],[x11,y11]] = axs[1].get_position().get_points() 
pad = 0.01; width = 0.02 
cbar_ax = fig.add_axes([x11+pad, y10, width, y11-y10]) 
axcb = fig.colorbar(im, cax=cbar_ax) 

enter image description here

그리고 일 :이 방법은 수동 기능 fig.subplots_adjust 내부의 right 매개 변수를 지정하여 년 Colorbar 일부 공간을 확보하기 위해 필요

fig,axs = matplotlib.pyplot.subplots(ncols=1, nrows=2) 
N=1000; fs=10e3 
x = np.sin(np.arange(N))+np.random.random(N) 
spectrum, freqs, t, im = axs[1].specgram(x,Fs=fs, 
        cmap=matplotlib.cm.inferno,noverlap=255) 
axs[0].plot(np.arange(0,N)/fs,x,'-') 
axs[0].set_xlim(t[0],t[-1]);axs[1].set_xlim(t[0],t[-1]) 
fig.subplots_adjust(right=0.85) # making some room for cbar 
# getting the lower left (x0,y0) and upper right (x1,y1) corners: 
[[x00,y00],[x01,y01]] = axs[0].get_position().get_points() 
[[x10,y10],[x11,y11]] = axs[1].get_position().get_points() 
pad = 0.01; width = 0.02 
cbar_ax = fig.add_axes([x11+pad, y10, width, y01-y10]) 
axcb = fig.colorbar(im, cax=cbar_ax) 

enter image description here

+0

링크의 내용과 매우 유사합니다. 생성 된 데이터/랜덤 데이터에 대해서는 훌륭하지만, 이것이 스펙트로 그램의 경우에 쉽게 적용될 수있는 방법을 알지 못합니다. 나는 그것이 적응할 수 있다는 확신을하기 위해'specgram '으로 이것을보아야한다. 나는 또한'matplotlib.GridSpec'을 사용하여 좋은 방법을 찾았습니다. 엄청난 양의 여분의 코드는 아니지만이 대답 이상의 것입니다. 'GridSpec' 메서드는 또한 스펙트로 그램의 측면에서만 풀 컬러 바를 전환 할 수 있습니다. 이 방법으로이 두 가지를 처리 ​​할 수 ​​있는지 정말 관심이 있습니다! – whatisit

+0

'GridSpec'을 사용했습니다. 나는 그런 식으로도 컬러 바를위한 공간을 할당했다. 하지만 이제는 코드 줄이 더 좋아지기 때문에 specgram의 이미지 출력 (처음으로 'specgram'사용자)을 사용하는 솔루션이 있습니다. 지금이 연구에서 사용합니다.나는 사인파 신호도 넣었다. –

+0

그래, 난 분명히 적은 코드에 반대하지 않습니다! 컬러 바의 높이를 스펙트로 그램으로 제한하기 위해 편집 내용을 수정할 수 있습니까? 그렇다면 두 예제를 모두 포함 할 수 있습니까? – whatisit

1

내가 캠 가장 좋은 해결책 전자 최대는 subplot2grid() 기능입니다. 이것은 내가 원래 사용하지 않았던 subplots의 사용을 요구합니다. 이 방법에 따라 plt (matplotlib.pyplot)을 사용하는 것에서부터 각 .plot() 또는 .specgram() 호출에 대해 지정된 플롯의 축을 사용하도록 모든 것을 변경해야했습니다. 관련 변경 사항은 여기에 포함됩니다

#No rows or columns need to be specified, because this is handled within a the `subplot2grid()` details 
fig, axes = plt.subplots(figsize=(13.6, 7.68)) 

#Setup for waveform 
ax1 = plt.subplot2grid((2, 60), (0, 0), rowspan=1, colspan=56) 
####WAVEFORM PLOTTING 

#Setup for spectrogram 
ax2 = plt.subplot2grid((2, 60), (1, 0), rowspan=1, colspan=56) 
####SPECTROGRAM PLOTTING 

#Setup for colorbar 
ax3 = plt.subplot2grid((2, 60), (0, 59), rowspan=1, colspan=1) 
cbar = plt.colorbar(cax, cax=ax3, ax=ax2) 

그리고 MWE는 모두 함께 가져 :

Waveform above spectrogram plus colorbar on right side (of both)

제일 부분 : 여기

import matplotlib as mpl 
mpl.use("TkAgg") 
from scipy.io import wavfile 
from matplotlib import mlab 
from matplotlib import pyplot as plt 
import matplotlib.gridspec as gridspec 
import numpy as np 
from numpy.lib import stride_tricks 

samplerate, data = wavfile.read('FILENAME.wav') 

times = np.arange(len(data))/float(samplerate) 

plt.close("all") 

fig, axes = plt.subplots(figsize=(13.6, 7.68))#nrows=2, ncols=2, 

gs = gridspec.GridSpec(2, 60) 

#### 
#Waveform 
#### 
ax1 = plt.subplot2grid((2, 60), (0, 0), rowspan=1, colspan=56) 
ax1.plot(times, data, color='k') 

ax1.xaxis.set_ticks_position('none') 
ax1.yaxis.set_ticks_position('none') 

#### 
#Spectrogram 
#### 
maxFrequency = 5000 
Fs = maxFrequency*2.#10000. 
NFFT = min(512, len(data)) 
noverlap = NFFT/2 
pad_to = NFFT * 16 
dynamicRange = 27.5 
vmin = 20*np.log10(np.max(data)) - dynamicRange 

cmap = plt.get_cmap('inferno') 

ax2 = plt.subplot2grid((2, 60), (1, 0), rowspan=1, colspan=56) 
Pxx, freqs, times, cax = ax2.specgram(data, NFFT=NFFT, Fs=samplerate, noverlap=noverlap, mode='magnitude', scale='dB', vmin=vmin, pad_to=pad_to, cmap=cmap) 

ax2.set_ylim([0, maxFrequency]) 
ax2.xaxis.set_ticks_position('none') 
ax2.yaxis.set_ticks_position('none') 

#### 
#Colorbar (for spectrogram) 
#### 
ax3 = plt.subplot2grid((2, 60), (1, 59), rowspan=1, colspan=1) 
cbar = plt.colorbar(cax, cax=ax3, ax=ax2) 
cbar.ax.yaxis.set_tick_params(pad=3, left='off', right='off', labelleft='on', labelright='off') 

plt.show() 

이 MWE의 출력의 예 ! 당신은 즉 :
ax3 = plt.subplot2grid((2, 60), (1, 59), rowspan=1, colspan=1) 

는 년 Colorbar 범위 스펙트로 그램의 높이를 만들기 위해 ( 10rowspan이 줄 1로 변경할 필요는 없다. 두 옵션 사이의 변경이 매우 간단하다는 것을 의미합니다. 다음은이 변화의 출력 예는 다음과 같습니다

Waveform above spectrogram plus colorbar on right side (of spectrogram only)

편집 : GridSpec 실제로 사용되지 않는이었고, 그래서 나는 그것을 밖으로 편집했다. 관련된 유일한 세부 사항은 subplot2grid()을 호출하여 서브 플로트를 설정하는 것입니다.

관련 문제