2010-09-15 65 views

回答

10

你不应该需要任何自定义轴。时间序列Scikit是伟大的,但你并不需要它在所有与matplotlib日期工作...

您可能需要使用的各种功能,matplotlib.datesplot_date绘制你的价值观,imshow(和/或在某些情况下为pcolor)绘制各种类型的谱图,然后matplotlib.mlab.specgram来计算它们。

对于您的次要情节,创建它们时要使用sharex kwarg,以便它们都共享相同的x轴。要在绘图之间共享x轴时禁用某些轴上的x轴标签,您需要使用诸如matplotlib.pyplot.setp(ax1.get_xticklabels(), visible=False)之类的东西。 (这是一个稍微粗糙的黑客攻击,但它是在所有子图之间共享同一个x轴时仅在底部子图上显示x轴标签的唯一方法)要调整子图之间的间距,请参见subplots_adjust

希望所有有一定道理......我会添加使用所有的,当我在今天晚些时候有时间的一个简单的例子...

编辑: 所以这里的一个粗略的例子理念。在你的例子中显示的一些东西(例如多色轴标签)在matplotlib中很难做到。 (不是不​​可能的,但是我在这里跳过他们...)

import datetime 

import numpy as np 
import matplotlib as mpl 
import matplotlib.pyplot as plt 

from matplotlib import mlab 

from mpl_toolkits.axes_grid1 import make_axes_locatable 

def main(): 
    #-- Make a series of dates 
    start = datetime.datetime(2010,9,15,8,0) 
    end = datetime.datetime(2010,9,15,18,0) 
    delta = datetime.timedelta(seconds=1) 

    # Note: "time" is now an array of floats, where 1.0 corresponds 
    # to one day, and 0.0 corresponds to 1900 (I think...) 
    # It's _not_ an array of datetime objects! 
    time = mpl.dates.drange(start, end, delta) 

    num = time.size 

    #-- Generate some data 
    x = brownian_noise(num) 
    y = brownian_noise(num) 
    z = brownian_noise(num) 

    plot(x, y, z, time) 
    plt.show() 

def plot(x, y, z, time): 
    fig = plt.figure() 

    #-- Panel 1 
    ax1 = fig.add_subplot(311) 
    im, cbar = specgram(x, time, ax1, fig) 
    ax1.set_ylabel('X Freq. (Hz)') 
    ax1.set_title('Fake Analysis of Something') 

    #-- Panel 2 
    ax2 = fig.add_subplot(312, sharex=ax1) 
    im, cbar = specgram(y, time, ax2, fig) 
    ax2.set_ylabel('Y Freq. (Hz)') 

    #-- Panel 3 
    ax3 = fig.add_subplot(313, sharex=ax1) 
    # Plot the 3 source datasets 
    xline = ax3.plot_date(time, x, 'r-') 
    yline = ax3.plot_date(time, y, 'b-') 
    zline = ax3.plot_date(time, z, 'g-') 
    ax3.set_ylabel(r'Units $(\mu \phi)$') 

    # Make an invisible spacer... 
    cax = make_legend_axes(ax3) 
    plt.setp(cax, visible=False) 

    # Make a legend 
    ax3.legend((xline, yline, zline), ('X', 'Y', 'Z'), loc='center left', 
      bbox_to_anchor=(1.0, 0.5), frameon=False) 

    # Set the labels to be rotated at 20 deg and aligned left to use less space 
    plt.setp(ax3.get_xticklabels(), rotation=-20, horizontalalignment='left') 

    # Remove space between subplots 
    plt.subplots_adjust(hspace=0.0) 

def specgram(x, time, ax, fig): 
    """Make and plot a log-scaled spectrogram""" 
    dt = np.diff(time)[0] # In days... 
    fs = dt * (3600 * 24) # Samples per second 

    spec_img, freq, _ = mlab.specgram(x, Fs=fs, noverlap=200) 
    t = np.linspace(time.min(), time.max(), spec_img.shape[1]) 

    # Log scaling for amplitude values 
    spec_img = np.log10(spec_img) 

    # Log scaling for frequency values (y-axis) 
    ax.set_yscale('log') 

    # Plot amplitudes 
    im = ax.pcolormesh(t, freq, spec_img) 

    # Add the colorbar in a seperate axis 
    cax = make_legend_axes(ax) 
    cbar = fig.colorbar(im, cax=cax, format=r'$10^{%0.1f}$') 
    cbar.set_label('Amplitude', rotation=-90) 

    ax.set_ylim([freq[1], freq.max()]) 

    # Hide x-axis tick labels 
    plt.setp(ax.get_xticklabels(), visible=False) 

    return im, cbar 

def make_legend_axes(ax): 
    divider = make_axes_locatable(ax) 
    legend_ax = divider.append_axes('right', 0.4, pad=0.2) 
    return legend_ax 

def brownian_noise(num): 
    x = np.random.random(num) - 0.5 
    x = np.cumsum(x) 
    return x 


if __name__ == '__main__': 
    main() 

alt text

+0

谢谢你非常有帮助!我今晚也必须开始寻找。如果示例代码不会太多问,那也会很棒,但已经有很多帮助! – hatmatrix 2010-09-15 18:23:46

+0

OMG这太棒了!很多,非常感谢 - 我很抱歉,我只能赞扬你一次! – hatmatrix 2010-09-16 03:45:42

+0

代码结构与matlab有多不同 - 处理图形是面向对象的,但并非如此。 – hatmatrix 2010-09-16 03:49:09