2017-07-28 71 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