条件格式图-A股热门行业历年收益

  • 日期:2020-08-20
  • 作者:周嘉楠
In [1]:
from WindPy import *  # 导入 API 接口
w.start()
import pandas as pd
from datetime import datetime # 导入处理时间的 python 库
from datetime import timedelta

# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
Welcome to use Wind Quant API for Python (WindPy)!

COPYRIGHT (C) 2020 WIND INFORMATION CO., LTD. ALL RIGHTS RESERVED.
IN NO CIRCUMSTANCE SHALL WIND BE RESPONSIBLE FOR ANY DAMAGES OR LOSSES CAUSED BY USING WIND QUANT API FOR Python.

step1:获取数据

  • 标的:指数 -> 股票指数 -> 申万指数 > 申银万国一级行业指数;
  • 指标:涨跌幅pct_chg,取得是年度涨跌幅数据。
In [3]:
startdate =  "2005-01-01"
enddate = (datetime.now() - timedelta(1)).strftime('%Y-%m-%d')  #以当前时刻的前一天为结束时间

# 调用Wind API调取行业数据
error,data = w.wsd("801780.SI,801120.SI,801010.SI,801050.SI,801150.SI,801180.SI,801740.SI,801750.SI,801760.SI,801770.SI,801790.SI", "pct_chg", startdate, enddate, "Period=Y", usedf=True)
assert error==0, 'WSD 未成功提取数据,ErrorCode={},含义为{}'.format(error, data.values)

# 重命名表格
data.columns = ['银行','食品饮料','农林牧渔','有色金属','医药生物','房地产','国防军工','计算机','传媒','通信','非银行金融']
data.index = [str(i.year) for i in data.index]
data
Out[3]:
银行 食品饮料 农林牧渔 有色金属 医药生物 房地产 国防军工 计算机 传媒 通信 非银行金融
2005 20.900913 6.309423 -15.058033 -8.318162 -12.338827 -3.801084 10.905819 -17.750595 -13.493868 -10.042795 -17.315659
2006 173.652007 171.033582 82.536258 144.067593 67.233028 153.424777 139.441800 65.728711 69.501948 72.801432 299.023046
2007 96.048750 124.760687 162.069735 262.550166 186.146694 165.268308 235.702991 144.527157 111.725609 122.686240 179.503840
2008 -63.978785 -58.697378 -46.510952 -77.297139 -43.351671 -64.128739 -72.012462 -53.542646 -57.064563 -53.077343 -68.435948
2009 103.755621 109.871720 91.159745 180.026137 102.785216 116.370953 130.902577 104.405247 77.096725 78.297749 103.839038
2010 -22.501760 20.812582 21.063801 22.099797 29.687860 -24.160550 18.380416 26.435488 -2.719672 -9.767735 -24.889308
2011 -4.848533 -10.374885 -31.175082 -41.808174 -30.885791 -22.000652 -33.093791 -34.462173 -22.360347 -28.498162 -31.920679
2012 14.475032 -0.743951 -5.051996 13.635166 8.467030 31.729980 -5.655689 -4.517390 -5.391063 -24.826784 28.100857
2013 -9.192065 -7.364210 17.288119 -29.636345 36.555955 -11.940437 33.345875 66.949511 107.022316 34.713799 -4.796419
2014 63.177330 16.030023 16.267892 38.393825 16.021659 65.280025 53.888999 40.312352 17.533578 41.001390 121.163607
2015 -1.364502 26.579835 66.771453 15.377013 56.683331 44.852518 28.499059 100.290853 76.740574 72.689743 -16.896293
2016 -4.934512 7.429930 -8.577717 -6.172062 -13.462985 -17.689690 -18.581718 -30.324826 -32.385228 -15.954111 -14.690430
2017 13.279530 53.851543 -12.621267 15.394464 3.564531 0.804731 -16.645356 -11.264512 -23.100551 -3.052560 17.296307
2018 -14.665096 -21.953798 -22.444282 -41.036192 -27.672089 -28.789159 -31.038296 -24.528636 -39.582055 -31.316647 -25.371968
2019 22.932666 72.867365 45.447431 24.272174 36.847449 22.752114 27.186604 48.044951 21.199971 19.963787 45.507504
2020 -9.270171 46.157476 40.579184 14.564627 51.056217 0.677980 47.374799 26.342584 24.400941 9.271191 4.675113

step2:数据处理

给涨跌幅保留2位小数,添加百分号%,合并品种名称和涨跌幅。

  • 每年都需要将各行业的涨跌幅进行由大到小排序(每行排序);
  • 将排序后的行业和涨跌幅进行拼接,而且还要支持换行,行业在上,涨跌幅在下;
  • 对涨跌幅保留2位小数,并加上百分号%;

DataFrame的分组聚合操作:

分组聚合操作就是拆分-应用-聚合(split-apply-combine),首先DataFrame会在它的行方向(axis=0)或列方向(axis=1)按照某些规则(如按照某列的取值)进行分组,然后一个函数就可以应用到各个组中,每组都会产生相应的值,最后将各组的计算结果聚合到一张表中。

In [4]:
data = data.round(2)  # 保留 2 位小数
# 这里对data每行数据进行apply函数应用操作(因为年份是按行的,所以axis=1),使用.items()将columns和内容生成一个zip文件
data = data.apply(lambda a :pd.Series( ['{}\n{}%'.format(i,j) for i,j in a.sort_values(ascending=False).items()]), axis=1)

step 3: 初步绘图

In [6]:
import matplotlib.pyplot as plt 
plt.style.use('seaborn-white')                   # 设置主题
plt.rcParams['font.sans-serif'] = ['SimHei']     # 设置字体
plt.rcParams['axes.unicode_minus'] = False       # 显示负号
  1. 绘制表格函数:Axes.table()
Axes.table(ax, cellText=None, cellColours=None, cellLoc='right', colWidths=None, rowLabels=None, rowColours=None, rowLoc='left', colLabels=None, colColours=None, colLoc='center', loc='bottom', bbox=None, edges='closed', **kwargs)
参数 类型 是否可选 含义
cellText 2D list of str 可选参数 表格单元格中须填写的文本。
cellColours 2D list of colors 可选参数 对应表格单元格的颜色。
cellLoc str 可选参数 单元格文字对其方式,'left' 左对齐, 'center' 居中, 'right' 右对齐,默认为 'right'。
colWidths list of float 可选参数 表格列宽,默认为1/ncol
rowLabels/colLabels list of str 可选参数 表格行标题和列标题。
rowColours/colColours list of colors 可选参数 表格行标题和列标题的单元格颜色。
rowLoc/colLoc str 可选参数 表格行标题和列标题在单元格中的对其方式,'left' 左对齐, 'center' 居中, 'right' 右对齐,行标题默认为 'left',列标题默认为'center'。
loc str 可选参数 表格单元格相对于 坐标系 的位置,默认在底部 'bottom'。
bbox bbox 可选参数 绘制表格的区域,(x, y, width, height) 将图例放在 xy 处且设置了宽度和高度,该设置优于loc。
edges str 可选参数 绘制单元格边框,'open' 无边框, 'closed' 有边框, 'horizontal' 只显示水平边框, 'vertical' 只显示垂直边框 。
  1. 设置图标题:Axes.set_title()
Axes.set_title( label, fontdict=None, loc=None, pad=None, **kwargs)
参数 类型 是否可选 含义
label str 不可选参数 图标题文本的内容。
fontdict dict 可选参数 用于控制标题文本的样式:{'fontsize': rcParams['axes.titlesize'], 'fontweight' : rcParams['axes.titleweight'],
'color' : rcParams['axes.titlecolor'], 'verticalalignment': 'baseline', 'horizontalalignment': loc},默认为 None。
loc str 可选参数 用于设置标题的位置:'center' 正上方 , 'left' 左上方, 'right' 右上方,默认为 center 。
pad float 可选参数 标题距轴顶部的偏移量(以磅为单位), 默认为 None, 对应 rcParams [“ axes.titlepad”]=6.0 。
  1. 设置文本标签:Axes.text()
Axes.text(x, y, s, fontdict=None, withdash=<deprecated parameter>, **kwargs)
参数 含义
x,y(标量) 用于放置文本的位置。
s(字符串) 文本展示的内容。
fontdict(字典) 用于设置文本的样式,将相关设置参数和取值组成字典,赋值给 fontdict。
fontsize 用于设置字体大小。
color 用于设置字体颜色。
alpha 用于设置字体透明度。
horizontalalignment/ha 用于设置文本与水平 y 坐标的相对位置。
verticalalignment/va 用于设置文本与垂直 x 坐标的相对位置。
position 用于设置文本位置(x,y),与单独设置想 x,y 等价。
rotation 用于设置文本旋转的角度。
In [9]:
# 设置颜色
# 字符串正则表达式,对中括号的字符进行匹配,然后用 sub 函数删除匹配的字符
import re 
colors = ['#fd9e9a', '#e95e35','#31b271', '#ffcd22','#4672d5','#16aec6','#404040','#3b4aff','#2053a6','#e12f23','#dd9f10']
furtures = ['银行','食品饮料','农林牧渔','有色金属','医药生物','房地产','国防军工','计算机','传媒','通信','非银行金融']
colors_dic = dict(zip(furtures, colors ))
colors_df = data.apply(lambda a : pd.Series([colors_dic[re.sub('[0-9\.\-\%\\n]', '', i)] for i in a]), axis=1)
# 生成一个颜色与行业一一对应的dataframe
colors_df
Out[9]:
0 1 2 3 4 5 6 7 8 9 10
2005 #fd9e9a #404040 #e95e35 #16aec6 #ffcd22 #e12f23 #4672d5 #2053a6 #31b271 #dd9f10 #3b4aff
2006 #dd9f10 #fd9e9a #e95e35 #16aec6 #ffcd22 #404040 #31b271 #e12f23 #2053a6 #4672d5 #3b4aff
2007 #ffcd22 #404040 #4672d5 #dd9f10 #16aec6 #31b271 #3b4aff #e95e35 #e12f23 #2053a6 #fd9e9a
2008 #4672d5 #31b271 #e12f23 #3b4aff #2053a6 #e95e35 #fd9e9a #16aec6 #dd9f10 #404040 #ffcd22
2009 #ffcd22 #404040 #16aec6 #e95e35 #3b4aff #dd9f10 #fd9e9a #4672d5 #31b271 #e12f23 #2053a6
2010 #4672d5 #3b4aff #ffcd22 #31b271 #e95e35 #404040 #2053a6 #e12f23 #fd9e9a #16aec6 #dd9f10
2011 #fd9e9a #e95e35 #16aec6 #2053a6 #e12f23 #4672d5 #31b271 #dd9f10 #404040 #3b4aff #ffcd22
2012 #16aec6 #dd9f10 #fd9e9a #ffcd22 #4672d5 #e95e35 #3b4aff #31b271 #2053a6 #404040 #e12f23
2013 #2053a6 #3b4aff #4672d5 #e12f23 #404040 #31b271 #dd9f10 #e95e35 #fd9e9a #16aec6 #ffcd22
2014 #dd9f10 #16aec6 #fd9e9a #404040 #e12f23 #3b4aff #ffcd22 #2053a6 #31b271 #e95e35 #4672d5
2015 #3b4aff #2053a6 #e12f23 #31b271 #4672d5 #16aec6 #404040 #e95e35 #ffcd22 #fd9e9a #dd9f10
2016 #e95e35 #fd9e9a #ffcd22 #31b271 #4672d5 #dd9f10 #e12f23 #16aec6 #404040 #3b4aff #2053a6
2017 #e95e35 #dd9f10 #ffcd22 #fd9e9a #4672d5 #16aec6 #e12f23 #3b4aff #31b271 #404040 #2053a6
2018 #fd9e9a #e95e35 #31b271 #3b4aff #dd9f10 #4672d5 #16aec6 #404040 #e12f23 #2053a6 #ffcd22
2019 #e95e35 #3b4aff #dd9f10 #31b271 #4672d5 #404040 #ffcd22 #fd9e9a #16aec6 #2053a6 #e12f23
2020 #4672d5 #404040 #e95e35 #31b271 #3b4aff #2053a6 #ffcd22 #e12f23 #dd9f10 #16aec6 #fd9e9a
In [10]:
# 设置画布
fig,ax = plt.subplots(figsize=(10,13), dpi=90)

# 设置字体为白色
plt.rcParams['text.color']= 'white' 

# 绘制表格
ax.set_axis_off()  # 除去坐标系
table = ax.table(cellText = data.values, 
                             bbox=(0,0,1,1),                             # 设置表格位置 (x0, y0, width, height)
                             rowLabels=data.index,                       # 设置行标题
                             rowLoc = 'center',                          # 行标题居中
                             cellLoc='center' ,
                             rowColours = ['#8c8c8c']*len(data.index),   # 设置行标题的颜色
                             cellColours = colors_df.values              # 设置单元格颜色
                            )

# 设置字体大小
table.set_fontsize(15)

# 设置图标题:标题颜色为黑色
ax.set_title('A股热门行业历年收益',  loc='center', pad=25, fontsize=20, color='black') 

# 设置数据来源
ax.text(0.82,-0.04 ,'数据来源:WindQuant', fontsize=13, alpha=0.5, ha='left', va='bottom',color='#5a5a5a') 
ax.text(0.82,-0.06 ,'日期:2020年8月20日', fontsize=13, alpha=0.5, ha='left', va='bottom',color='#5a5a5a') 
ax.text(0.82,-0.08 ,'作者:周嘉楠', fontsize=13, alpha=0.5, ha='left', va='bottom',color='#5a5a5a') 

fig.tight_layout()