You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将timestamp设为索引后Matplotlib蜡烛图显示异常,求原因

问题

给定如下DataFrame:

open     close      high       low                        timestamp
0   17910.25  17902.75  17910.50  17901.75 2024-02-28 20:46:10.628867+00:00
1   17902.50  17901.75  17906.50  17900.50 2024-02-28 20:46:50.270189+00:00
2   17902.25  17904.50  17905.50  17901.25 2024-02-28 20:47:55.031114+00:00
3   17904.75  17907.25  17909.00  17904.50 2024-02-28 20:48:44.114794+00:00
4   17907.25  17910.25  17914.50  17906.75 2024-02-28 20:49:31.424009+00:00
5   17910.25  17912.50  17914.50  17906.00 2024-02-28 20:50:05.337921+00:00
6   17912.75  17909.00  17912.75  17906.50 2024-02-28 20:50:51.489718+00:00
7   17909.00  17908.50  17910.50  17905.50 2024-02-28 20:51:32.629298+00:00
8   17908.75  17899.75  17908.75  17899.25 2024-02-28 20:52:06.190489+00:00
9   17899.50  17900.50  17902.00  17897.50 2024-02-28 20:52:38.421629+00:00
10  17900.25  17900.75  17904.25  17898.75 2024-02-28 20:53:22.651748+00:00
11  17900.25  17898.00  17901.25  17895.50 2024-02-28 20:54:07.124026+00:00
12  17898.00  17895.75  17900.75  17892.00 2024-02-28 20:54:36.208693+00:00
13  17895.75  17897.25  17898.00  17893.75 2024-02-28 20:55:00.171311+00:00
14  17897.25  17902.00  17902.00  17895.75 2024-02-28 20:55:09.389301+00:00
15  17902.00  17905.50  17906.75  17901.00 2024-02-28 20:55:30.245781+00:00
16  17905.25  17905.25  17906.50  17900.75 2024-02-28 20:56:03.837146+00:00
17  17905.25  17909.75  17910.75  17904.75 2024-02-28 20:56:26.466095+00:00
18  17909.75  17916.50  17918.25  17908.50 2024-02-28 20:56:47.284619+00:00
19  17916.25  17911.50  17917.25  17911.50 2024-02-28 20:57:16.248157+00:00
20  17911.50  17913.75  17914.50  17909.25 2024-02-28 20:57:56.980558+00:00
21  17913.50  17916.00  17917.25  17910.00 2024-02-28 20:58:32.008823+00:00
22  17916.00  17916.25  17918.75  17913.50 2024-02-28 20:58:59.908276+00:00
23  17916.25  17915.00  17918.25  17915.00 2024-02-28 20:59:16.061040+00:00
24  17915.00  17911.75  17915.25  17910.00 2024-02-28 20:59:27.103036+00:00

使用以下plotCandles函数可正常绘制蜡烛图:

def plotCandles(df):
    #df.set_index('timestamp', inplace=True)
    plt.figure() 

    # "up" dataframe will store the stock_prices 
    # when the closing stock price is greater 
    # than or equal to the opening stock prices 
    up = df[df.close >= df.open] 

    # "down" dataframe will store the stock_prices 
    # when the closing stock price is 
    # lesser than the opening stock prices 
    down = df[df.close < df.open] 

    # When the stock prices have increased, then it 
    # will be represented by green color candlestick 
    col1 = 'green'

    # When the stock prices have decreased, then it 
    # will be represented by red color candlestick 
    col2 = 'red'

    # Setting width of candlestick elements 
    width = .3
    width2 = .03

    # Plotting up prices of the stock 
    plt.bar(up.index, up.close-up.open, width, bottom=up.open, color=col1) 
    plt.bar(up.index, up.high-up.close, width2, bottom=up.close, color=col1) 
    plt.bar(up.index, up.low-up.open, width2, bottom=up.open, color=col1) 

    # Plotting down prices of the stock 
    plt.bar(down.index, down.close-down.open, width, bottom=down.open, color=col2) 
    plt.bar(down.index, down.high-down.open, width2, bottom=down.open, color=col2) 
    plt.bar(down.index, down.low-down.close, width2, bottom=down.close, color=col2) 

    # rotating the x-axis tick labels at 30degree 
    # towards right 
    plt.xticks(rotation=30, ha='right') 

    # show it
    plt.show() 

此时生成的蜡烛图显示正常,但取消注释df.set_index('timestamp', inplace=True)将timestamp设为DataFrame的索引后,Matplotlib生成的蜡烛图显示异常,请问这是什么原因?

原因分析

问题根源在于Matplotlib的plt.bar()对时间类型索引的处理方式:

  • 用默认整数索引时,up.index和down.index是连续的0、1、2...整数,plt.bar()直接把这些整数当x轴坐标,每个K线均匀分布,显示正常。
  • 换成timestamp索引后,索引变成了datetime64类型的时间戳。plt.bar()会把时间戳转成对应的数值(比如从1970年开始的秒数)作为x轴坐标,但你的数据中时间间隔并不均匀(有的间隔40秒,有的55秒),导致K线在x轴上的间距忽大忽小,甚至重叠,自然显示异常。
    另外,plt.xticks()处理时间索引时会自动生成刻度,和手动绘制的K线位置不匹配,进一步让图变得混乱。
解决办法

如果要使用timestamp作为索引并正常绘制蜡烛图,可以做以下调整:

  1. 保留整数位置作为x轴坐标,手动设置x轴刻度为时间戳:
def plotCandles(df):
    df.set_index('timestamp', inplace=True)
    plt.figure() 

    up = df[df.close >= df.open] 
    down = df[df.close < df.open] 

    col1 = 'green'
    col2 = 'red'

    width = .3
    width2 = .03

    # 使用整数位置作为x轴坐标
    x_pos = range(len(df))
    # 为up和down匹配对应的x位置
    up_x = [x_pos[i] for i in df.index.get_indexer(up.index)]
    down_x = [x_pos[i] for i in df.index.get_indexer(down.index)]

    # 绘制上涨K线
    plt.bar(up_x, up.close-up.open, width, bottom=up.open, color=col1) 
    plt.bar(up_x, up.high-up.close, width2, bottom=up.close, color=col1) 
    plt.bar(up_x, up.low-up.open, width2, bottom=up.open, color=col1) 

    # 绘制下跌K线
    plt.bar(down_x, down.close-down.open, width, bottom=down.open, color=col2) 
    plt.bar(down_x, down.high-down.open, width2, bottom=down.open, color=col2) 
    plt.bar(down_x, down.low-down.close, width2, bottom=down.close, color=col2) 

    # 设置x轴刻度为时间戳
    plt.xticks(x_pos, df.index.strftime('%H:%M:%S'), rotation=30, ha='right') 

    plt.show() 
  1. 或者使用专门的金融绘图库(如mplfinance),它原生支持时间索引的蜡烛图绘制,无需手动处理坐标:
import mplfinance as mpf

def plotCandles(df):
    df.set_index('timestamp', inplace=True)
    mpf.plot(df, type='candle', style='yahoo')

内容的提问来源于stack exchange,提问作者Jan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 10:07:02