范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

利用Python的matplotlib库绘制动态图形

  一、python 绘制动画图
  python绘制动态图形是数据可视化更直观、更好看的一种方式,matplotlib工具包是常用的绘图工具,也可以用来绘制动态图形。本文介绍四种绘制动态图形的方法,包括生成图形的代码和动态图形演示示例。
  用matplotlib工具包创建动画图有两种方法:  使用 pause() 函数  使用 FuncAnimation() 函数  动画柱状图,使用FuncAnimation() 函数
  代码如下:from matplotlib import pyplot as pltfrom matplotlib.animation import FuncAnimation, writersimport numpy as np  fig = plt.figure(figsize = (7,5))axes = fig.add_subplot(1,1,1)axes.set_ylim(0, 300)palette = ["blue", "red", "green",            "darkorange", "maroon", "black"]  y1, y2, y3, y4, y5, y6 = [], [], [], [], [], []  def animation_function(i):    y1 = i    y2 = 5 * i    y3 = 3 * i    y4 = 2 * i    y5 = 6 * i    y6 = 3 * i      plt.xlabel("Country")    plt.ylabel("GDP of Country")          plt.bar(["India", "China", "Germany",              "USA", "Canada", "UK"],            [y1, y2, y3, y4, y5, y6],            color = palette)  plt.title("Bar Chart Animation")  animation = FuncAnimation(fig, animation_function,                           interval = 50)plt.show()
  如下图:
  横向柱状跑图 (Horizontal Bar Chart Race),使用FuncAnimation() 函数
  以下代码是绘制世界1500年-2018年主要城市人口变化横向柱状跑图,需要数据集文件city_populations.csv评论区留言。
  程序代码如下:import pandas as pdimport matplotlib.pyplot as pltimport matplotlib.ticker as tickerfrom matplotlib.animation import FuncAnimationdf = pd.read_csv("city_populations.csv",usecols=["name", "group", "year", "value"])colors = dict(zip(["India","Europe","Asia","Latin America","Middle East","North America","Africa"],["#adb0ff", "#ffb3ff", "#90d595","#e48381", "#aafbff", "#f7bb5f","#eafb50"]))group_lk = df.set_index("name")["group"].to_dict()def draw_barchart(year):dff = df[df["year"].eq(year)].sort_values(by="value",ascending=True).tail(10)ax.clear()ax.barh(dff["name"], dff["value"],color=[colors[group_lk[x]] for x in dff["name"]])dx = dff["value"].max() / 200for i, (value, name) in enumerate(zip(dff["value"],dff["name"])):ax.text(value-dx, i, name,size=14, weight=600,ha="right", va="bottom")ax.text(value-dx, i-.25, group_lk[name],size=10, color="#444444",ha="right", va="baseline")ax.text(value+dx, i, f"{value:,.0f}",size=14, ha="left", va="center")# polished stylesax.text(1, 0.4, year, transform=ax.transAxes,color="#777777", size=46, ha="right",weight=800)ax.text(0, 1.06, "Population (thousands)",transform=ax.transAxes, size=12,color="#777777")ax.xaxis.set_major_formatter(ticker.StrMethodFormatter("{x:,.0f}"))ax.xaxis.set_ticks_position("top")ax.tick_params(axis="x", colors="#777777", labelsize=12)ax.set_yticks([])ax.margins(0, 0.01)ax.grid(which="major", axis="x", linestyle="-")ax.set_axisbelow(True)ax.text(0, 1.12, "The most populous cities in the world from 1500 to 2018",transform=ax.transAxes, size=24, weight=600, ha="left")ax.text(1, 0, " ",transform=ax.transAxes, ha="right", color="#777777",bbox=dict(facecolor="white", alpha=0.8, edgecolor="white"))plt.box(False)plt.show()fig, ax = plt.subplots(figsize=(15, 8))animator = FuncAnimation(fig, draw_barchart,frames = range(1990, 2019))plt.show()
  散点图动画,使用FuncAnimation()函数
  在本例中, 使用random 数据和自定义函数animation_func()  from matplotlib import pyplot as pltfrom matplotlib.animation import FuncAnimationimport randomimport numpy as npx = []y = []colors = []fig = plt.figure(figsize=(7,5))def animation_func(i):x.append(random.randint(0,100))y.append(random.randint(0,100))colors.append(np.random.rand(1))area = random.randint(0,30) * random.randint(0,30)plt.xlim(0,100)plt.ylim(0,100)plt.scatter(x, y, c = colors, s = area, alpha = 0.5)animation = FuncAnimation(fig, animation_func,interval = 100)plt.show()
  如下图:
  使用 pause() 函数绘制动态直线
  matplotlib工具包的pyplot模块中有pause()函数,可用来设置时间间隔参数,达到绘制直线的动画效果。
  代码如下:from matplotlib import pyplot as pltx = []y = []for i in range(100):x.append(i)y.append(i)# Mention x and y limits to define their rangeplt.xlim(0, 100)plt.ylim(0, 100)# Ploting graphplt.plot(x, y, color = "green")plt.pause(0.01)plt.show()
  如下图:
  使用 FuncAnimation() 绘制动态直线
  FuncAnimation() 函数本身并不能创建动画效果,而是通过生成一系列不同参数的图片来实现动画效果.
  Syntax: FuncAnimation(figure, animation_function, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
  在这个实例代码中,使用FuncAnimation函数  创建一条直线的简单动画效果,只需要调整参数即刻。from matplotlib import pyplot as pltfrom matplotlib.animation import FuncAnimationimport numpy as np  x = []y = []  figure, ax = plt.subplots()  # Setting limits for x and y axisax.set_xlim(0, 100)ax.set_ylim(0, 12)  # Since plotting a single graphline,  = ax.plot(0, 0)   def animation_function(i):    x.append(i * 15)    y.append(i)      line.set_xdata(x)    line.set_ydata(y)    return line,  animation = FuncAnimation(figure,                          func = animation_function,                          frames = np.arange(0, 10, 0.1),                           interval = 10)plt.show()
  如下图:
  二、如何把python绘制的动态图形保存为gif文件或视频
  使用Matplotlib中的matplotlib.animation 方法可以绘制更好看、更有吸引力的动画图形,那如何把这种动画图形保存为Gif动画文件或视频文件呢?本文简述与之相关的方法。把python程序中绘制的动画图形保存为视频格式或gif格式文件,以便播放或发送给其他人,或者插入找文档或网页中。本文分两部分,先介绍python程序绘制简单的动态图形或动画,然后再介绍如何把绘制的动态图形或动画保存为gif格式文件或视频文件。
  先用  Matplotlib.animation  类中的函数  FuncAnimation 创建动态图和动画,如动态折线、柱状图动画,另外还需要使用  figure  函数和  animation  函数,这些都是python使用matplotlib绘制图形时常用的方法。 1. 创建动态折线图
  1)绘制动态折线图,代码如下:import randomimport matplotlibimport matplotlib.pyplot as pltfrom matplotlib.animation import FuncAnimationfig = plt.figure(figsize=(15,15))x,y = [], []index= count()def animate(i):    x.append(next(index))    y.append(random.randint(2,20))    plt.style.use("ggplot")        plt.plot(x,y)ani = FuncAnimation(fig, animate, interval=300)plt.show()
  结果如图1:
  主要代码行说明:
  以上代码块中 "ani = FuncAnimation(fig, animate, interval=300)" 这一行中,FuncAnimation() 有三个参数:
  1) fig,表示图形参数
  指容纳plot图形的对象, 需要创建该对象,或者调用  matplotlib.pyplot.gcf() 函数 , 表示获得当前图形;
  2) animate 自定义函数
  这是  FuncAnimation 中的动画自定义函数, 要想获得动画图形就要把该参数设定为"animate",图形就会根据数据持续更新,注意创建图形和数据更新缺一不可。
  3) 画面间隔参数 interval
  该参数指定画面的更新速度,单位是毫秒。 interval=1000 表示该函数运行动画函数,并且每秒钟更新一次。
  以上代码块中 "plt . style . use ( "ggplot" ) " 这一行,指定动画图形的风格为 "ggplot ",要想了解更多的图形风格,可使用以下代码:import matplotlib.pyplot as pltprint(plt.style.available)
  输入结果如下:bmhclassicdark_backgroundfastfivethirtyeightggplotgrayscaleseaborn-brightseaborn-colorblindseaborn-dark-paletteseaborn-darkseaborn-darkgridseaborn-deepseaborn-mutedseaborn-notebookseaborn-paperseaborn-pastelseaborn-posterseaborn-talkseaborn-ticksseaborn-whiteseaborn-whitegridseabornSolarize_Light2tableau-colorblind10_classic_test
  上述代码块输出的图形结果中,两个数轴都是不固定的,这与 Matplotlib Axes Setting 有关,plot函数中也没有定义线的颜色。2.创建动画图形
  代码如下:import matplotlib.pyplot as pltfrom matplotlib.animation import FuncAnimation%matplotlib qtfig = plt.figure(figsize=(6,4))axes = fig.add_subplot(1,1,1)plt.title("Dynamic Axes")y1 = [random.randint(-10,10)+(i**1.6)/(random.randint(9,12)) for i in range(0,280,2)]t = range(len(y1))x,y=[], []def animate(i):    x.append(t[i])    y.append((y1[i]))    plt.xlim(i-30,i+3)    axes.set_ylim(y1[i]-100, y1[i]+100)    plt.plot(x,y, scaley=True, scalex=True, color="red")anim = FuncAnimation(fig, animate, interval=100)
  输出结果如图2:
  图2 动态数轴动画
  保存动态图形
  保存Matplotlib绘制的动画可能会出现一些小故障。下面介绍一下常用的选项和参数,既可以节省保存动画所需的时间,又可以尽可能地减少故障; 可以把python代码生成的动画保存为个人需要的格式,如gif、mp4、avi、mov等文件格式,这取决于保存时选择对应的参数。保存为GIF文件--图1,代码如下:f = r"d:animation.gif" writergif = animation.PillowWriter(fps=30) anim.save(f, writer=writergif)
  这段代码中,常用的选项有 ImageMagick 和 PillowWriter。
  对于windows 操作系统来说,使用 ImageMagick 方法一般要先安装相关程序包,并且在保存动画为 GIF 文件时,建议使用 Write Instance,还是比较复杂;如果是Unix操作系统,ImageMagick一般情况下都已经安装了,使用 ImageMagick 方法 就方便。因此,建议windows用户使用 PillowWriter 方法。
  定义 gif 图形的帧数:
  修改 FuncAnimation函数中的 save_count 参数的值,设定 GIF 文件的帧数,默认为 100 帧,代码如下:anim = animation.FuncAnimation(figure, func=update_figure, fargs=(bar_rects, iteration), frames=generator, interval=100, repeat=True, save_count=1500)
  示例代码中,把GIF文件的帧数修改为 1500 帧。保存为视频文件
  把调用matplotlib的方法生成的动画保存为视频文件,需要 ffmpeg.exe 安装程序,可到官网下载,如下图:
  特别注意,安装后要把该运行程序的路径 ffmpegbinffmpeg.exe 添加到环境变量中,此路径一定要正确 并且一定是指向可执行文件,而不仅仅是该文件所在的文件夹。在生成动画的python程序块中要加入以下代码行: import matplotlib as mpl mpl.rcParams["animation.ffmpeg_path"] = r"C:UsersxxDesktopffmpegbinffmpeg.exe"
  接下来,把 matplotlib 绘制的动画保存为 mp4 格式的视频文件,代码如下:f = r"d:animation.mp4" writervideo = animation.FFMpegWriter(fps=60) anim.save(f, writer=writervideo)
  定义视频的尺寸:
  视频的尺寸就是用 matplotlib 工具包绘制图形的窗口大小,调整对应窗口的大小即刻,示例代码如下:plt.subplots(figsize=(12,8))
  三、使用 matplotlib 绘制动画
  在python编程中,用matplotlib绘图工具包绘制动画图形。动画是数据图形化的一种方法,视觉冲击力很强,给人留下了深刻的印象。动画图形或者可交互图形和静态图形相比,对人的诱惑力更强。像股票数据,气象数据,季节性和趋势这样的数据,用动画来表示会让人更容易明白。matplotlib库的主要特征有很多后台渲图工具组成它可以重新生成任何形式的绘图(只需要略做修改)该工具包历史悠久,比较成熟matplotlib和MATLAB绘图可以转换
  然而,matplotlib库也有一些缺点:matplotlib有一个必要的API,这类接口一般比较冗长有时一些默认的绘图风格比较粗陋对web图形和交互图形的支持不足绘制大规模数据和复杂数据的图形比较慢matplotlib的animation基类和使用条件
  matplotlib绘制动画图形就是使用animation基类的方法,它提供了构建动画功能的基本框架,使用的主要接口有两个:FuncAnimation: 通过重复调用函数 func 绘制动画ArtistAnimation: 使用一组固定的Artist对象实现动画效果
  这两个接口相比之下,使用FuncAnimation最方便。
  使用matplotlib绘制动画需要安装必要的工具包和程序:需要安装numpy和matplotlib工具包把程序生成的动画保存为mp4格式或gif格式文件,需要安装 ffmpeg   或  imagemagick。
  更详细的内容可阅读文章--《如何把python绘制的动态图形保存为gif文件或视频》实例1:移动的正弦曲线
  代码如下:import numpy as npfrom matplotlib import pyplot as pltfrom matplotlib.animation import FuncAnimationplt.style.use("seaborn-pastel")fig = plt.figure()ax = plt.axes(xlim=(0, 4), ylim=(-2, 2))line, = ax.plot([], [], lw=3)def init():    line.set_data([], [])    return line,def animate(i):    x = np.linspace(0, 4, 1000)    y = np.sin(2 * np.pi * (x - 0.01 * i))    line.set_data(x, y)    return line,anim = FuncAnimation(fig, animate, init_func=init,                               frames=200, interval=20, blit=True)anim.save("sine_wave.gif", writer="imagemagick")
  输出的图形结果如下图所示:
  实例2:螺旋线动画
  代码如下:import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np plt.style.use("dark_background")fig = plt.figure() ax = plt.axes(xlim=(-50, 50), ylim=(-50, 50)) line, = ax.plot([], [], lw=2) #初始化函数 def init(): #创建空的 plot/frame line.set_data([], []) return line, # 存储x轴和y轴坐标值的列表xdata, ydata = [], [] # 定义动画函数 def animate(i): # 参数 t t = 0.1*i # 根据x和y的值绘制图形 x = t*np.sin(t) y = t*np.cos(t) # 把新的x轴和y轴的值追加到列表 xdata.append(x) ydata.append(y) line.set_data(xdata, ydata) return line, # 制定图形的标题plt.title("Creating a growing coil with matplotlib!") # 隐藏x轴上的数据标识 plt.axis("off") # 调用动画函数 anim = animation.FuncAnimation(fig, animate, init_func=init, frames=500, interval=20, blit=True) # 把动画保存为gif文件 anim.save("coil.gif",writer="imagemagick")
  输出结果如下图所示:
  实例3:动画实时更新
  绘制股票行情数据、传感器数据等实时图形就需要实时更新动画。
  代码如下:import matplotlib.pyplot as pltimport matplotlib.animation as animationfig = plt.figure()# 创建子图ax1 = fig.add_subplot(1,1,1)def animate(i):    data = open("stock.txt","r").read()    lines = data.split(" ")    xs = []    ys = []       for line in lines:        x, y = line.split(",") # Delimiter is comma            xs.append(float(x))        ys.append(float(y))           ax1.clear()    ax1.plot(xs, ys)    plt.xlabel("Date")    plt.ylabel("Price")    plt.title("Live graph with matplotlib")    ani = animation.FuncAnimation(fig, animate, interval=1000) plt.show()
  输出结果如下图所示:
  实例4:3D动画
  代码如下:from mpl_toolkits.mplot3d import Axes3Dimport matplotlib.pyplot as pltimport pandas as pdimport seaborn as sns# 获取数据url = "https://python-graph-gallery.com/wp-content/uploads/volcano.csv"data = pd.read_csv(url)# 数据转换df=data.unstack().reset_index()df.columns=["X","Y","Z"]# 转换列名称df["X"]=pd.Categorical(df["X"])df["X"]=df["X"].cat.codes# 以20个不同的角度,绘制20个图形for angle in range(70,210,2):# 绘制图形    fig = plt.figure()    ax = fig.gca(projection="3d")    ax.plot_trisurf(df["Y"], df["X"], df["Z"], cmap=plt.cm.viridis, linewidth=0.2)    ax.view_init(30,angle)    filename="Volcano/Volcano_step"+str(angle)+".png"    plt.savefig(filename, dpi=96)    plt.gca()
  以上代码创建多个PNG格式文件,要使用ImageMagick把这些图片转换为动画,即在命令行窗口输入下命令:convert -delay 10 Volcano*.png animated_volcano.gif
  输出结果如下图:
  实例5:使用Celluloid工具包绘制动画
  Celluloid工具包简化了用matplotlib绘制动画的过程,该工具包只创建一个matplotlib的figure对象和camera对象,然后创建的每一帧画面都重复使用这个figure和camera对象,就像是用照相机在抓拍图形。最后,用所有抓拍的画面帧就构成了动画。
  安装Celluloid工具包:pip install celluloid
  使用celluloid工具包的绘图实例如下:
  实例5-1,代码如下:from matplotlib import pyplot as pltfrom celluloid import Camerafig = plt.figure()camera = Camera(fig)for i in range(10):    plt.plot([i] * 10)    camera.snap()animation = camera.animate()animation.save("celluloid_minimal.gif", writer = "imagemagick")
  输出结果如下图:
  实例5-2:子图,代码如下:import numpy as npfrom matplotlib import pyplot as pltfrom celluloid import Camerafig, axes = plt.subplots(2)camera = Camera(fig)t = np.linspace(0, 2 * np.pi, 128, endpoint=False)for i in t:    axes[0].plot(t, np.sin(t + i), color="blue")    axes[1].plot(t, np.sin(t - i), color="blue")    camera.snap()    animation = camera.animate()  animation.save("celluloid_subplots.gif", writer = "imagemagick")
  输出结果如下图:
  实例5-3:图例,代码如下:import matplotlibfrom matplotlib import pyplot as pltfrom celluloid import Camerafig = plt.figure()camera = Camera(fig)for i in range(20):    t = plt.plot(range(i, i + 5))    plt.legend(t, [f"line {i}"])    camera.snap()animation = camera.animate()animation.save("celluloid_legends.gif", writer = "imagemagick")
  输出结果如下图:
  四、Python - 2D/3D动画案例
  本文以九个ETF基金行情数据为例,绘制出交易这九个基金的收益变化(行情数据有随机数生成)。如果想观察哪只基金的收益高于或低于沪深300ETF,就可以从2D/3D的动画图上看出来。下面分四部分来讲述。导入必要的工具包import numpy as npimport pandas as pd#import csv#from csv import writer# 绘图import matplotlib.pyplot as pltfrom matplotlib import animation, rcfrom matplotlib.cm import get_cmapfrom mpl_toolkits.mplot3d import Axes3Dfrom matplotlib.font_manager import FontPropertiesfrom matplotlib.collections import LineCollectionfrom matplotlib.colors import ListedColormapfrom mpl_toolkits.mplot3d.art3d import Line3DCollectionplt.rcParams["font.sans-serif"] = ["SimHei"]plt.rcParams["axes.unicode_minus"] = Falseimport matplotlib as mpl mpl.rcParams["animation.ffmpeg_path"] = r"C:ffmpegbinffmpeg.exe"# 设置动画类型rc("animation", html="html5")导入数据
  用随机数生成九只ETF基金的行情价格数据index_returns = np.random.normal(loc=1e-4, scale=5e-3, size=(783, 9))index_returns = np.vstack((np.zeros(shape=(1, 9)) + 100, index_returns))# 累计收益index_prices = np.cumprod(1 + index_returns, axis=0)# 选择时间窗口window = 261indexes_rolling = np.zeros(shape=(index_prices.shape[0]-window, 9))# 生成滚动收益for i in range(window, index_prices.shape[0], 1):    indexes_rolling[i-window] = (index_prices[i]/index_prices[i-window]) - 1# 构成 dataframe 数据index = pd.date_range("2019-01-01", periods=index_prices.shape[0]-window, freq="B")columns = ["智能汽车|515250", "新能源车|515030 ", "半 导 体|512480",                  " 银  行 |512800", " 沪深300|510300",  "创 新 药|159992",                  " 光  伏 |515790", "信息技术|159939", "食品饮料|515170"]indexes_rolling = pd.DataFrame(indexes_rolling, index=index, columns=columns)2D动画创建2D动画的规格以及格式,即指定该动画图形的大小,颜色,图例等内容。
  代码如下:# 创建图形fig, axes = plt.subplots(1, 2, figsize=(18, 6), gridspec_kw={"width_ratios": [.9, .1]})fig.patch.set_alpha(1)# 设置:右边的图形不可见,只更新左边部分axes[1].axis("off")ax = axes[0]# 获取 cmap cmap = get_cmap("RdYlGn")# 数据切分current_slice = indexes_rolling.values[:261, :]index_names = indexes_rolling.columnsindex_dates = indexes_rolling.index# 保存各ETF基金数据的列表lines = []for i in range(current_slice.shape[1]):    # 获取坐标    x = np.array(np.arange(current_slice.shape[0]))    y = np.array(current_slice[:, i])    # 绘制不同颜色的点和线段    points = np.array([x, y]).T.reshape(-1, 1, 2)    segments = np.concatenate([points[:-1], points[1:]], axis=1)    # 指定连续值,映射数据点的颜色    norm = plt.Normalize(-0.19, 0.19)    lc = LineCollection(segments, cmap=cmap, norm=norm)    # 设置颜色值    lc.set_array(y)    lc.set_linewidth(2)    lc.set_color(cmap(y[-1] * 2.5 + 0.5))    lc.set_label(index_names[i])    lines.append(ax.add_collection(lc))# 添加背景的网格ax.legend(loc="center right", bbox_to_anchor=(1.2, 0.5), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={"family": "SimHei"})ax.yaxis.grid(color="gray", linestyle="dashed")ax.xaxis.grid(color="gray", linestyle="dashed")ax.set_xlim(0, current_slice.shape[0]-1)ax.set_ylim(-0.39, 0.39)ax.set_yticklabels(["{:.0%}".format(val) for val in ax.get_yticks()])ax.set_ylabel("滚动收益 - 1年")ax.set_xlabel("日 期")ax.set_xticklabels([index_dates[int(val)].strftime("%m/%y") for val in ax.get_xticks()])#ax.set_facecolor((0, 0, 0, 1.0)) # 背景色ax.set_facecolor((0.05, 0.05, 0.65, 1))# 演示图形plt.show()
  演示图形如下:
  2. 定义更新以上2D图形的函数
  代码如下:def update_lines_2D(num, data, columns, dates, cmap, lines, ax):            # 获得切分数据    current_slice = data[num:261+num, :]    current_dates = dates[num:261+num]        for i in range(current_slice.shape[1]):        # 获取坐标值        x = np.array(np.arange(current_slice.shape[0]))        y = np.array(current_slice[:, i])        # 绘制不同颜色的点和线段        points = np.array([x, y]).T.reshape(-1, 1, 2)        segments = np.concatenate([points[:-1], points[1:]], axis=1)        # 指定连续值,映射数据点的颜色        norm = plt.Normalize(-0.22, 0.22)                lines[i].set_segments(segments)        lines[i].set_array(y)        #lines[i].set_color(cmap(y[-1] * 2.5 + 0.5))        lines[i].set_color(cmap(y[-1] * 2.5 + 0.5))        # 动态更新数据和标识    ax.set_xticklabels([dates[int(val)+num].strftime("%m/%y") for val in ax.get_xticks()[:-1]] + [""])    ax.legend(loc="center right", bbox_to_anchor=(1.2, 0.5), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={"family": "SimHei"})          return lines# 初始化图形的各行的数据def init_lines_2D():       for line in lines:        line.set_array([])    return lines
  3.创建2D动画
  代码如下:line_ani = animation.FuncAnimation(fig=fig,                                    func=update_lines_2D,                                    # frames=30,                                   frames=indexes_rolling.shape[0]-261,                                    init_func=init_lines_2D,                                    fargs=(indexes_rolling.values, indexes_rolling.columns, indexes_rolling.index, cmap, lines, ax),                                   interval=75,                                    blit=True)# 演示2D动画line_ani
  演示结果如下图:
  4.保存动画为GIF格式
  代码如下:# 演示数据的变化progress_callback = lambda i, n: print("Saving frame {:.0%}".format(i/n)) if int((i/n) * 100) % 10 == 0 else None# 保存动画line_ani.save("./2D_animation.gif", writer="imagemagick", fps=14, dpi=80, codec="h264", bitrate=2048, progress_callback=progress_callback)3D动画创建3D动画的规格以及格式,即指定该动画图形的大小,颜色,图例等内容。
  代码如下:# 创建图形fig = plt.figure(figsize=(14.4, 9))ax = fig.add_subplot(111, projection="3d")fig.patch.set_alpha(1)# 获得 cmap 的值cmap = get_cmap("RdYlGn")# 切分数据current_slice = indexes_rolling.values[:261, :]index_names = indexes_rolling.columnsindex_dates = indexes_rolling.index# 保存各ETF基金数据的线的列表lines = []for i in range(current_slice.shape[1]):    # 获取坐标值    x = np.array(np.arange(current_slice.shape[0]))    y = np.tile(i, current_slice.shape[0])    z = np.array(current_slice[:, i])    #  绘制不同颜色的点和线段    points = np.array([x, y, z]).T.reshape(-1, 1, 3)    segments = np.concatenate([points[:-1], points[1:]], axis=1)    # 指定连续值,映射数据点的颜色    norm = plt.Normalize(-0.19, 0.19)    lc = Line3DCollection(segments, cmap=cmap, norm=norm, zorder=current_slice.shape[1]-i)    # 动态更新数据和标识    lc.set_array(z)    lc.set_linewidth(2)    lc.set_color(cmap(z[-1] * 2.5 + 0.5))    lc.set_label(index_names[i])    lines.append(ax.add_collection(lc))# 添加动画背景的网格ax.legend(loc="center right", bbox_to_anchor=(1.1, 0.46), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={"family": "SimHei"})ax.set_zlabel("滚动收益 1Y", labelpad=10)ax.set_zlim(-0.39, 0.39)ax.set_zticklabels([" "* 3 + "{:.0%}".format(val) for val in ax.get_zticks()], fontdict={"verticalalignment": "center", "horizontalalignment": "center"})ax.set_xlabel("Date", labelpad=30)ax.set_xlim(0, current_slice.shape[0]-1)ax.set_xticklabels([index_dates[int(val)].strftime("%m/%y") for val in ax.get_xticks()[:-1]] + [""], rotation=0, fontdict={"verticalalignment": "top", "horizontalalignment": "center"})ax.set_yticks(np.arange(current_slice.shape[1]))ax.set_yticklabels([index_names[i] for i in range(current_slice.shape[1])], rotation=-15, fontdict={"verticalalignment": "center", "horizontalalignment": "left"})# ax.w_xaxis.set_pane_color((0, 0, 0, 1.0))# ax.w_yaxis.set_pane_color((0, 0, 0, 1.0))# ax.w_zaxis.set_pane_color((0, 0, 0, 1.0))ax.w_xaxis.set_pane_color((0.05, 0.05, 0.65, 1)) #ax.set_facecolor((0.05, 0.05, 0.65, 1))ax.w_yaxis.set_pane_color((0.05, 0.05, 0.65, 1))ax.w_zaxis.set_pane_color((0.05, 0.05, 0.65, 1))ax.view_init(25, -60)# ------------------------------------------------------------------x_scale=1.8y_scale=1z_scale=1scale=np.diag([x_scale, y_scale, z_scale, 1.0])scale=scale*(1.0/scale.max())scale[3,3]=1.0def short_proj():    return np.dot(Axes3D.get_proj(ax), scale)ax.get_proj=short_projfig.subplots_adjust(left=0, right=1, bottom=0, top=1)# ------------------------------------------------------------------# 输出动画plt.show()
  输出结果如下图所示:
  2. 定义更新以上图形的函数
  代码如下:def update_lines_3D(num, data, columns, dates, cmap, lines, ax):        # 切分数据    current_slice = data[num:261+num, :]    current_dates = dates[num:261+num]         for i in range(current_slice.shape[1]):        # 获取坐标值        x = np.arange(current_slice.shape[0])        y = np.tile(i, current_slice.shape[0])        z = np.array(current_slice[:, i])        #  绘制不同颜色的点和线段        points = np.array([x, y, z]).T.reshape(-1, 1, 3)        segments = np.concatenate([points[:-1], points[1:]], axis=1)        # 指定连续值,映射数据点的颜色        norm = plt.Normalize(-0.19, 0.19)                lines[i].set_segments(segments)        lines[i].set_array(z)        lines[i].set_color(cmap(z[-1] * 2.5 + 0.5))    # 动态更新数据和标识    ax.set_xticklabels([dates[int(val)+num].strftime("%m/%y") for val in ax.get_xticks()[:-1]] + [""], rotation=0, fontdict={"verticalalignment": "top", "horizontalalignment": "center"})    ax.legend(loc="center right", bbox_to_anchor=(1.1, 0.46), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={"family": "SimHei"})        return linesdef init_lines_3D():    for line in lines:        line.set_array([])    return lines
  3.创建3D动画
  代码如下:line_ani = animation.FuncAnimation(fig=fig,                                    func=update_lines_3D,                                    # frames=30,                                   frames=indexes_rolling.shape[0]-261,                                    init_func=init_lines_3D,                                    fargs=(indexes_rolling.values, indexes_rolling.columns, indexes_rolling.index, cmap, lines, ax),                                   interval=75,                                    blit=True)# 演示3D动画line_ani
  演示结果如下图所示:
  4.保存3D动画为GIF格式 progress_callback = lambda i, n: print("Saving frame {:.0%}".format(i/n)) if int((i/n) * 100) % 10 == 0 else None# save the animationline_ani.save("./3D_animation.gif", writer="imagemagick", fps=14, dpi=80, codec="h264", bitrate=2048, progress_callback=progress_callback)3D mesh 动画创建3D mesh 动画的规格以及格式,即指定该动画图形的大小,颜色,图例等内容。
  代码如下:# 创建图形fig = plt.figure(figsize=(14.4, 9))ax = fig.add_subplot(111, projection="3d")fig.patch.set_alpha(1)# 获取 cmap 的值cmap = get_cmap("RdYlGn")# 切分数据# current_slice = indexes_rolling.values[:261, :]current_slice = indexes_rolling.values[:int(261/2), :]index_names = indexes_rolling.columnsindex_dates = indexes_rolling.index# 保存各ETF基金数据的线的列表lines = []for i in range(current_slice.shape[1]):    # 获取坐标值    x = np.array(np.arange(current_slice.shape[0]))    y = np.tile(i, current_slice.shape[0])    z = np.array(current_slice[:, i])    # 绘制不同颜色的点和线段    points = np.array([x, y, z]).T.reshape(-1, 1, 3)    segments = np.concatenate([points[:-1], points[1:]], axis=1)    # 指定连续值,映射数据点的颜色    norm = plt.Normalize(-0.19, 0.19)    lc = Line3DCollection(segments, cmap=cmap, norm=norm, zorder=current_slice.shape[1]-i)    # 设定颜色值    lc.set_array(z)    lc.set_linewidth(2)    lc.set_color(cmap(z[-1] * 2.5 + 0.5))    lc.set_label(index_names[i])    lines.append(ax.add_collection(lc))# 保存 mesh 线的列表mesh_lines = []for j in range(current_slice.shape[0]):    if j % 1 == 0:                # 获取坐标值        x = np.tile(j, current_slice.shape[1])        y = np.arange(current_slice.shape[1])        z = np.array(current_slice[j, :])        # 绘制不同颜色的点和线段        points = np.array([x, y, z]).T.reshape(-1, 1, 3)        segments = np.concatenate([points[:-1], points[1:]], axis=1)        # 指定连续值,映射数据点的颜色        norm = plt.Normalize(-0.19, 0.19)        lc = Line3DCollection(segments, cmap=cmap, norm=norm)        # 设定颜色值        lc.set_array(z)        lc.set_linewidth(2)        mesh_lines.append(ax.add_collection(lc))    # 添加 mesh 动画的背景网格ax.legend(loc="center right", bbox_to_anchor=(1.1, 0.46), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={"family": "SimHei"})ax.set_zlabel("Rolling Equity 1Y", labelpad=10)ax.set_zlim(-0.39, 0.39)ax.set_zticklabels([" "* 3 + "{:.0%}".format(val) for val in ax.get_zticks()], fontdict={"verticalalignment": "center", "horizontalalignment": "center"})ax.set_xlabel("Date", labelpad=30)ax.set_xlim(0, current_slice.shape[0]-1)ax.set_xticklabels([index_dates[int(val)].strftime("%m/%y") for val in ax.get_xticks()[:-1]] + [""], rotation=0, fontdict={"verticalalignment": "top", "horizontalalignment": "center"})ax.set_yticks(np.arange(current_slice.shape[1]))ax.set_yticklabels([index_names[i]for i in range(current_slice.shape[1])], rotation=-15, fontdict={"verticalalignment": "center", "horizontalalignment": "left"})ax.w_xaxis.set_pane_color((0.05, 0.05, 0.65, 1))ax.w_yaxis.set_pane_color((0.05, 0.05, 0.65, 1))ax.w_zaxis.set_pane_color((0.05, 0.05, 0.65, 1)) # (0.05, 0.05, 0.65, 1)ax.view_init(25, -60)# ------------------------------------------------------------------x_scale=1.8y_scale=1z_scale=1scale=np.diag([x_scale, y_scale, z_scale, 1.0])scale=scale*(1.0/scale.max())scale[3,3]=1.0def short_proj():    return np.dot(Axes3D.get_proj(ax), scale)ax.get_proj=short_projfig.subplots_adjust(left=0, right=1, bottom=0, top=1)# ------------------------------------------------------------------# 输出图形plt.show()
  输出结果如下图所示:
  2.定义更新以上图形的函数
  代码如下:def update_mesh_lines_3D(num, data, columns, dates, cmap, lines, mesh_lines, ax):            # 切分数据    current_slice = data[num:int(261/2)+num, :]         for i in range(current_slice.shape[1]):        # 获取坐标值        x = np.arange(current_slice.shape[0])        y = np.tile(i, current_slice.shape[0])        z = np.array(current_slice[:, i])        # 绘制不同颜色的点和线段        points = np.array([x, y, z]).T.reshape(-1, 1, 3)        segments = np.concatenate([points[:-1], points[1:]], axis=1)        # 指定连续值,映射数据点的颜色        norm = plt.Normalize(-0.19, 0.19)                lines[i].set_segments(segments)        lines[i].set_array(z)        lines[i].set_color(cmap(z[-1] * 2.5 + 0.5))    # 通过计数检查当前的mesh线    counter = 0           for j in range(current_slice.shape[0]):        if j % 1 == 0:                                    # 获取坐标值            x = np.tile(j, current_slice.shape[1])            y = np.arange(current_slice.shape[1])            z = np.array(current_slice[j, :])            # 绘制不同颜色的点和线段            points = np.array([x, y, z]).T.reshape(-1, 1, 3)            segments = np.concatenate([points[:-1], points[1:]], axis=1)            # 设定 mesh 线的颜色值            norm = plt.Normalize(-0.22, 0.22)                    mesh_lines[counter].set_segments(segments)            mesh_lines[counter].set_array(z)            counter += 1            # 动态更新数据和标识    ax.set_xticklabels([dates[int(val)+num].strftime("%m/%y") for val in ax.get_xticks()[:-1]] + [""], rotation=0, fontdict={"verticalalignment": "top", "horizontalalignment": "center"})    ax.legend(loc="center right", bbox_to_anchor=(1.1, 0.46), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={"family": "SimHei"})        return linesdef init_mesh_lines_3D():    for line in lines:        line.set_array([])    return lines
  3.创建3D mesh 动画
  代码如下:line_ani = animation.FuncAnimation(fig=fig,                                    func=update_mesh_lines_3D,                                    # frames=30,                                   frames=indexes_rolling.shape[0]-int(261/2),                                   init_func=init_mesh_lines_3D,                                    fargs=(indexes_rolling.values, indexes_rolling.columns, indexes_rolling.index, cmap, lines, mesh_lines, ax),                                   interval=100,                                    blit=True)# 演示动画line_ani
  演示结果如下图所示:

罗斯战靴,真的没人穿了吗?今年618活动中,罗斯的DRose系列是adidas中售卖的鞋款最多的。售卖的都是当年大名鼎鼎的鞋款,例如adidasDRose1。5,罗斯成为史上最年轻MVP赛季的MVP战靴。2一亿年后,人类的命运会是怎么样的,未来该走向何方?地球是一颗美丽的生命星球,数百万年前,人类诞生了,经过不断的进化和发展才有了现代的科技文明。人类走进科技发展的道路之后,科学家对地球的历史开始了一些研究,发现地球可能存在过史前文明温室效应及其影响1温室效应温室效应,又称花房效应,是大气保温效应的俗称。大气能使太阳短波辐射到达地面,但地表受热后向外放出的大量长波热辐射线却被大气吸收,这样就使地表与低层大气温度增高,因其作用类NASA将巨型月球火箭运回发射台进行第二次湿式彩排据CNET报道,对于位于佛罗里达州肯尼迪航天中心的美国宇航局(NASA)探索地面系统团队来说,周一晚上是一个漫长的夜晚。工作人员在黑暗中工作,将ArtemisI巨型月球火箭从其室内如果618你正要买一台华为手机,我来告诉你这么选最近个人想要购买一台华为手机,研究了很多型号,所以对于价格等了解得也比较多,所以如果你也正在选一台华为,可以这么来选京东华为手机界面其实想要看华为目前在售的手机有哪些,打开京东搜一又一款开放式无线耳机!JVCKENWOOD发布HANP35T日本音频厂商JVCKENWOOD旗下品牌VictorStudio在近期公布了全新无线耳机系列Nearphones。而该系列的首款耳机就是HANP35T。和一般蓝牙耳机大多采用入耳式购机教你简单选择荣耀70Pro小米12Pro以及vivoX80Pro顶流机型最难选择的地方是在于它们的价格非常的相似,但是在性能方面差别也没有大家想象的那么高。那么,如何选择高端的旗舰手机?特别是在618时期,这确实是一个难题。我们今天就和大家一起煮荷包蛋时,最忌直接下锅,教你一招,鸡蛋又圆又嫩,很多人不会荷包蛋是一道传统美食,它的由来已久,具体时间已经无法考证,因为它的外观漂亮,口感嫩滑,所以成为了家家户户都很喜欢的一种美味。虽然荷包蛋看似极为简单,但是很多人在煮荷包蛋的时候,不是我科学家建立并命名西湾生物群我科学家建立并命名西湾生物群揭示迄今最古老昆虫婚飞和资源脉冲效应光明日报南京6月4日电(记者苏雁通讯员姬尊雨)近期,中国科学院南京地质古生物研究所(以下简称中科院南古所)博士生张前煮鸡蛋多1分钟都不行!一个实验告诉你为什么每个人心中都有一颗完美的煮鸡蛋。时间长短不同,煮出来的蛋也不同。它可能是温泉蛋溏心蛋全熟蛋那鸡蛋煮多久最好呢?执行力超级强的我们,就亲自做了实验豁出了全部家当实验步骤烧开一锅水,把数据指标体系建设和数据仓库搭建与可视化一数据指标体系建设方法01hr数据数据是指未经过处理的原始记录。数据的本质是利用数学观察记录理解世界数据分析的过程就是人类从定性到定量模糊到精准过程。大家都喜欢看数据,而不是通过一
积石山公安文联向往向往文马如林向往是一种坚守初心的力量向往让我们以开阔的视野宽广的胸襟去开启美好的梦想向往用美好的未来温暖我们的内心让我们坚持寻找的脚步在迷茫中找到前进的方向人民警察的向往是为国献身四季更迭,贵应唯一春夏秋冬,四季轮回,是大自然赐予人间最美丽的景色。春日花儿香,夏日阳儿照,秋日叶儿光,冬日雪儿霜。描写四季的优美诗句很多很多,就像变化着的四季,各有美感,魅力无穷,前人之述备矣。我DK陪生病RNG热手,粉丝秀R联合你帮我做掉大飞,我帮你干chovy关注残影游戏,看LOL最新资讯,今天咱们聊聊秀R联合的这件事在八强投票出来之后,相信大家对于这四场比赛都有了自己的预测,JDG对阵RGE,毫无悬念会是JDG晋级RNG对阵T1,如果向限价联盟开战!石油美元翻船,美国霸权坍塌,中东大可拥抱东方向限价联盟开战!这国总统访俄表明,美国的中东霸权地位正在坍塌。日前,国际产油国组织欧佩克在奥地利维也纳举行的一次部长级会议,被国际社会认为是向美欧限价联盟开战的会议。期间,各成员国宝宝晚上睡得熟你会给他换尿不湿吗?看到有很多妈妈问,宝宝晚上睡着了,又发现他的纸尿裤湿了,那到底要不要给宝宝换了?很多妈妈担心的是,如果不给宝宝换尿布湿,就很容易导致宝宝红屁屁。可是宝宝好不容易哄睡了,换尿不湿把他如何与青春期的孩子相处?这12条沟通技巧值得借鉴应该怎么和青春期的孩子相处?这是困扰不少父母的难题。这一时期,这些半大的孩子们从身体到心理都在急剧发生变化,渴望成人,但其阅历和成熟度又局限着他们的成长方式。青春期的孩子们尤其需要小明Q2Pro投影仪发布真1080p800流明,1699元IT之家10月17日消息,小明Q2Pro投影仪现已发布,真1080p物理分辨率800ANSI流明,首发1699元。据官方介绍,小明Q2Pro投影仪用于800ANSI流明,相比上代提如果S12LPL再夺冠会带来什么样的影响?本月8日,英雄联盟S12全球总决赛正式打响,这无疑是全球LOL粉丝们每年最津津乐道的赛事。早在入围赛阶段网友们就已经充分发挥想象力,开始猜测一个月后的最终冠军。究竟是LCK夺冠,重恒大负债超过2万亿元,为何不破产?10月财经新势力恒大陷入债务问题,拖欠总额超过3000亿美元。实际上,不仅是2021年的恒大资金断裂出现暴雷,而且在2017年的下半年也无缘无故地违约了合同。从其负债收入比来看,杠给接下来买房的人三个忠告,避免买房踩雷过去的房地产市场火爆程度不言而喻,很多人通过买房资产得到了保障,有些人甚至通过投资房产实现了财务自由,这让人们对于买房这件事深信不疑,坚信房价是永涨不跌的存在,这种观点可以说持续了人活着有点兴致,才能说不负此生人活着,就得有点兴致,一定要爱着点什么,恰似草木对光阴的钟情。积极向上,随心而活,不要着急,慢慢就活出了趣味和自我。有人闲暇时喜欢逛逛公园,有人喜欢养宠物,有的人爱侍弄花草,有人喜