怎样用Python自制好看的指数估值图
对于以定投指数的方式理财的朋友,最需要关注的指标便是各个指数的估值,在指数低估时买入,高估时卖出,那如何制作一张估值图来跟踪指数的估值情况呢?本文就从0到1介绍如何用 Matplotlib 画一张漂亮的指数估值图。
准备数据
首先,准备我们需要的数据,一般来说,经历了一轮牛熊周期的历史估值更具比较意义,所以,这里以上证指数2013年到目前为止的行情数据为例进行演示,同时,采用滚动市盈率为估值指标。数据来源为tushare。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tushare as ts
from datetime import *
%matplotlib inline
#设置显示中文
plt.rcParams['font.sans-serif'] = 'FangSong' pro = ts.pro_api() index_df = pro.index_dailybasic(ts_code = "000001.SH",start_date = "20130101",
end_date = "20200311",fields="trade_date,pe_ttm")
index_df.sort_values(by="trade_date",inplace=True)
x = pd.to_datetime(index_df["trade_date"]).values
y = index_df["pe_ttm"].values
根据得到的数据,可以绘制出上证指数市盈率的走势图:
fig,ax = plt.subplots(figsize=(12,8))
ax.plot(x,y)

接下来便需要根据一定的规则,将估值划分为高估区、正常区以及低估区。
估值区间划分
参照比较常见的划分方法,本文将大于80%分位数的区域视为高估区间,低于20%分位数的区域视为低估区间,位于两者之间的,则为正常区间。下面的代码算出了这几个关键数据点
max = np.max(y)
pe_80 = np.percentile(y,80)
pe_20 = np.percentile(y,20)
min = np.min(y)
now = y[-1] #为了后续标出当日估值
绘图
根据分割的数据点,就可以进行绘图了,这里主要用到 fill_between 函数绘制各区域的颜色分割,将高估区域用红色块填充,正常区间用黄色块填充,低估值区域用绿色块填充。同时为了显示效果,将图的上下限分别设置为最大值+1和最小值-1。
fig,ax = plt.subplots(figsize=(12,8))
ax.plot(x,y,linewidth=3)
ax.fill_between(x,min-1,pe_20,facecolor = "#00ff80",alpha=0.2)
ax.fill_between(x,pe_20,pe_80,facecolor = "#ffff4d",alpha=0.2)
ax.fill_between(x,pe_80,max+1,facecolor = "#ff69b4",alpha=0.2)

整个图形的大致轮廓已经出来了,为了更好的显示效果,接下来还需要对图形进行微调。比如:
- 去掉坐标轴的刻度并将相应字体放大-->
ax.tick_params() - 去掉图形与坐标轴之间的空白-->
ax.margins() - 在图中标出当日市盈率-->
ax.text() - 将图形的方框去掉-->
plt.box() - 为图标添加标题-->
plt.title
所以,在之前代码的基础上,加入下面的调整代码,就可以得到最终的成品图
fig,ax = plt.subplots(figsize=(12,8))
ax.plot(x,y,linewidth=3)
ax.fill_between(x,min-1,pe_20,facecolor = "#00ff80",alpha=0.2)
ax.fill_between(x,pe_20,pe_80,facecolor = "#ffff4d",alpha=0.2)
ax.fill_between(x,pe_80,max+1,facecolor = "#ff69b4",alpha=0.2)
ax.tick_params(axis='both', which='both',length=0)
ax.tick_params(axis='both', which='major', labelsize=16)
ax.margins(0.01,0)
ax.text(0.75,0.9,"市盈率 = {}".format(now),transform=ax.transAxes,fontdict={'size':18})
plt.xticks(rotation=45)
plt.box(False)
plt.title("上证指数估值图",fontdict={'size':24})

函数封装
进一步地,为了将上面的代码复用,可以将所有绘图的代码封装成函数,之后只需要输入相应的指数代码(可以值宽基指数、行业板块指数)和时间范围,即可快速生成一张估值图。
def pe_plot(ts_code = "",name="",period=5):
#准备数据
now = datetime.now()
end_date = str(now.date()).replace("-","")
start_date = str(now.year-period)+end_date[4:]
index_df = pro.index_dailybasic(ts_code = ts_code,start_date = start_date,
end_date = end_date,fields="trade_date,pe_ttm")
index_df.sort_values(by="trade_date",inplace=True)
x = pd.to_datetime(index_df["trade_date"]).values
y = index_df["pe_ttm"].values #划定分割范围
max = np.max(y)
pe_80 = np.percentile(y,80)
pe_20 = np.percentile(y,20)
min = np.min(y)
now = y[-1] #绘图
fig,ax = plt.subplots(figsize=(12,8))
ax.plot(x,y,linewidth=3)
ax.fill_between(x,min-1,pe_20,facecolor = "#00ff80",alpha=0.2)
ax.fill_between(x,pe_20,pe_80,facecolor = "#ffff4d",alpha=0.2)
ax.fill_between(x,pe_80,max+1,facecolor = "#ff69b4",alpha=0.2)
ax.tick_params(axis='both', which='both',length=0)
ax.tick_params(axis='both', which='major', labelsize=16)
ax.margins(0.01,0)
ax.text(0.75,0.9,"市盈率 = {}".format(now),
transform=ax.transAxes,fontdict={'size':18})
plt.xticks(rotation=45)
plt.box(False)
plt.title("{}估值图".format(name),fontdict={'size':24})
plt.show()
比如,生成一张创业板指数近5年的估值图
pe_plot(ts_code="399006.SZ",name="创业板指",period=5)

交流基地:630390733
怎样用Python自制好看的指数估值图的更多相关文章
- Python的网络编程--思维导图
Python的网络编程--思维导图
- python逆向工程:通过代码生成类图
python逆向工程:通过代码生成类图 大致过程 现在有一个core包,里面有python的代码. 通过core包,生成python的类图,如下: 实施步骤: 1.首先安装graphviz,一个画图工 ...
- 使用JavaScript制作一个好看的轮播图
目录 使用JavaScript制作出好看的轮播图效果 准备材料 1.图片若干张(包括轮播图和按钮的图片) 2.将按钮的图片应用到按钮上的CSS样式文件 3.实现轮播和点击跳转的JavaScript代码 ...
- 用Python 绘制分布(折线)图
用Python 绘制分布(折线)图,使用的是 plot()函数. 一个简单的例子: # encoding=utf-8 import matplotlib.pyplot as plt from pyla ...
- python编写微信公众号首图思路详解
前言 之前一直在美图秀秀调整自己的微信公众号首图,效果也不尽如人意,老是调来调去,最后发出来的图片被裁剪了一大部分,丢失部分关键信息,十分恼火,于是想着用python写一个程序,把微信公众号首图的模式 ...
- 跟我学Python图像处理丨基于灰度三维图的图像顶帽运算和黑帽运算
摘要:本篇文章结合灰度三维图像讲解图像顶帽运算和图像黑猫运算,通过Python调用OpenCV函数实现. 本文分享自华为云社区<[Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽 ...
- 用python自制微信机器人,定时发送天气预报
0 引言 前段时间找到了一个免费的天气预报API,费了好段时间把这个API解析并组装成自己想用的格式了,就想着如何实现每天发送天气信息给自己.最近无意中发现了wxpy库,用它来做再合适不过了.以下是w ...
- Python分析世界幸福指数
前言 民意测验机构盖洛普从2012年起,每年都会在联合国计划下发布<世界幸福指数报告>,报告会综合两年内150多个国家的国民对其所处社会.城市和自然环境等因素进行评价后,再根据他们所感知的 ...
- Python自制微信机器人:群发消息、自动接收好友
运营公众号也有半年了,今年5月份开始的,之前一直用一款windows工具来运营自动接受好友请求.群发文章.自动回复等操作,但颇有不便. 举几个场景: 突然在外面看到一篇文章很好,临时写了一篇,想群发一 ...
随机推荐
- leetcode 56合并区间 java
//先排序,将左区间小的放在前面,然后如果前一个的右区间大于下一个的左区间,则可以合并,分别用两个下标指向当前的大区间和将要考察的小区间 class Solution { public int[ ...
- 2020.7.19 区间dp阶段测试
打崩了-- 事先说明,今天没有很在状态,所以题解就直接写在代码注释里的,非常抱歉 T1 颜色联通块 此题有争议,建议跳过 题目描述 N 个方块排成一排,第 i 个颜色为 Ci .定义一个颜色联通块 [ ...
- O - Matching 题解(状压dp)
题目链接 题目大意 给你一个方形矩阵mp,边长为n(n<=21) 有n个男生和女生,如果\(mp[i][j]=1\) 代表第i个男生可以和第j个女生配对 问有多少种两两配对的方式,使得所有男生和 ...
- 深入浅出之mysql索引--上
当着小萌新之际,最近工作中遇到了mysql优化的相关问题,然后既然提到了优化,很多像我这样的小萌新不容置喙,肯定张口就是 建立索引 之类的. 那么说到底,索引到底是什么,它是怎么工作的?接下来就让我和 ...
- socket阻塞与非阻塞,同步与异步,select,pool,epool
概念理解 一.与I/O相关的五个重要概念 1. 第一个概念:用户空间与内核空间 1. 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方) 2. ...
- 第九章 Python文件操作
前一阵子写类相关的内容,把老猿写得心都累了,本来准备继续介绍一些类相关的知识的,如闭包.装饰器.描述符.枚举类.异常等,现在实在不想继续,以后再开章节吧.本章弄点开胃的小菜提提神,介绍Python中文 ...
- React跳转路由传参3种方法和区别
1.params传参 路由表配置:参数地址栏显示 路由页面:<Route path='/demo/:id' component={Demo}></Route> //配置 /:i ...
- 第五篇 Scrum 冲刺博客
一.站立式会议 1. 会议照片 2. 工作汇报 团队成员名称 昨日(26日)完成的工作 今天(27日)计划完成的工作 工作中遇到的困难 陈锐基 - 完成发布页面的布局- 完成发布动态的功能 - 优化当 ...
- js 彻底搞懂事件循环机制 Event Loop
我们都知道javascript是单线程语言,就是因为单线程的特性,就不得不提js中的同步和异步 一.同步和异步 所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就 ...
- 题解-CF1437F Emotional Fishermen
题面 CF1437F Emotional Fishermen 给 \(n\) 个数的序列 \(a_i\),求有多少种 \(n\) 个数的排列 \(p_i\),使得 \[\frac{a_{p_i}}{\ ...