前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

荔枝 | 作者

Crossin的编程教室 | 来源

1. 需求

做股票分析的朋友经常会见到类似这种的期货公司持仓榜单图:

这种图就是棒棒糖图。也就是我们今天文章的目标:

绘制出期货持仓榜单的棒棒糖图

图中线的两端是圆点或者菱形,旁边都有标注持仓证券商和相对应的持多仓数或持空仓数,且左右线颜色不同。画图思路大体就是:先画水平线图,再用 scatter 散点图画线左右两端的点,然后标注两端名称,以及标题和注解。

Python 中比较常用的两种图表库是 matplotlib 和 plotly。上图就是以 matplotlib 绘制。而 Plotly 交互性更好。

更进一步,如果想让用户可以点击选择交易日期,查看该日期对应的榜单图,这就可以通过一个响应式 web 应用程序来实现。Dash 是一个基于 python 的交互式可视化 web 应用框架,matplotlib 和 Plotly 都可与 Dash 框架结合使用。

Matplotlib 大家比较熟悉。在开始之前,我们先简单介绍下 plotly 和 Dash。

2. Plotly

plotly 库(plotly.py)是一个交互式的开源绘图库,支持40多种独特的图表类型,涵盖各种统计,财务,地理,科学和三维用例,是适用于Python,R 和 JavaScript 的交互式图表库。

plotly.py 建立在 Plotly JavaScript 库(plotly.js)之上,使Python用户可以创建基于 Web 的漂亮交互式可视化效果。这些可视化效果可以显示在 Jupyter 笔记本中,可以保存到独立的 HTML 文件中,也可以作为纯 Python 使用。其官方文档上提供了各种图标的接口说明。

3. Dash

Dash 是用于构建 Web 应用程序的 Python 框架。Dash 建立在 Flask、Plotly.js 和 React.js 基础之上,即 Dash 中的控件和其触发事件都是用 React.js 包装的,Plotly.js 为 Dash 提供强大的交互式数据可视化图库,Flask 为其提供后端框架。这个框架对 python 程序员特别友好,只需要写 python 代码,不需要写 JS 代码,直接拖拽控件来用即可。感兴趣的童鞋可以去 Dash 的官方文档多多了解一下。Dash 是使用纯 Python 构建高度自定义用户界面的数据可视化应用程序的理想选择。它特别适合做数据分析、数据可视化以及仪表盘或者报告展示。可以将 Dash 应用程序部署到服务器,然后通过 URL 共享它们,不受平台和环境的限制。

4. 安装

在画图之前,我们需要装一下 Dash、plotly 相关包。可以用 pip 装:

pip install plotly dash

或者也可以用 conda 进行安装。

5. 数据格式和数据处理

测试数据来自东方财富网,用 csv 文件格式保存。

数据的格式如下,header 是日期为第一列,第3列往后为期货公司名字。表格中的负数是上面图中蓝色的空仓,正数是红色的多仓。绘图时,从表格中取出某一日期的一行记录,将持仓数目排序,把对应的数据存入列表中,之后进行画图。

首先对数据进行清洗和处理, pandas读取数据,这里需要去除 000905_SH 列,以及删除全0行。代码如下:

excel_pd = pd.read_excel('data/IC期货商历史数据(1).xlsx', index_col='日期')#去空

excel_pd.dropna()#去除000905_SH列

excel_pd = excel_pd.drop(labels='000905_SH', axis=1)#去0行

excel_pd = excel_pd[~(excel_pd == 0).all(axis=1)]#取出时间列表,获取最大日期和最小日期,为日历选项做判断

date_list =excel_pd.index.values.tolist()

min_date=min(date_list)

max_date= max(date_list)

接下来我们需要根据输入的日期来筛选某一行记录,分别将持空仓期货公司和持多仓期货公司取出,剔除持仓数为0的期货公司。代码如下:

defget_data_via_date_from_excel(date):#筛选日期

sheet1_data =excel_pd.loc[date]#去除列值为0

sheet1_data = sheet1_data[sheet1_data !=0]#排序 从小到大

sheet1_data =sheet1_data.sort_values()#空仓

short_hold = sheet1_data[sheet1_data <0]#多仓

long_hold = sheet1_data[sheet1_data >= 0].sort_values(ascending=False)return short_hold, long_hold

6. 画图

Matplotlib画图

创建一张画布figure和ax画图层,用ax.hlines分别画空仓水平线和多仓水平线。用ax.scatter画左右两边线的散点,使用菱形marker。使用plt.text分别画线两端的标注期货公司和持仓数。plt.annotate画排名标注,分别设置颜色和字体大小。

但这个效果是反的,我们是希望排名最前面的在上,排名最后面的下。这时我们可以设置y轴反置一下ax.invert_yaxis()。添加图例和标题以及设置坐标轴不可见,得到最终效果:

核心代码如下:

defdraw_lollipop_graph(short_hold, long_hold, date):#sheet_major.index.values.tolist()

fig, ax = plt.subplots(figsize=(10, 8))#空仓水平线

ax.hlines(y=[i for i in range(len(short_hold))], xmin=list(short_hold), xmax=[0] * len(short_hold.index), color='#1a68cc', label='空')#多仓水平线

ax.hlines(y=[i for i in range(len(long_hold))], xmax=list(long_hold), xmin=[0] * len(long_hold.index), color='red', label='多')#画散点

ax.scatter(x=list(short_hold), y=[i for i in range(len(short_hold))], s=10, marker='d', edgecolors="#1a68cc", zorder=2, color='white') #zorder设置该点覆盖线

ax.scatter(x=list(long_hold), y=[i for i in range(len(long_hold))], s=10, marker='d', edgecolors="red", zorder=2, color='white') #zorder设置该点覆盖线

#画线两端标注图

for x, y, label inzip(list(short_hold), range(len(short_hold)), short_hold.index):

plt.text(x=x, y=y, s=label+'({})'.format(abs(x)), horizontalalignment='right', verticalalignment='center', fontsize=10)for x, y, label inzip(list(long_hold), range(len(long_hold)), long_hold.index):

plt.text(x=x, y=y, s=' '+label+'({})'.format(abs(x)), horizontalalignment='left', verticalalignment='center', fontsize=10)#设置排名

size = [17, 16, 15] + [8 for i in range(max(len(short_hold), len(long_hold))-3)]

color= ['#b91818', '#e26012', '#dd9f10'] + ['#404040' for i in range(max(len(short_hold), len(long_hold))-3)]for i, s, c in zip(range(max(len(short_hold), len(long_hold))+1), size, color):

plt.annotate(s=i+1, xy=(0, i), fontsize=s, ma='center', ha='center', color=c)#坐标轴y反置

ax.invert_yaxis()#坐标轴不可见

ax.set_xticks([])

ax.set_yticks([])

ax.spines['top'].set_visible(False) #去上边框

ax.spines['bottom'].set_visible(False) #去下边框

ax.spines['left'].set_visible(False) #去左边框

ax.spines['right'].set_visible(False) #去右边框

#设置title

ax.set_title('黄金持仓龙虎榜单({})'.format(date), position=(0.7, 1.07), fontdict=dict(fontsize=20, color='black'))#自动获取ax图例句柄及其标签

handles, labels =ax.get_legend_handles_labels()

plt.legend(handles=handles, ncol=2, bbox_to_anchor=(0.75, 1.05), labels=labels, edgecolor='white', fontsize=10)#保存fig

image_filename = "lollipop_rank.png"plt.savefig(image_filename)

encoded_image= base64.b64encode(open(image_filename, 'rb').read())#plt.show()

return encoded_image

PS:如有需要Python学习资料的小伙伴可以加下方的群去找免费管理员领取

可以免费领取源码、项目实战视频、PDF文件等

绘制棒棒糖用python_Python数据可视化:绘制持仓榜单的“棒棒糖图” - 松鼠爱吃饼干...相关推荐

  1. plt数据图去边框 python3_Python数据可视化:绘制持仓榜单的“棒棒糖图”

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 荔枝 | 作者 Crossin的编程教室 | 来源 1. 需求 做股票分析 ...

  2. Python数据可视化:绘制持仓榜单的“棒棒糖图”

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 荔枝 | 作者 Crossin的编程教室 | 来源 1. 需求 做股票分析 ...

  3. [数据可视化]绘制持仓榜单的“棒棒糖图”

    1. 需求 做股票分析的朋友经常会见到类似这种的期货公司持仓榜单图: 这种图就是棒棒糖图.也就是我们今天文章的目标: 绘制出期货持仓榜单的棒棒糖图 图中线的两端是圆点或者菱形,旁边都有标注持仓证券商和 ...

  4. 蜡烛图plotly_Python数据可视化:如何用mplfinance创建蜡烛图

    Python数据可视化:如何用mplfinance创建蜡烛图 Python数据可视化:如何用mplfinance创建蜡烛图 一图胜千言,使用Python的matplotlib库,可以快速创建高质量的图 ...

  5. 数据可视化分析之新技能——魔数图

    数据可视化分析之新技能--魔数图 大家在使用数据可视化工具进行数据设计的时候,有没有遇到过这些设计场景:部门人员的履历细信息.工厂各个产线的生产状态和生产信息.公司各个部门的KPI信息--这些数据都有 ...

  6. 用Python+matplotlib足球运动员的射门数据可视化(绘制散点图)

    射门数据的可视化,本质上就是散点图,只是点的大小按期望进球值(预测进球概率)变化,提高了直观性和可视性. 一.https://understat.com联赛数据网 足球运动员的射门数据来自https: ...

  7. Python pyecharts地理数据可视化 绘制地理图表

    很喜欢的一句话 为什么有些人明明看起来友善 却总是喜欢独来独往 " 待人友善是修养,独来独往是性格 " 文章目录 一.Pyecharts简介和安装 1. 简介 2. 安装 二.绘制 ...

  8. 数据可视化——绘制3D图表和绘制地图

    一.使用mplot3d绘制3D图表 1.1.mplot3d概述 matplotlib不仅专注于二维图表的绘制,也具有绘制3D图表.统计地图的功能,并将这些功能分别封装到工具包mpl_toolkits. ...

  9. Python数据可视化 Matplotlib详解(一) —— 折线图与时序数据绘制

    目录 本小节内容 基础代码 实例讲解 如何多图绘制 多行多列的情况 多行单列的情况 Matplotlib 绘制时序数据 多时序变量绘图 如何给数据添加注释 Reference 本小节内容 今天这一小节 ...

最新文章

  1. 异构云:另一个烫手的山芋
  2. 关于mysql的“+0”操作
  3. 【CyberSecurityLearning 53】信息收集
  4. DPDK精准测量时间
  5. Android之提示Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed
  6. python程序的name的作用是什么_python 中__name__ = '__main__' 的作用,到底干嘛的?
  7. 文献阅读 - Genome-wide consequences of deleting any single gene
  8. FPGA实现CAN接口(SJA1000)
  9. Using SharePoint 2003 Web Services to Retrieve Data From A List
  10. 让你的 Node.js 应用跑得更快的 10 个技巧
  11. Android不同版本下Notification创建方法
  12. 【bat批处理脚本命令】bat命令接收用户输入的内容(保姆级图文+实现代码)
  13. sql:删除重复数据并且只保留id最小的一条
  14. ascll码表 ASCALL码表
  15. Spring中的@DependsOn注解
  16. 什么是Windows安全模式?Windows安全模式详解
  17. 服务器上的VGA切换原理,什么是VGA接口 原理及特点是什么
  18. 东方财富股吧评论爬虫和情绪分析
  19. 6-1 另类循环队列 (30 分) 如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。请编写算法实现队列的入队和出队操作。
  20. 我做出一个决定!(2-3nian后时间来证明对错!)

热门文章

  1. 数字信号处理①之信号的合成、分解、相关性及傅里叶系数的计算
  2. 日常生活中总结出来的DIY生活小窍门
  3. cview怎么close_6.应用程序的退出
  4. react-native-router-flux 使用详解(一)
  5. 一个仿时钟自定义View例子
  6. Oracle单值函数,数据库对日期的操作,日期的转换
  7. 软件测试 | 概念篇
  8. 从 7天(北京首都师范大学店) 到 新中央电视台(大裤衩儿)
  9. python 语音输入
  10. 57支团队突出重围!第四届开发者大赛成果重磅发布