Python, Matplotlib, podplot: Jak ustawić zakres osi?


266

Jak mogę ustawić zakres osi y drugiego wykresu podrzędnego na np. [0,1000]? Wykres moich danych FFT (kolumna w pliku tekstowym) powoduje skok (inf.?), Dzięki czemu rzeczywiste dane nie są widoczne.

pylab.ylim([0,1000])

niestety nie działa. Oto cały skrypt:

# based on http://www.swharden.com/blog/2009-01-21-signal-filtering-with-python/
import numpy, scipy, pylab, random

xs = []
rawsignal = []
with open("test.dat", 'r') as f:
      for line in f:
            if line[0] != '#' and len(line) > 0:
                xs.append( int( line.split()[0] ) )
                rawsignal.append( int( line.split()[1] ) )

h, w = 3, 1
pylab.figure(figsize=(12,9))
pylab.subplots_adjust(hspace=.7)

pylab.subplot(h,w,1)
pylab.title("Signal")
pylab.plot(xs,rawsignal)

pylab.subplot(h,w,2)
pylab.title("FFT")
fft = scipy.fft(rawsignal)
#~ pylab.axis([None,None,0,1000])
pylab.ylim([0,1000])
pylab.plot(abs(fft))

pylab.savefig("SIG.png",dpi=200)
pylab.show()

Inne ulepszenia są również mile widziane!


Odpowiedzi:



112

Używanie obiektów osi jest do tego świetnym podejściem. Pomaga, jeśli chcesz wchodzić w interakcje z wieloma postaciami i wątkami. Aby bezpośrednio dodawać obiekty osi i nimi manipulować:

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(12,9))

signal_axes = fig.add_subplot(211)
signal_axes.plot(xs,rawsignal)

fft_axes = fig.add_subplot(212)
fft_axes.set_title("FFT")
fft_axes.set_autoscaley_on(False)
fft_axes.set_ylim([0,1000])
fft = scipy.fft(rawsignal)
fft_axes.plot(abs(fft))

plt.show()

2
Jak sugeruje Rob, interfejs OO w matplotlib jest lepszy niż oparty na stanie interfejs pylab. „Chociaż wiele przykładów używa pylab, nie jest już dłużej zalecane. W przypadku drukowania nieinteraktywnego zaleca się stosowanie pyplot do tworzenia figur, a następnie interfejsu OO do drukowania”. matplotlib.org/faq/…
Bennett Brown

26

Czasami naprawdę chcesz ustawić limity osi przed wykreśleniem danych. W takim przypadku możesz ustawić funkcję „automatycznego skalowania” obiektu Axeslub AxesSubplot. Funkcje interesujące są set_autoscale_on, set_autoscalex_oni set_autoscaley_on.

W twoim przypadku chcesz zamrozić granice osi y, ale pozwól osi x rozwinąć się, aby pomieścić twoje dane. Dlatego chcesz zmienić autoscaley_onwłaściwość na False. Oto zmodyfikowana wersja fragmentu podplotu FFT z Twojego kodu:

fft_axes = pylab.subplot(h,w,2)
pylab.title("FFT")
fft = scipy.fft(rawsignal)
pylab.ylim([0,1000])
fft_axes.set_autoscaley_on(False)
pylab.plot(abs(fft))

0

Jeśli znasz dokładną oś, którą chcesz, to

pylab.ylim([0,1000])

działa zgodnie z wcześniejszą odpowiedzią. Ale jeśli chcesz, aby bardziej elastyczna oś pasowała do twoich dokładnych danych, tak jak to zrobiłem, kiedy znalazłem to pytanie, ustaw limit osi jako długość zestawu danych. Jeśli zestaw danych jest taki fftjak w pytaniu, dodaj go po poleceniu wydruku:

length = (len(fft)) pylab.ylim([0,length])


0

Jeśli masz wiele wątków, tj

fig, ax = plt.subplots(4, 2)

Możesz użyć tych samych limitów y dla wszystkich z nich. Z pierwszego wykresu pobiera granice osi.

plt.setp(ax, ylim=ax[0,0].get_ylim())
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.