前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >比特币一年翻 6 倍?看我用 Python 动态可视化比特币价格变动趋势

比特币一年翻 6 倍?看我用 Python 动态可视化比特币价格变动趋势

作者头像
AirPython
发布2021-03-26 15:04:12
6340
发布2021-03-26 15:04:12
举报

大家好,我是安果!

最近几年,比特币一直站在风口浪尖,一度被追捧为最佳的投资产品,拥护者认为这种加密货币是一种类似于黄金的储值工具,可以对冲通胀和美元疲软

其他人则认为,比特币的暴涨只是一个经济刺激措施催生的巨大泡沫,并且必将破裂

本文就将对比特币 2013 年到 2021 年价格进行动态可视化,先看效果

获取数据

比特币数据很多网站都有,并且也有很多成熟的 API,所以取数据非常简单,直接调用 API 接口即可,下面是获取与写入数据的全部代码

import requests
import json
import csv
import time
time_stamp = int(time.time())
url = f"https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?convert=USD&slug=bitcoin&time_end={time_stamp}&time_start=1367107200"
rd = requests.get(url = url)
# 返回的数据是 JSON 格式,使用 json 模块解析
co = json.loads(rd.content)
list1 = co['data']['quotes']

with open('BTC.csv','w' ,encoding='utf8',newline='') as f:
    csvi = csv.writer(f)
    csv_head = ["date","price","volume"]
    csvi.writerow(csv_head)

    for i in list1:
        quote_date = i["time_open"][:10]
        quote_price = "{:.2f}".format(i["quote"]["USD"]["close"])
        quote_volume = "{:.2f}".format(i["quote"]["USD"]["volume"])
        csvi.writerow([quote_date, quote_price, quote_volume])

执行后,当前目录就会生成BTC.csv数据文件

动态可视化BTC价格变化

首先导入需要的包及相关设定

import pandas as pd
import matplotlib as mpl
from matplotlib import cm
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker 
import matplotlib.animation as animation
from IPython.display import HTML
from datetime import datetime
plt.rcParams['font.sans-serif'] = ['SimHei']  
plt.rcParams['axes.unicode_minus'] = False  
plt.rc('axes',axisbelow=True) 
mpl.rcParams['animation.embed_limit'] = 2**128

其中两句plt.rcParams[]是用来设置显示中文的

plt.rc('axes',axisbelow=True)的作用是设置外观要求,即坐标轴置底

mpl.rcParams['animation.embed_limit'] = 2**128这句是为了生成动画而用的,由于动画默认的最大体积为 20971520 字节;如果需要调整生成的动画最大体积,需要更改这个参数

接下来数据并利用查看前 5 行与后 5 行

从表格初窥可以得知,13 年初的价格在 100 美元左右,而到如今 21 年价格已经飞涨到 5 万左右了。具体在哪段时间飞涨如此之快呢,我们通过动态面积可视化来探索

可视化之前,需要对数据进行处理,由于我们原本的数据是这样的

是 csv 格式,且Date字段是字符串类型,而在 Python 中运用matplotlib画时间序列图都需要datetime时间戳格式才美观,所以我们运用了如下代码进行转换

df = pd.read_csv('BTC.csv')
df['date']=[datetime.strptime(d, '%Y/%m/%d').date() for d in df['date']]

下面制作静态面积图,使用单色填充的话,可用如下代码

Span=180
N_Span=0
df_temp=df.loc[N_Span*Span:(N_Span+1)*Span,:]
df_temp.head(5)
fig =plt.figure(figsize=(6,4), dpi=100)
plt.subplots_adjust(top=1,bottom=0,left=0,right=0.9,hspace=0,wspace=0)
plt.fill_between(df_temp.date.values, y1=df_temp.price.values, y2=0,alpha=0.75, facecolor='r', linewidth=1,edgecolor ='none',zorder=1)
plt.plot(df_temp.date, df_temp.price, color='k',zorder=2)
plt.scatter(df_temp.date.values[-1], df_temp.price.values[-1], color='white',s=150,edgecolor ='k',linewidth=2,zorder=3)
plt.text(df_temp.date.values[-1], df_temp.price.values[-1]*1.18,s=np.round(df_temp.price.values[-1],1),size=10,ha='center', va='top')
plt.ylim(0, df_temp.price.max()*1.68)
plt.xticks(ticks=df_temp.date.values[0:Span+1:30],labels=df_temp.date.values[0:Span+1:30],rotation=0)
plt.margins(x=0.01)
ax = plt.gca()#获取边框
ax.spines['top'].set_color('none')    # 设置上‘脊梁’为无色
ax.spines['right'].set_color('none')  # 设置上‘脊梁’为无色
ax.spines['left'].set_color('none')   # 设置上‘脊梁’为无色
plt.grid(axis="y",c=(217/256,217/256,217/256),linewidth=1)         #设置网格线   
plt.show()

其中Span设定的是多少天的价格,这里我们使用 200 天。N_Span代表权重;

df_temp=df.loc[N_Span*Span:(N_Span+1)*Span,:]代表的是选择到179行为止的数据,即 180 天

plt.fill_between()是使用单色--红色填充

得到如下效果

但是一个颜色填充总感觉不够好看,所以下面使用渐变色填充,使用plt.bar()函数实现 Spectral_r 颜色映射。代码如下:

Span_Date =180  
Num_Date =360  #终止日期
df_temp=df.loc[Num_Date-Span_Date: Num_Date,:]  #选择从Num_Date-Span_Date开始到Num_Date的180天的数据
colors = cm.Spectral_r(df_temp.price / float(max(df_temp.price)))
fig =plt.figure(figsize=(6,4), dpi=100)
plt.subplots_adjust(top=1,bottom=0,left=0,right=0.9,hspace=0,wspace=0)
plt.bar(df_temp.date.values,df_temp.price.values,color=colors,width=1,align="center",zorder=1)
plt.plot(df_temp.date, df_temp.price, color='k',zorder=2)
plt.scatter(df_temp.date.values[-1], df_temp.price.values[-1], color='white',s=150,edgecolor ='k',linewidth=2,zorder=3)
plt.text(df_temp.date.values[-1], df_temp.price.values[-1]*1.18,s=np.round(df_temp.price.values[-1],1),size=10,ha='center', va='top')
plt.ylim(0, df_temp.price.max()*1.68)
plt.xticks(ticks=df_temp.date.values[0: Span_Date +1:30],labels=df_temp.date.values[0: Span_Date +1:30],rotation=0)
plt.margins(x=0.01)
ax = plt.gca()#获取边框
ax.spines['top'].set_color('none')   # 设置上‘脊梁’为无色
ax.spines['right'].set_color('none')  # 设置上‘脊梁’为无色
ax.spines['left'].set_color('none')   # 设置上‘脊梁’为无色
plt.grid(axis="y",c=(217/256,217/256,217/256),linewidth=1)   #设置网格线   
plt.show()

这里的数据筛选有稍许不同,其中Span_Date设置初始时间,这里设置为180即从起始日开始算的 180 天.

Num_Date设置的是终止时间。

df_temp=df.loc[Num_Date-Span_Date: Num_Date,:]则是用loc函数筛选从180天到终止日期的数据。

效果如下:

动态可视化

最后,我们来将这幅图动起来,先将刚刚的绘图部分封装

def draw_areachart(Num_Date):
    Span_Date=180
    ax.clear()
    if Num_Date<Span_Date:
        df_temp=df.loc[0:Num_Date,:]
        df_span=df.loc[0:Span_Date,:]
        colors = cm.Spectral_r(df_span.price.values / float(max(df_span.price.values)))
        plt.bar(df_temp.date.values,df_temp.price.values,color=colors,width=1.5,align="center",zorder=1)
        plt.plot(df_temp.date, df_temp.price, color='k',zorder=2)
        plt.scatter(df_temp.date.values[-1], df_temp.price.values[-1], color='white',s=150,edgecolor ='k',linewidth=2,zorder=3)
        plt.text(df_temp.date.values[-1], df_temp.price.values[-1]*1.18,s=np.round(df_temp.price.values[-1],1),
size=10,ha='center', va='top')
        plt.ylim(0, df_span.price.max()*1.68)
        plt.xlim(df_span.date.values[0], df_span.date.values[-1])
        plt.xticks(ticks=df_span.date.values[0:Span_Date+1:30],labels=df_span.date.values[0:Span_Date+1:30],rotation=0,fontsize=9)
    else:
        df_temp=df.loc[Num_Date-Span_Date:Num_Date,:]
        colors = cm.Spectral_r(df_temp.price / float(max(df_temp.price)))
        plt.bar(df_temp.date.values[:-2],df_temp.price.values[:-2],color=colors[:-2],width=1.5,align="center",zorder=1)
        plt.plot(df_temp.date[:-2], df_temp.price[:-2], color='k',zorder=2)
        plt.scatter(df_temp.date.values[-4], df_temp.price.values[-4], color='white',s=150,edgecolor ='k',linewidth=2,zorder=3)
        plt.text(df_temp.date.values[-1], df_temp.price.values[-1]*1.18,s=np.round(df_temp.price.values[-1],1),
size=10,ha='center', va='top')
        plt.ylim(0, df_temp.price.max()*1.68)
        plt.xlim(df_temp.date.values[0], df_temp.date.values[-1])
        plt.xticks(ticks=df_temp.date.values[0:Span_Date+1:30],labels=df_temp.date.values[0:Span_Date+1:30],rotation=0,fontsize=9)    

    plt.margins(x=0.2)
    ax.spines['top'].set_color('none')  # 设置上‘脊梁’为红色
    ax.spines['right'].set_color('none')  # 设置上‘脊梁’为无色
    ax.spines['left'].set_color('none')  # 设置上‘脊梁’为无色
    plt.grid(axis="y",c=(217/256,217/256,217/256),linewidth=1)         #设置网格线  
    plt.text(0.01, 0.95,"BTC平均价格($)",transform=ax.transAxes, size=10, weight='light', ha='left')
    ax.text(-0.07, 1.03, '2013年到2021年的比特币BTC价格变化情况',transform=ax.transAxes, size=17, weight='light', ha='left')

fig, ax = plt.subplots(figsize=(6,4), dpi=100)
plt.subplots_adjust(top=1,bottom=0.1,left=0.1,right=0.9,hspace=0,wspace=0)  
draw_areachart(150)

之后使用matplotlib包的animation.FuncAnimation()函数,之后调用上述编写的draw_areachart(Num_Date)函数。

其中输入的参数Num_Date是如静态可视化中提及的日期作用一样,赋值为np.arange(0,df.shape[0],1)

最后使用Ipython包的HTML()函数将动画转换成动画页面的形式演示。代码如下:

import matplotlib.animation as animation
from IPython.display import HTML
fig, ax = plt.subplots(figsize=(6,4), dpi=100)
plt.subplots_adjust(left=0.12, right=0.98, top=0.85, bottom=0.1,hspace=0,wspace=0)  
animator = animation.FuncAnimation(fig, draw_areachart, frames=np.arange(0,df.shape[0],1),interval=100)
HTML(animator.to_jshtml()) 

函数FuncAnimation(fig,func,frames,init_func,interval,blit)是绘制动图函数。其参数如下:

  • fig 表示绘制动图的画布名称(figure);
  • func为自定义绘图函数,如draw_barchart()函数;
  • frames为动画长度,一次循环包含的帧数,在函数运行时,其值会传递给函数draw_barchart (year)的形参“year”;
  • init_func为自定义开始帧可省略;
  • interval表示更新频率,计量单位为ms;
  • blit表示选择更新所有点,还是仅更新产生变化的点,应选择为True,但mac电脑用户应选择False,否则无法显示。

最后效果就是这样?

可以看到在过去的一年中,由于机构的兴趣日益增加,比特币上涨超过了 6 倍,最高突破 58000 美元/枚,当然可以看到跌起来也是非常恐怖的,关于比特币,你怎么看?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AirPython 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 获取数据
  • 动态可视化BTC价格变化
  • 动态可视化
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档