复制链接
克隆策略

Pandas DataFrame数据可视化:基于Highcharts的可交互图表

In [12]:
help(T.plot)
Help on function plot in module biglearning.api.tools:

plot(df: pandas.core.frame.DataFrame, output: Literal['object', 'json', 'script', 'display'] = 'display', stock: bool = None, double_precision: int = 4, title: Union[str, NoneType] = None, chart_type: Literal[None, 'line', 'spline', 'area', 'areaspline', 'column', 'bar', 'pie', 'scatter', 'gauge', 'arearange', 'areasplinerange'] = None, x: Union[str, NoneType] = None, y: Union[str, NoneType] = None, candlestick: bool = False, panes: List[List[str]] = None, options: Any = None, do_compress: bool = False, marker_enabled: bool = False, height: Union[int, NoneType] = None)
        绘制DataFrame数据到可交互的图表,支持多种图表格式
    
        用highcharts/HighStock实现DataFrame的多种方式的可交互的可视化
    
        :param DataFrame|Series|dict df: 输入数据,一般是DataFrame类型,索引对应x轴,数据列用作y轴数据;如果不为DataFrame,数据将直接传给Highcharts,可参考Highcharts文档
        :param boolean stock: 是否使用Highstock。默认为None,会根据df.index类型来判断,如果为时间类型,则使用Highstock,否则使用Highcharts
        :param 字符串 title: 标题,也可以通过 options={'title': {'text': 'Your Title Here'}} 设置
        :param 字符串 chart_type: 图表类型,也可以通过 options={'chart': {'type': 'column'}} 设置,支持所有 `Highcharts图表类型 <http://www.highcharts.com/docs/chart-and-series-types/chart-types>`_
        :param 字符串 x: x轴对应的列,默认为None,表示使用index
        :param 字符串数组 y: y轴数据列,默认为None,表示使用所有数据列
        :param 浮点数 double_precision: 浮点数输出精度,默认为4,表示4位小数
        :param dict|function options: 图表设置,dict或者回调函数 (参数 df_options,为df转化后的highcharts输入对象),参考Highcharts文档
        :param boolean candlestick: 是否绘制蜡烛图,需要输入数据有 open、high、low、close四列
        :param 二维字符串数组 panes: 分栏显示,[['col1', 'col2'], ['col3', 'col4', '50%'], ..]
    
    示例代码
    --------------
    `Pandas DataFrame数据图表可视化 <https://community.bigquant.com/t/Pandas-DataFrame%E6%95%B0%E6%8D%AE%E5%9B%BE%E8%A1%A8%E5%8F%AF%E8%A7%86%E5%8C%96/46>`_

In [13]:
# 样例数据准备

# 以 平安银行 (000001.SZA) 的股票数据为例
df = DataSource('bar1d_CN_STOCK_A').read('000001.SZA', start_date='2015-01-01', end_date='2017-02-01',
                    fields=['open', 'high', 'low', 'close', 'adjust_factor', 'amount'])

# 日收益
df['return_1'] = df['close'] / df['close'].shift(1) - 1
# 5日收益
df['return_5'] = df['close'] / df['close'].shift(5) - 1

# # 历史数据默认为后复权价格,除以 adjust_factor 得到实际价格
# df['open'] /= df['adjust_factor']
# df['high'] /= df['adjust_factor']
# df['low'] /= df['adjust_factor']
# df['close'] /= df['adjust_factor']

# 设置 date 为index,index将被用作x轴
df.set_index('date', inplace=True)
# 设置index的名字为None,在x轴将不显示x轴数据的名字
df.index.name = None
In [14]:
df.tail()
Out[14]:
open instrument low adjust_factor close amount high return_1 return_5
2017-01-20 960.633179 000001.SZA 960.633179 104.758255 965.871094 361865155.0 966.918701 0.004357 0.006550
2017-01-23 965.871094 000001.SZA 963.775940 104.758255 965.871094 388019072.0 970.061401 0.000000 0.008753
2017-01-24 966.918701 000001.SZA 963.775940 104.758255 971.109009 434787729.0 972.156616 0.005423 0.013115
2017-01-25 971.109009 000001.SZA 969.013855 104.758255 970.061401 281976294.0 972.156616 -0.001079 0.009815
2017-01-26 971.109009 000001.SZA 970.061401 104.758255 977.394470 391844286.0 978.442078 0.007559 0.016340

基础折线

In [15]:
# 显示股票收盘价
T.plot(df[['close']], title='收盘价', chart_type='line')

柱状图

In [16]:
T.plot(df[['amount']], title='成交额', chart_type='column')

面积图

In [17]:
T.plot(df[['low', 'high']], title='最高最低价格', chart_type='area', stock=False)

分栏显示

In [18]:
T.plot(df[['open', 'high', 'low', 'close', 'return_1', 'return_5']],
       # high、low显示在第一栏,高度40%,open、close显示在第二栏,其他的在最后一栏
       panes=[['high', 'low', '40%'], ['open', 'close', '40%']],
       # height=500,设置高度为500
       options={'chart':{'height': 500}})

蜡烛图

In [19]:
T.plot(df[['open', 'high', 'low', 'close', 'amount']],
       # 设置图表title和高度;'series': [{},{'type': 'column'}] 设置第二个数据系列(即 amount)显示类型为柱状图(column)
       options={'chart': {'title': '股票数据分析','height': 600}, 'series': [{'color': 'green','lineColor': 'green','upColor': 'red','upLineColor': 'red'},{'type': 'column'}]},
       stock=True, candlestick=True)

实现分栏显示

用options参数来自己实现分栏显示

In [20]:
# 参考 文档 http://api.highcharts.com/highstock/yAxis
y_axis = [
    {
        'labels': {'align': 'right', 'x': -3 },
        'title': {'text': '价格'},
        'height': '50%', 'lineWidth': 2
    },
    {
        'labels': {'align': 'right','x': -3},
        'title': {'text': '日收益'},
        'top': '55%', 'height': '25%', 'offset': 0, 'lineWidth': 2
    },
    {
        'labels': {'align': 'right', 'x': -3},
        'title': {'text': '交易额'},
        'top': '85%', 'height': '25%', 'offset': 0, 'lineWidth': 2,
    }
]
# series:只覆盖我们需要修改的字段,这里是 yAxis
options = {
    'chart': {'type': 'spline', 'height': 500},
    'title': {'text': '股票数据分析'},
    'yAxis': y_axis,
    'series': [{},{'yAxis': 1},{'yAxis': 2, 'type': 'column'}]
}

T.plot(df[['close', 'return_1', 'amount']], options=options, stock=True)

画出k线及均线

In [21]:
def candlestick_processor(df_options):
    # df_options:为df转化后的数据
#     print(df_options)
    # 蜡烛图

    # 生成ohlc:从series中读取OHLC数据(前四列)合并
    ohlc_series = {}
    sma_series={}
    other_series = []
    series = df_options['series']
    for s in series:
        if s['name'] in {'open', 'high', 'low', 'close'}:
            ohlc_series[s['name']] = s
        elif s['name'] in {'sma_10'}:
            sma_series[s['name']]=s
        else:
            other_series.append(s)
    if len(ohlc_series) != 4:
        print('【错误】蜡烛图,没有找到open, high, low, close数据,请确保输入的数据有这四列')
        return None

    ohlc_data = []
    for i in range(0, len(ohlc_series['open']['data'])):
        row = [ohlc_series['open']['data'][i][0]]
        for j in ['open', 'high', 'low', 'close']:
            row.append(ohlc_series[j]['data'][i][1])
        ohlc_data.append(row)
    
    sma_data=[]
    for i in range(0,len(sma_series['sma_10']['data'])):
        xrow = [sma_series['sma_10']['data'][i][0]]
        for j in ['sma_10']:
            xrow.append(sma_series[j]['data'][i][1])
        sma_data.append(xrow)
    df_options['series'] = [{'data': ohlc_data, 'name': 'OHLC', 'yAxis': 0, 'type': 'candlestick','color': 'green','lineColor': 'green','upColor': 'red','upLineColor': 'red'},
                           {'data':sma_data,'name':'sma_10','yAxis':0,'type':'spline',}] + other_series
    df_options['chart'] = {'height': 800}
    if other_series:
        #  设置其他数据使用第二个y轴
        for s in other_series:
            s.update({'yAxis':1, 'type': 'column'})
        
        y_axis = [
            {
                'labels': {'align': 'right', 'x': -3},
                'title': {'text': 'OHLC'},
                'height': '60%', 'lineWidth': 2
            },
            {
                'labels': {'align': 'right', 'x': -3},
                'top': '65%', 'height': '35%', 'offset': 0, 'lineWidth': 2,
            }
        ]
        
       

       
        df_options = T.deep_update(df_options, {'yAxis': y_axis})

    return df_options

df['sma_10'] = talib.SMA(np.array(df['close'].astype('double')), 10)
T.plot(df[['open', 'high', 'low', 'close','amount','sma_10']], options=candlestick_processor, title='股票数据分析', stock=True)

查看生成的数据

In [22]:
# output可取值 object / display,默认为display,表示直接显示。object对应highchart/highstock的输入数据,用于高级需求自定义。
T.plot(df[['close']].head(3), title='收盘价', chart_type='line', output='object')
Out[22]:
{'chart': {'height': 400, 'type': 'line'},
 'legend': {'enabled': True},
 'title': {'text': '收盘价'},
 'stock': True,
 'series': [{'name': 'close',
   'yAxis': 0,
   'data': [(Timestamp('2015-01-05 00:00:00'), 1138.2802734375),
    (Timestamp('2015-01-06 00:00:00'), 1121.227294921875),
    (Timestamp('2015-01-07 00:00:00'), 1099.9112548828125)],
   'marker': {'enabled': False}}],
 'xAxis': {'type': 'datetime'}}

画出双y轴

In [23]:
df = DataSource('bar1d_CN_STOCK_A').read(instruments=['000002.SZA'], start_date='2021-01-01', fields=['close', 'volume'])
df = df[['close','date','volume']].set_index('date')

options = {
             
             'yAxis': [
                 
                 { 
                 'title': {
                     'text': '收盘价',
                     'style': {
                         'color': '#4572A7'
                     }
                 },
                 'labels': {
                   
                     'style': {
                         'color': '#4572A7'
                     }
                 },
                 'opposite': True,
                     
                      
             },
                 
                 {  
                 'labels': {
                   
                     'style': {
                         'color': '#89A54E',
                         'fontSize': '12px'
                     }
                 },
                 'title': {
                     'text': '成交量',
                     'style': {
                         'color': '#89A54E',
                         'fontSize': '12px'
                     }
                 },
                      'opposite': False,
                     
             }
             
             ],
    
    
    
    'series': [ {
                 'name': 'close',
                 'color': '#89A54E',
                 'type': 'spline',
                 'yAxis': 0,
                 
             },
           {
                 'name': 'volume',
                 'color': '#4572A7',
                 'type': 'column',
                 'yAxis': 1,
 
             },
    ]

    
    
    
}

T.plot(df, options=options)
In [ ]: