2016-05-26 2 views
0

У меня есть pyplot диаграмма, которая выглядит немного как это:Конец участка в последней точке данных временных рядов pyplot

The chart in question

Как получить красные и синие линии, чтобы остановить в их последней точке данных (13 мая и 19 мая, соответственно) вместо продолжения горизонтальной линии вправо?

Каждая строка состоит из точек с увеличением значения x в каждый последующий момент времени t. Данные берутся из моментальных снимков в прошлом, поэтому они останавливаются в разное время.

Я пробовал свой лучший google-fu, но на самом деле не нашел ничего полезного, если не вручную рисовать все биты строки.

Вот код, который генерирует таблицу, если она помогает:

import sys 
import json 
from datetime import datetime 
import itertools 
import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 

if __name__ == '__main__': 
    colours = itertools.cycle(['r', 'b', 'g', 'm', 'c', 'y', 'k']) 

    # A bit of faff for clean printing with globbed arguments: 
    filenames = [name.split('.')[0] for name in sys.argv[1:]] 

    fig = plt.figure() 

    axes = plt.axes() 
    axes.set_ylabel('Events') 

    for file in filenames: 
     data = json.loads(open(file + '.json').read())['results']['data'] 

     # Unzip to a tuple of lists ([x], [y]) 
     x, y = zip(*[(datetime.utcfromtimestamp(int(d['t']/1000)), d['x']) for d in data]) 
     axes.plot(x, y, colours.next(), label=file) 

    fig.autofmt_xdate() 
    plt.savefig('plot_{0}.png'.format('_'.join(filenames))) 

ответ

1

Трудно знать, что именно происходит, не имея данных, но в общем то, что вы пытаетесь сделать, должен работать, если вам строят Series, которые имеют индекс datetime.

Рассмотрим:

import pandas as pd 
import matplotlib.pyplot as plt 

a = pd.Series(np.random.rand(10), index=pd.date_range("2016-01-01","2016-10-01",freq="MS")) 
b = pd.Series(np.random.rand(5), index=pd.date_range("2016-01-01","2016-5-01",freq="MS")) 

fig, ax = plt.subplots() 
ax.plot(a) 
ax.plot(b) 

Выход:

enter image description here

Таким образом, для случая использования рассмотреть возможность сделать что-то вроде

axes.plot(pd.Series(y, index=x), colours.next(), label=file) 
+0

Привет, большое спасибо за это. Оказывается, я просто массивный идиот, и источником моих данных было добавление дополнительной точки в конец, которая всегда «сейчас», – Jacob

1

Предположим y были

In [27]: y = np.concatenate([[0,1,4,4,2,3], [4]*3]); y 
Out[27]: array([0, 1, 4, 4, 2, 3, 4, 4, 4]) 

Мы хотели бы, чтобы удалить повторяющиеся 4-е на хвосте y так, что она становится

array([0, 1, 4, 4, 2, 3, 4]) 

Чтобы сделать это, мы могли бы найти, какие значения y не равно последнее значение в y :

In [28]: y != y[-1] 
Out[28]: array([ True, True, False, False, True, True, False, False, False], dtype=bool) 

Найти соответствующий индекс порядкового Истинных значений:

In [29]: np.flatnonzero(y != y[-1]) 
Out[29]: array([0, 1, 4, 5]) 

и принять последнее значение:

In [30]: np.flatnonzero(y != y[-1])[-1] 
Out[30]: 5 

Таким образом, чтобы обрезать повторяющиеся значения из хвостовой части y, мы могли бы использовать

In [31]: y[:np.flatnonzero(y != y[-1])[-1]+2] 
Out[31]: array([0, 1, 4, 4, 2, 3, 4]) 

Таким образом, вы можете использовать

for file in filenames: 
    data = json.loads(open(file + '.json').read())['results']['data'] 

    # Unzip to a tuple of lists ([x], [y]) 
    x, y = zip(*[(datetime.utcfromtimestamp(int(d['t']/1000)), d['x']) for d in data]) 
    y = np.array(y) 
    idx = np.flatnonzero(y != y[-1])[-1]+2 
    axes.plot(x[:idx], y[:idx], colours.next(), label=file) 
Смежные вопросы