2016-02-15 7 views
7

Ich versuche, einem Spektrogramm eine Farbleiste hinzuzufügen. Ich habe jedes Beispiel und Frage Thread, die ich online gefunden habe, versucht und keiner hat dieses Problem gelöstHinzufügen von Farbbalken zu einem Spektrogramm

Beachten Sie, dass "spl1" (Datenspleiß 1) eine Ablaufverfolgung von ObsPy ist.

Mein Code ist:

fig = plt.figure() 
ax1 = fig.add_axes([0.1, 0.75, 0.7, 0.2]) #[left bottom width height] 
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.60], sharex=ax1) 
ax3 = fig.add_axes([0.83, 0.1, 0.03, 0.6]) 

t = np.arange(spl1[0].stats.npts)/spl1[0].stats.sampling_rate 
ax1.plot(t, spl1[0].data, 'k') 

ax,spec = spectrogram(spl1[0].data,spl1[0].stats.sampling_rate, show=False, axes=ax2) 
ax2.set_ylim(0.1, 15) 
fig.colorbar(spec, cax=ax3) 

Es kommt mit dem Fehler aus:

Traceback (most recent call last): 

    File "<ipython-input-18-61226ccd2d85>", line 14, in <module> 
    ax,spec = spectrogram(spl1[0].data,spl1[0].stats.sampling_rate, show=False, axes=ax2) 

TypeError: 'Axes' object is not iterable 

bisher bestes Ergebnis:

Ersetzen der letzten 3 Zeilen weiter oben mit:

ax = spectrogram(spl1[0].data,spl1[0].stats.sampling_rate, show=False, axes=ax2) 
ax2.set_ylim(0.1, 15) 
fig.colorbar(ax,cax=ax3) 

produziert diese: Waveform and spectrogram plot

und diesen Fehler für die colorbar:

axes object has no attribute 'autoscale_None' 

Ich habe keine Möglichkeit, in der Lage sein scheinen zu finden, die colorbar auf dem rechten Flügel an die Arbeit.

Lösungen?

Eine der Lösungen, die ich gesehen habe, ist, dass Sie ein 'Bild' Ihrer Daten mit imshow() erstellen müssen, aber ich bekomme keine Ausgabe von Spectrogram(), nur 'ax'. Ich habe Orte gesehen, die mit dem "ax, spec" -Ausgang von spectrogram() versuchen, aber das verursacht den TypeError.

gegeben

Ich hoffe, dass jemand dabei helfen kann - ich habe den ganzen Tag daran gearbeitet!

+3

Haben Sie erfolgreich ein Spektrogramm ohne colorbar aufgetragen? Was ist die "Spektrogramm" -Funktion (aus welcher Bibliothek), die Sie verwenden? – gsmafra

+1

@gsmafra Ich habe den Beitrag oben mit mehr Informationen aktualisiert - Ich kann das Spektrogramm zur Darstellung normalerweise ja bekommen. Die Spektrogramm-Funktion ist: obspy.imaging.spectrogram.spectrogram (wie es einfachere eingebaute Funktionalität hat) - obwohl darunter verwendet wird – mjp

+1

laufenden Diskussion in: https://github.com/obspy/obspy/issues/1086 welche hat ein erfolgreiches Farbbalken-Diagramm. Funktioniert nicht für meine Situation, aber wenn dort eine Lösung gefunden wird, werde ich auch hier die Lösung hinzufügen. – mjp

Antwort

3

es wurde gelöst, mit Hilfe von this link.Es zeigt nicht Dezibel noch nicht, aber das Hauptproblem war immer das colorbar:

from obspy.imaging.spectrogram import spectrogram 
fig = plt.figure() 
ax1 = fig.add_axes([0.1, 0.75, 0.7, 0.2]) #[left bottom width height] 
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.60], sharex=ax1) 
ax3 = fig.add_axes([0.83, 0.1, 0.03, 0.6]) 

#make time vector 
t = np.arange(spl1[0].stats.npts)/spl1[0].stats.sampling_rate 

#plot waveform (top subfigure)  
ax1.plot(t, spl1[0].data, 'k') 

#plot spectrogram (bottom subfigure) 
spl2 = spl1[0] 
fig = spl2.spectrogram(show=False, axes=ax2) 
mappable = ax2.images[0] 
plt.colorbar(mappable=mappable, cax=ax3) 

produced figure

0

Ich nehme an, Sie verwenden matplotlib.pyplot. Es hat starke Aufrufe für Farbe in Form von matplotlib.pyplot.plot(x-cordinates , y-co-ordinates, color)

Eine Beispielimplementierung ist wie folgt.

"""Plots 
Time in MS Vs Amplitude in DB of a input wav signal 
""" 

import numpy 
import matplotlib.pyplot as plt 
import pylab 
from scipy.io import wavfile 
from scipy.fftpack import fft 


myAudio = "audio.wav" 

#Read file and get sampling freq [ usually 44100 Hz ] and sound object 
samplingFreq, mySound = wavfile.read(myAudio) 

#Check if wave file is 16bit or 32 bit. 24bit is not supported 
mySoundDataType = mySound.dtype 

#We can convert our sound array to floating point values ranging from -1 to 1 as follows 

mySound = mySound/(2.**15) 

#Check sample points and sound channel for duel channel(5060, 2) or (5060,) for mono channel 

mySoundShape = mySound.shape 
samplePoints = float(mySound.shape[0]) 

#Get duration of sound file 
signalDuration = mySound.shape[0]/samplingFreq 

#If two channels, then select only one channel 
mySoundOneChannel = mySound[:,0] 

#Plotting the tone 

# We can represent sound by plotting the pressure values against time axis. 
#Create an array of sample point in one dimension 
timeArray = numpy.arange(0, samplePoints, 1) 

# 
timeArray = timeArray/samplingFreq 

#Scale to milliSeconds 
timeArray = timeArray * 1000 

#Plot the tone 
plt.plot(timeArray, mySoundOneChannel, color='G') 
plt.xlabel('Time (ms)') 
plt.ylabel('Amplitude') 
plt.show() 


#Plot frequency content 
#We can get frquency from amplitude and time using FFT , Fast Fourier Transform algorithm 

#Get length of mySound object array 
mySoundLength = len(mySound) 

#Take the Fourier transformation on given sample point 
#fftArray = fft(mySound) 
fftArray = fft(mySoundOneChannel) 

numUniquePoints = numpy.ceil((mySoundLength + 1)/2.0) 
fftArray = fftArray[0:numUniquePoints] 

#FFT contains both magnitude and phase and given in complex numbers in real + imaginary parts (a + ib) format. 
#By taking absolute value , we get only real part 

fftArray = abs(fftArray) 

#Scale the fft array by length of sample points so that magnitude does not depend on 
#the length of the signal or on its sampling frequency 

fftArray = fftArray/float(mySoundLength) 

#FFT has both positive and negative information. Square to get positive only 
fftArray = fftArray **2 

#Multiply by two (research why?) 
#Odd NFFT excludes Nyquist point 
if mySoundLength % 2 > 0: #we've got odd number of points in fft 
    fftArray[1:len(fftArray)] = fftArray[1:len(fftArray)] * 2 

else: #We've got even number of points in fft 
    fftArray[1:len(fftArray) -1] = fftArray[1:len(fftArray) -1] * 2 

freqArray = numpy.arange(0, numUniquePoints, 1.0) * (samplingFreq/mySoundLength); 

#Plot the frequency 
plt.plot(freqArray/1000, 10 * numpy.log10 (fftArray), color='B') 
plt.xlabel('Frequency (Khz)') 
plt.ylabel('Power (dB)') 
plt.show() 

#Get List of element in frequency array 
#print freqArray.dtype.type 
freqArrayLength = len(freqArray) 
print "freqArrayLength =", freqArrayLength 
numpy.savetxt("freqData.txt", freqArray, fmt='%6.2f') 

#Print FFtarray information 
print "fftArray length =", len(fftArray) 
numpy.savetxt("fftData.txt", fftArray) 

enter image description here enter image description here

+0

Hey, es tut mir leid, ich glaube nicht, dass du die Frage verstanden hast. Ich kann die Farbe von Liniendiagrammen usw. ändern, aber ich möchte einem Spektrogramm eine Farbleiste hinzufügen (wie in einer Z-Achsen-Farbleiste, die den Wertebereich in Bezug auf Farben angibt) – mjp

Verwandte Themen