линии и строка с датой создают большой прямоугольник в matplotlib - PullRequest
0 голосов
/ 09 сентября 2018

Мне нужно отобразить линии и столбцы в соответствии с датой на одном графике в Python.

Я использую matplotlib и python2.7

Если я создаю строки и строку с индексом вместо даты, это выглядит нормально. Но если я создаю линии и строку с датой в виде индекса x, я вижу только большой прямоугольник.

Вот код

def draw_graph():
    x = [ datetime.datetime.fromtimestamp(time.time()+ i * 100)  for i in range(1,26) ]
    #x = [ i  for i in range(1,26) ]
    ys = [ [12.8, 11.7, 11.0, 10.2, 9.7, 9.2, 8.8, 8.3, 7.9, 7.6, 8.7, 12.0, 13.8, 14.9, 16.0, 16.6, 17.2, 17.9, 18.9, 19.7, 20.3, 20.8, 20.3, 19.9, 19.5],
                [17.2, 16.5, 15.6, 15.1, 14.4, 14.0, 13.6, 13.3, 12.8, 12.5, 13.2, 14.0, 15.7, 17.0, 17.8, 19.0, 19.7, 20.4, 21.3, 22.1, 22.5, 22.8, 22.3, 21.8, 21.4]
                ,[0.0, 1407362982.0, 1376380000.0, 1244750888.0, 1281503386.0, 1345770126.0, 1233699697.0, 1281798998.0, 1204362605.0, 1292156436.0, 1317519540.0, 359873335.0, 481384505.0, 425220178.0, 436946318.0, 357935188.0, 411935743.0, 778855000.0, 569431637.0, 967452677.0, 707153362.0, 784057555.0, 0.0, 0.0, 0.0] ]

    lines=[]
    plt.xlabel('x label')
    fig = plt.figure(1)  # the first figure
    ax=plt.gca()

    index = 0
    for y in ys:
        plt.ylabel('y label')
        plt.title('graph.title')
        if index == len(ys)-1:#last y axis
            print index
            ax2=ax.twinx()
            line = ax2.bar(x, y, color='C' + str(index), alpha=0.5, label='bar')
        else:#all other y axis
            if 1: #time
                ax.format_xdata = matplotlib.dates.DateFormatter('%Y-%m-%d')
                ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%d/%m/%Y %H:%M:%S'))
                line, = ax.plot_date(x, y,'-',label='line1')
                fig.autofmt_xdate()
            else:#index
                line, = ax.plot(x, y, '-',label='line2')
                yloc = plt.MaxNLocator(10)
                ax.yaxis.set_major_locator(yloc)
        index = index + 1
        lines.append(line)

    ax=plt.gca()
    ax.legend(lines, [l.get_label() for l in lines])
    plt.show()

if __name__=='__main__':
    draw_graph()

Вот гистограмма и график с датой в виде оси x

big rectangle instead of bars

Здесь тот же код, использующий индекс вместо даты в качестве оси x

bar and lines with index

1 Ответ

0 голосов
/ 09 сентября 2018

Похоже, есть две проблемы.

  • Слишком широкие полосы. Ширина полосы по умолчанию составляет 1. В случае с датами это один день. Однако ваши точки данных только 100 секунд. Следовательно, вы хотели бы сделать ширину стержня похожей на расстояние между двумя точками данных. В этом случае, например,

    ax.bar(x, y, width=1./24/60., ...)
    
  • Форматер не применяется. Из-за использования сдвоенных осей необходимо применять форматтер после рисования на осях. То есть линия

    ax.xaxis.set_major_formatter(...)
    

    должен идти после цикла.

В целом это может выглядеть как

import datetime, time
import matplotlib.pyplot as plt
import matplotlib.dates

def draw_graph():
    x = [ datetime.datetime.fromtimestamp(time.time()+ i * 100)  for i in range(1,26) ]
    print x
    #x = [ i  for i in range(1,26) ]
    ys = [ [12.8, 11.7, 11.0, 10.2, 9.7, 9.2, 8.8, 8.3, 7.9, 7.6, 8.7, 12.0, 13.8, 14.9, 16.0, 16.6, 17.2, 17.9, 18.9, 19.7, 20.3, 20.8, 20.3, 19.9, 19.5],
                [17.2, 16.5, 15.6, 15.1, 14.4, 14.0, 13.6, 13.3, 12.8, 12.5, 13.2, 14.0, 15.7, 17.0, 17.8, 19.0, 19.7, 20.4, 21.3, 22.1, 22.5, 22.8, 22.3, 21.8, 21.4]
                ,[0.0, 1407362982.0, 1376380000.0, 1244750888.0, 1281503386.0, 1345770126.0, 1233699697.0, 1281798998.0, 1204362605.0, 1292156436.0, 1317519540.0, 359873335.0, 481384505.0, 425220178.0, 436946318.0, 357935188.0, 411935743.0, 778855000.0, 569431637.0, 967452677.0, 707153362.0, 784057555.0, 0.0, 0.0, 0.0] ]

    lines=[]

    fig, ax = plt.subplots()
    ax.set_xlabel('x label')
    ax2=ax.twinx()
    index = 0

    for y in ys:
        plt.ylabel('y label')
        plt.title('graph.title')
        if index == len(ys)-1: #last y axis
            line = ax2.bar(x, y, color='C' + str(index),  width=1./24/60., alpha=0.5, label='bar')
        else: #all other y axis
            line, = ax.plot(x, y,'-',label='line1')
            ax.format_xdata = matplotlib.dates.DateFormatter('%Y-%m-%d')

        index = index + 1
        lines.append(line)
    ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%d/%m/%Y %H:%M:%S'))
    fig.autofmt_xdate()

    ax.legend(lines, [l.get_label() for l in lines])
    plt.show()

if __name__=='__main__':
    draw_graph()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...