2017-07-28 68 views
2

我正在尋找關於我的圖表問題的幫助。使用熊貓進行matplotlib格式化的問題

我想繪製包含在日期和小時數據框中的財務數據作爲索引,但是,matplotlib標準日期格式不會在這裏執行這個技巧,因爲我不想在x軸上均勻傳播刻度,因爲它顯示了工作時間之間的大橫線。

我想出的解決方案是簡單地在x軸上使用np.arange繪製此圖,並將索引用作x軸上的標籤,因此不使用matplotlib日期格式,但仍顯示日期在我的圖表上。

我的代碼如下:

L = np.arange(len(DAX_M15.index)) 

def format_date(x, pos=None): 
    return DAX_M15.index[x].strftime("%Y-%m-%d %H-%M-%S") 

fig, ax = plt.subplots() 
ax.plot(L, DAX_M15["Open"]) 
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date)) 
ax.set_title("Custom tick formatter") 
fig.autofmt_xdate() 

不過,我得到的時候使用下面的錯誤是:

File "D:\Anaconda\lib\site-packages\matplotlib\backends\backend_qt5agg.py", line 197, in __draw_idle_agg 
    FigureCanvasAgg.draw(self) 
    File "D:\Anaconda\lib\site-packages\matplotlib\backends\backend_agg.py", line 464, in draw 
    self.figure.draw(self.renderer) 
    File "D:\Anaconda\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "D:\Anaconda\lib\site-packages\matplotlib\figure.py", line 1144, in draw 
    renderer, self, dsu, self.suppressComposite) 
    File "D:\Anaconda\lib\site-packages\matplotlib\image.py", line 139, in _draw_list_compositing_images 
    a.draw(renderer) 
    File "D:\Anaconda\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "D:\Anaconda\lib\site-packages\matplotlib\axes\_base.py", line 2426, in draw 
    mimage._draw_list_compositing_images(renderer, self, dsu) 
    File "D:\Anaconda\lib\site-packages\matplotlib\image.py", line 139, in _draw_list_compositing_images 
    a.draw(renderer) 
    File "D:\Anaconda\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "D:\Anaconda\lib\site-packages\matplotlib\axis.py", line 1136, in draw 
    ticks_to_draw = self._update_ticks(renderer) 
    File "D:\Anaconda\lib\site-packages\matplotlib\axis.py", line 969, in _update_ticks 
    tick_tups = [t for t in self.iter_ticks()] 
    File "D:\Anaconda\lib\site-packages\matplotlib\axis.py", line 969, in <listcomp> 
    tick_tups = [t for t in self.iter_ticks()] 
    File "D:\Anaconda\lib\site-packages\matplotlib\axis.py", line 916, in iter_ticks 
    for i, val in enumerate(majorLocs)] 
    File "D:\Anaconda\lib\site-packages\matplotlib\axis.py", line 916, in <listcomp> 
    for i, val in enumerate(majorLocs)] 
    File "D:\Anaconda\lib\site-packages\matplotlib\ticker.py", line 386, in __call__ 
    return self.func(x, pos) 
    File "D:/Finance python/test_data_formatter.py", line 40, in format_date 
    return DAX_M15.index[x].strftime("%Y-%m-%d %H-%M-%S") 
    File "D:\Anaconda\lib\site-packages\pandas\tseries\base.py", line 247, in __getitem__ 
    raise ValueError 
ValueError 

會有人對這個問題提出一個想法在這裏,如何解決呢?

謝謝。

+0

假設matplotlib希望把蜱在'4.5'在軸上的值。然後你的代碼會嘗試索引索引爲'DAX_M15.index [4.5]'。這會引發錯誤,因爲浮點索引未定義。類似的,如果勾號位於負值或高於列表長度的值。您可以嘗試在'format_date'函數中排除這些情況;但我不確定這是否是你想要的。 – ImportanceOfBeingErnest

+0

謝謝你的回答,我現在明白了這個問題。 我試過在函數中使用最接近的整數,但是它引發了一個超出界限的問題。 有什麼辦法強制matplotlib在我的數據的限制內使用整數索引而不修改我的函數? – Erlinska

回答

1

正如評論所說,問題在於列表或序列的索引需要是介於0和列表長度之間的整數。像DAX_M15.index[4.5]這樣的東西將不起作用。

爲了確保只有那些與它們相關聯的數據點的位置被勾選,您可以使用matplotlib.ticker.IndexLocator。例如。如果你想標記列表的每一個第五點,

ax.xaxis.set_major_locator(ticker.IndexLocator(5,0)) 
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date)) 

格式化您還需要進行內部確認指數是一個整數,並允許值的範圍之內。

def format_date(x, pos=None): 
    if int(x) >= len(df.index) or int(x) < 0: return "" 
    return df.index[int(x)].strftime("%Y-%m-%d %H-%M-%S") 

一個完整的例子:

import matplotlib.pyplot as plt 
import matplotlib.ticker as ticker 
import numpy as np 
import pandas as pd 

inx = pd.DatetimeIndex(start="2017-05-05", freq="7H", periods=45) 
df = pd.DataFrame({"open" : np.random.rand(len(inx))}, index=inx) 


L = np.arange(len(df.index)) 

def format_date(x, pos=None): 
    return df.index[int(x)].strftime("%Y-%m-%d %H-%M-%S") 

fig, ax = plt.subplots() 
ax.plot(L, df["open"]) 
ax.xaxis.set_major_locator(ticker.IndexLocator(5,0)) 
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date)) 
ax.set_title("Custom tick formatter") 
fig.autofmt_xdate() 

plt.show() 

enter image description here

+0

非常感謝你,它完美地工作,最重要的是我認爲我明白matplotlib代碼現在是如何工作的。 – Erlinska