主页 > 怎么注册imtoken钱包 > 比特币一年翻6倍?看我用 Python 动态可视化比特币价格趋势

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

怎么注册imtoken钱包 2023-07-06 05:21:14

大家好,我是安哥!

比特币近年来一直处于风口浪尖,一度被吹捧为最好的投资产品,支持者将加密货币视为一种类似黄金的价值储存手段,可以对冲通胀和美元贬值

也有人认为,比特币暴涨只是经济刺激造成的巨大泡沫,必将破灭

本文将动态可视化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 行

从表格的第一眼我们可以看到,2013年初的价格在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        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.010.95,"BTC平均价格($)",transform=ax.transAxes, size=10, weight='light', ha='left')
    ax.text(-0.071.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) 是绘制动画的函数。其参数如下:

“”

最后的效果是这样的

可以看出,在过去的一年里,由于机构兴趣的增加,比特币上涨了6倍多,最高达到每块5.8万美元。当然,可以看出摔倒是很吓人的。你如何看待比特币??