Python, Matplotlib, subplot: Как установить диапазон оси?
Как я могу установить диапазон оси Y второго субплота, например, на [0,1000]? График БПФ моих данных (столбец в текстовом файле) приводит к (инф.?) Всплеску, так что фактические данные не видны.
pylab.ylim([0,1000])
не имеет никакого эффекта, к сожалению. Это весь сценарий:
# 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()
Другие улучшения также приветствуются!
6 ответов
Как найдено в http://www.mofeel.net/582-comp-soft-sys-matlab/54166.aspx
pylab.ylim([0,1000])
Примечание: команда должна быть выполнена после сюжета!
Использование объектов осей является отличным подходом для этого. Это помогает, если вы хотите взаимодействовать с несколькими фигурами и вспомогательными участками. Для непосредственного добавления и управления объектами осей:
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()
Иногда вы действительно хотите установить пределы осей, прежде чем строить данные. В этом случае вы можете установить функцию "автоматического масштабирования" Axes
или же AxesSubplot
объект. Интересующие функции set_autoscale_on
, set_autoscalex_on
, а также set_autoscaley_on
,
В вашем случае вы хотите заморозить пределы оси y, но позволить оси x расширяться для размещения ваших данных. Поэтому вы хотите изменить autoscaley_on
собственность на False
, Вот измененная версия фрагмента FFT-подпункта из вашего кода:
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))
Также возможно установитьylim
/xlim
во время добавления подграфика к существующему экземпляру фигуры (plt.subplot
признаетylim=
аргумент).
import numpy as np
import matplotlib.pyplot as plt
xs = np.arange(1000) # sample data
rawsignal = np.random.rand(1000)
fft = np.fft.fft(rawsignal)
plt.figure(figsize=(9,6)) # create figure
plt.subplots_adjust(hspace=0.4)
plt.subplot(2, 1, 1, title='Signal') # first subplot
plt.plot(xs, rawsignal)
plt.subplot(2, 1, 2, title='FFT', ylim=(0,100)) # second subplot
# ^^^^^ <---- set ylim here
plt.plot(abs(fft));
Опять же, использование объектно-ориентированного интерфейса менее многословно и более понятно. Экземпляры осей определяютset()
метод, который можно использовать для установки целого ряда свойств, включая y-limit/title и т. д.
fig, (ax1, ax2) = plt.subplots(2, figsize=(9,6))
ax1.plot(xs, rawsignal) # plot rawsignal in the first Axes
ax1.set(title='Signal') # set the title of the first Axes
ax2.plot(abs(fft)) # plot FFT in the second Axes
ax2.set(ylim=(0, 100), title='FFT'); # set title and y-limit of the second Axes
Оба набора кодов выдают один и тот же следующий результат.
Если у вас есть несколько подзаговоров, т.е.
fig, ax = plt.subplots(4, 2)
Вы можете использовать одни и те же пределы y для всех из них. Он получает пределы оси y из первого графика.
plt.setp(ax, ylim=ax[0,0].get_ylim())
Если вы знаете точную ось, которую хотите, тогда
pylab.ylim([0,1000])
работает, как указано ранее. Но если вы хотите, чтобы более гибкая ось соответствовала вашим точным данным, как я сделал, когда нашел этот вопрос, установите предел оси, равный длине вашего набора данных. Если ваш набор данныхfft
как в вопросе, затем добавьте это после команды сюжета:
length = (len(fft))
pylab.ylim([0,length])