python matplotlib烛台图表

时间:2015-10-06 07:04:44

标签: python matplotlib

我在制作星期15分钟的烛台图表时遇到问题。我从谷歌下载并解析数据并将其本地保存到csv文件。我解析数据并将其加载到变量,具有以下顺序浮动日期,打开,高,低,关闭,音量。当我使用历史日常数据时,一切正常,但是当我尝试使用日期和时间x轴时,它会变得混乱。以下是我使用的示例数据:

  

2015-10-05 16:30:00,196.47,196.48,196.43,196.46,438838,0 2015-10-05   16:45:00,196.46,197.08,196.33,196.95,2835287,0 2015-10-05   17:00:00,196.95,197.38,196.92,197.32,1732829,0 2015-10-05   17:15:00,197.32,197.53,196.95,197.44,1988081,0 2015-10-05   17:30:00,197.46,197.59,197.29,197.42,1226381,0 2015-10-05   17:45:00,197.425,197.48,196.9,196.93,1101573,0 2015-10-05   18:00:00,196.93,197.23,196.84,197.15,646694,0 2015-10-05   18:15:00,197.16,197.51,197.11,197.45,623662,0 2015-10-05   18:30:00,197.45,197.46,197.18,197.26,684113,0 2015-10-05   18:45:00,197.255,197.42,197.1,197.14,764368,0 2015-10-05   19:00:00,197.14,197.48,197.13,197.46,476307,0 2015-10-05   19:15:00,197.46,197.67,197.4,197.54,758593,0 2015-10-05   19:30:00,197.55,197.77,197.44,197.58,929402,0 2015-10-05   19:45:00,197.605,197.73,197.565,197.71,493741,0 2015-10-05   20:00:00,197.73,197.84,197.5,197.6,542889,0 2015-10-05   20:15:00,197.61,197.91,197.49,197.84,535851,0 2015-10-05   20:30:00,197.85,198.08,197.85,197.95,629089,0 2015-10-05   20:45:00,197.95,198.03,197.84,197.9,465000,0 2015-10-05   21:00:00,197.895,198.16,197.895,198.08,658012,0 2015-10-05   21:15:00,198.095,198.2,197.98,198.11,643964,0 2015-10-05   21:30:00,198.115,198.48,198.09,198.47,1311870,0 2015-10-05   21:45:00,198.47,198.68,198.47,198.54,1414104,0 2015-10-05   22:00:00,198.53,198.54,198.31,198.43,885886,0 2015-10-05   22:15:00,198.43,198.68,198.36,198.46,1541751,0 2015-10-05   22:30:00,198.465,198.51,198.275,198.44,861833,0 2015-10-05   22:45:00,198.44,198.74,198.295,198.32,1847980,0 2015-10-05   23:00:00,198.31,198.65,198.31,198.46,2884656,0

以下是解析文件并返回准备好的数组以创建图表的代码:

def get_local_intraday_db(self, symbol, seconds_period, period = (None, None)):
    data = None

    if os.path.isfile(FILE_GENERATOR_INTRADAY.format(DB_PATH, symbol, seconds_period)):
        saved_data = open(FILE_GENERATOR_INTRADAY.format(DB_PATH, symbol, seconds_period), 'r')
        data = saved_data.read().split('\n')

        ohlcv_data = []
        date_data = []
        open_data = []
        high_data = []
        low_data = []
        close_data = []
        volume_data = []

        for line in data:
            splitted_line = line.split(',')

            datetime_to_float = mdates.date2num(datetime.datetime.strptime(splitted_line[0], '%Y-%m-%d %H:%M:%S'))
            date_data.append(datetime_to_float)

            open_to_float = float(splitted_line[1])
            open_data.append(open_to_float)

            high_to_float = float(splitted_line[2])
            high_data.append(high_to_float)

            low_to_float = float(splitted_line[3])
            low_data.append(low_to_float)

            close_to_float = float(splitted_line[4])
            close_data.append(close_to_float)

            volume_to_float = float(splitted_line[5])
            volume_data.append(volume_to_float)

            ohlcv_data.append((datetime_to_float, open_to_float, high_to_float, low_to_float, close_to_float, volume_to_float))

        if period == (None, None):
            return ( ohlcv_data, np.array(date_data), np.array(open_data), np.array(high_data), np.array(low_data), np.array(close_data), np.array(volume_data) )
        else:
            try:
                range_start = mdates.date2num(period[0])
                range_start_index = date_data.index(range_start)
                range_end = mdates.date2num(period[1])
                range_end_index = date_data.index(range_end)

                if range_start_index >= 0 and range_end_index >= 0:
                    print '{}: Selected range starts from {} to {}.'.format(datetime.datetime.now(), period[0], period[1])
                    return ( ohlcv_data[range_start_index : range_end_index], np.array(date_data[range_start_index : range_end_index]), np.array(open_data[range_start_index : range_end_index]), np.array(high_data[range_start_index : range_end_index]), np.array(low_data[range_start_index : range_end_index]), np.array(close_data[range_start_index : range_end_index]), np.array(volume_data[range_start_index : range_end_index]) )
                else:
                    print '{}: Selected data range is invalid!'.format(datetime.datetime.now())
            except:
                print 'No source provider data for {}.'.format(symbol)
                return ( None, None, None, None, None, None, None )
    else:
        print '{}: No data exists for {}!'.format(datetime.datetime.now(), symbol)

以下是创建图表的代码:

def create_chart_intraday(self, symbol, ohlcv_data, date_data, open_data, high_data, low_data, close_data, volume_data):
    if ohlcv_data == None:
        return
    _start = datetime.datetime.now()       
    fig = plt.figure(facecolor = 'white')
    fig.set_size_inches(18., 10.)
    fig.text(0.5, 0.75, symbol, fontsize = 40, color = 'black', ha = 'center', va = 'center', alpha = 0.1)

    xmin = date_data[0]
    xmax = date_data[len(date_data) - 1]
    #Candlestick chart
    ax1 = plt.subplot2grid((12, 6), (0, 0), rowspan = 6, colspan = 6, axisbg = 'white')
    ax1.grid(True, color = 'black')
    ax1.axes.xaxis.set_ticklabels([])
    ax1.axes.get_xaxis().set_visible(False)
    ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S'))
    ax1.yaxis.label.set_color('black')
    ax1.spines['bottom'].set_color('black')
    ax1.spines['top'].set_color('black')
    ax1.spines['left'].set_color('black')
    ax1.spines['right'].set_color('black')
    ax1.tick_params(axis = 'y', colors = 'black')
    ax1.set_xlim(xmin, xmax)

    plt.ylabel('Price & Volume')
    candlestick_ohlc(ax1, ohlcv_data, colorup = 'purple', colordown = 'red')        
    ax1.plot(date_data, open_data, 'blue', linewidth = 0.5)
    ax1.plot(date_data, high_data, 'green', linewidth = 0.5)
    ax1.plot(date_data, low_data, 'red', linewidth = 0.5)
    ax1.plot(date_data, close_data, 'yellow', linewidth = 0.5)
    plt.show()

    _end = datetime.datetime.now()
    print 'Chart generated in {}'.format(str(_end - _start))

    fig.savefig('{}{}.png'.format(PNG_PATH, symbol), facecolor = fig.get_facecolor())

enter image description here

您可以看到存在问题。我已经制作了标记开放,高,低,接近的线条,但蜡烛的主体填充不是它必须的位置。紫色/红色应该填充蜡烛的主体,但实际上它们在其他地方。有人可以帮我解决这个问题吗?提前致谢

1 个答案:

答案 0 :(得分:0)

I rewrote your code in python3 and it probably works as it should, though I can't tell what exactly fixed the problem. My guess is - the new data extraction function, but I can't tell for sure. Here is my code (should also work in python2):

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.finance import *
import datetime

def get_data_simple():
    ohlcv_data = []

    data = open('test1') # Path to file with sample data

    for line in data:
        splitted_line = line.split(',')

        ohlcv = [(datetime.datetime.now() - datetime.datetime.strptime(splitted_line[0], '%Y-%m-%d %H:%M:%S')).total_seconds()]

        for elem in splitted_line[1:]:
            ohlcv.append(float(elem))

        ohlcv_data.append(ohlcv)

    return ohlcv_data

def create_chart_intraday(ohlcv_data):
    ax1 = plt.subplot2grid((12, 6), (0, 0), rowspan = 6, colspan = 6, axisbg = 'white')
    candlestick_ohlc(ax1, ohlcv_data, colorup = 'purple', colordown = 'red')
    plt.show()

create_chart_intraday(get_data_simple())

There are no titles or additional plots, but it works. My result