【Python百日进阶-数据分析】Day229 - plotly的动画

news2024/9/22 15:33:28

文章目录

  • 一、动画
    • 1.1 基本动画
    • 1.2 使用 Plotly Express 制作动画条形图
    • 1.3 当前动画限制和注意事项
  • 二、为动画添加控制按钮
    • 2.1 简单的播放按钮
    • 2.2 曲线上的移动点
    • 2.3 沿平面曲线移动 Frenet 框架
    • 2.4 使用滑块和按钮
  • 三、MRI 体积切片的可视化

一、动画

使用 Plotly Express 制作的动画
几个Plotly Express 函数支持通过animation_frame和animation_group参数创建动画图形。

这是使用 Plotly Express 创建的动画散点图示例。请注意,您应该始终修复x_range和y_range以确保您的数据在整个动画过程中保持可见。

1.1 基本动画

import plotly.express as px
df = px.data.gapminder()
fig = px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animation_group="country",
           size="pop", color="continent", hover_name="country",
           log_x=True, size_max=55, range_x=[100,100000], range_y=[25,90])
fig.show()

在这里插入图片描述

1.2 使用 Plotly Express 制作动画条形图

请注意,您应该始终修复y_range以确保您的数据在整个动画过程中保持可见。

import plotly.express as px

df = px.data.gapminder()

fig = px.bar(df, x="continent", y="pop", color="continent",
  animation_frame="year", animation_group="country", range_y=[0,4000000000])
fig.show()

在这里插入图片描述

1.3 当前动画限制和注意事项

  • 当每一行输入都存在于所有动画帧中,并且当映射到符号、颜色和构面的分类值在帧中保持不变时,动画设计得很好。如果不满足这些约束,动画可能会产生误导或不一致。
  • 尽管 Plotly Express 支持许多图表和地图类型的动画,但如今平滑的帧间过渡仅适用于scatter和bar
  • Plotly Express不会自动计算所有 x/y/颜色范围的并集,因此必须手动指定这些范围以避免跨帧的比例跳跃

二、为动画添加控制按钮

您可以通过将updatemenus数组添加layout到figure. Plotly 的updatemenus参考资料中提供了有关按钮样式和位置的更多信息。
按钮定义如下:

"updatemenus": [{"type": "buttons",
                 "buttons": [{"label": "Your Label",
                              "method": "animate",
                              "args": [See Below]}]}]

定义按钮参数

  • None:设置"args"为 undefined (ie “args”: [None]) 将创建一个简单的播放按钮,该按钮将为所有帧设置动画。
  • string:使用 group 为所有帧设置动画""。这是一种确定动画范围的方法,以防您希望在不显式枚举所有帧的情况下进行动画处理。
  • [“frame1”, “frame2”, …]:动画一系列命名帧。
  • [{data: [], layout: {}, traces: []}, {…}]:几乎与动画命名帧相同;尽管此变体允许您内联数据而不是将其添加为命名帧。这对于不需要为临时更改添加和管理命名帧的交互很有用。
  • [null]:创建暂停按钮的简单方法(需要mode: “immediate”)。此参数转储当前排队的帧 ( mode: “immediate”),然后为空的帧序列 ( [null]) 设置动画。
  • 请注意:我们不建议使用:[ ]. 这种语法可能会引起混淆,因为它看起来与“暂停按钮”没有区别,但嵌套属性具有将空数组视为完全可移动的逻辑,因此它将用作播放按钮。

2.1 简单的播放按钮

import plotly.graph_objects as go

fig = go.Figure(
    data=[go.Scatter(x=[0, 1], y=[0, 1])],
    layout=go.Layout(
        xaxis=dict(range=[0, 5], autorange=False),
        yaxis=dict(range=[0, 5], autorange=False),
        title="开始标题",
        updatemenus=[dict(
            type="buttons",
            buttons=[dict(label="Play",
                          method="animate",
                          args=[None])])]
    ),
    frames=[go.Frame(data=[go.Scatter(x=[1, 2], y=[1, 2])]),
            go.Frame(data=[go.Scatter(x=[1, 4], y=[1, 4])]),
            go.Frame(data=[go.Scatter(x=[3, 4], y=[3, 4])],
                     layout=go.Layout(title_text="最终标题"))]
)

fig.show()

在这里插入图片描述

2.2 曲线上的移动点

import plotly.graph_objects as go

import numpy as np

# 生成曲线数据
t = np.linspace(-1, 1, 100)
x = t + t ** 2
y = t - t ** 2
xm = np.min(x) - 1.5
xM = np.max(x) + 1.5
ym = np.min(y) - 1.5
yM = np.max(y) + 1.5
N = 50
s = np.linspace(-1, 1, N)
xx = s + s ** 2
yy = s - s ** 2


# Create figure
fig = go.Figure(
    data=[go.Scatter(x=x, y=y,
                     mode="lines",
                     line=dict(width=2, color="blue")),
          go.Scatter(x=x, y=y,
                     mode="lines",
                     line=dict(width=2, color="blue"))],
    layout=go.Layout(
        xaxis=dict(range=[xm, xM], autorange=False, zeroline=False),
        yaxis=dict(range=[ym, yM], autorange=False, zeroline=False),
        title_text="平面曲线的运动学生成绩", hovermode="closest",
        updatemenus=[dict(type="buttons",
                          buttons=[dict(label="Play",
                                        method="animate",
                                        args=[None])])]),
    frames=[go.Frame(
        data=[go.Scatter(
            x=[xx[k]],
            y=[yy[k]],
            mode="markers",
            marker=dict(color="red", size=10))])

        for k in range(N)]
)

fig.show()

在这里插入图片描述

2.3 沿平面曲线移动 Frenet 框架

import plotly.graph_objects as go

import numpy as np


# 生成曲线数据
t = np.linspace(-1, 1, 100)
x = t + t ** 2
y = t - t ** 2
xm = np.min(x) - 1.5
xM = np.max(x) + 1.5
ym = np.min(y) - 1.5
yM = np.max(y) + 1.5
N = 50
s = np.linspace(-1, 1, N)
xx = s + s ** 2
yy = s - s ** 2
vx = 1 + 2 * s
vy = 1 - 2 * s  # v=(vx, vy) is the velocity
speed = np.sqrt(vx ** 2 + vy ** 2)
ux = vx / speed  # (ux, uy) unit tangent vector, (-uy, ux) unit normal vector
uy = vy / speed

xend = xx + ux  # (xx,yy)处单位切线向量的终点坐标
yend = yy + uy

xnoe = xx - uy  # (xx,yy)处单位法向量的结束坐标
ynoe = yy + ux


# Create figure
fig = go.Figure(
    data=[go.Scatter(x=x, y=y,
                     name="frame",
                     mode="lines",
                     line=dict(width=2, color="blue")),
          go.Scatter(x=x, y=y,
                     name="curve",
                     mode="lines",
                     line=dict(width=2, color="blue"))
          ],
    layout=go.Layout(width=600, height=600,
                     xaxis=dict(range=[xm, xM], autorange=False, zeroline=False),
                     yaxis=dict(range=[ym, yM], autorange=False, zeroline=False),
                     title="沿平面曲线移动Frenet帧",
                     hovermode="closest",
                     updatemenus=[dict(type="buttons",
                                       buttons=[dict(label="Play",
                                                     method="animate",
                                                     args=[None])])]),

    frames=[go.Frame(
        data=[go.Scatter(
            x=[xx[k], xend[k], None, xx[k], xnoe[k]],
            y=[yy[k], yend[k], None, yy[k], ynoe[k]],
            mode="lines",
            line=dict(color="red", width=2))
        ]) for k in range(N)]
)

fig.show()

在这里插入图片描述

2.4 使用滑块和按钮

以下示例使用众所周知的Gapminder 数据集来举例说明动画功能。这个气泡图动画显示了从 1952 年到 2007 年,几个国家的“人均 GDP”相对于“预期寿命”的变化,按各自的大陆着色并按人口大小排列。

这也是将图形结构构建为 Python 字典,然后从该字典构造图形对象图形的示例。

import plotly.graph_objects as go

import pandas as pd

url = "https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv"
dataset = pd.read_csv('f:/gapminderDataFiveYear.csv')

years = ["1952", "1962", "1967", "1972", "1977", "1982", "1987", "1992", "1997", "2002",
         "2007"]

# make list of continents
continents = []
for continent in dataset["continent"]:
    if continent not in continents:
        continents.append(continent)
# make figure
fig_dict = {
    "data": [],
    "layout": {},
    "frames": []
}

# fill in most of layout
fig_dict["layout"]["xaxis"] = {"range": [30, 85], "title": "Life Expectancy"}
fig_dict["layout"]["yaxis"] = {"title": "GDP per Capita", "type": "log"}
fig_dict["layout"]["hovermode"] = "closest"
fig_dict["layout"]["updatemenus"] = [
    {
        "buttons": [
            {
                "args": [None, {"frame": {"duration": 500, "redraw": False},
                                "fromcurrent": True, "transition": {"duration": 300,
                                                                    "easing": "quadratic-in-out"}}],
                "label": "Play",
                "method": "animate"
            },
            {
                "args": [[None], {"frame": {"duration": 0, "redraw": False},
                                  "mode": "immediate",
                                  "transition": {"duration": 0}}],
                "label": "Pause",
                "method": "animate"
            }
        ],
        "direction": "left",
        "pad": {"r": 10, "t": 87},
        "showactive": False,
        "type": "buttons",
        "x": 0.1,
        "xanchor": "right",
        "y": 0,
        "yanchor": "top"
    }
]

sliders_dict = {
    "active": 0,
    "yanchor": "top",
    "xanchor": "left",
    "currentvalue": {
        "font": {"size": 20},
        "prefix": "Year:",
        "visible": True,
        "xanchor": "right"
    },
    "transition": {"duration": 300, "easing": "cubic-in-out"},
    "pad": {"b": 10, "t": 50},
    "len": 0.9,
    "x": 0.1,
    "y": 0,
    "steps": []
}

# make data
year = 1952
for continent in continents:
    dataset_by_year = dataset[dataset["year"] == year]
    dataset_by_year_and_cont = dataset_by_year[
        dataset_by_year["continent"] == continent]

    data_dict = {
        "x": list(dataset_by_year_and_cont["lifeExp"]),
        "y": list(dataset_by_year_and_cont["gdpPercap"]),
        "mode": "markers",
        "text": list(dataset_by_year_and_cont["country"]),
        "marker": {
            "sizemode": "area",
            "sizeref": 200000,
            "size": list(dataset_by_year_and_cont["pop"])
        },
        "name": continent
    }
    fig_dict["data"].append(data_dict)

# make frames
for year in years:
    frame = {"data": [], "name": str(year)}
    for continent in continents:
        dataset_by_year = dataset[dataset["year"] == int(year)]
        dataset_by_year_and_cont = dataset_by_year[
            dataset_by_year["continent"] == continent]

        data_dict = {
            "x": list(dataset_by_year_and_cont["lifeExp"]),
            "y": list(dataset_by_year_and_cont["gdpPercap"]),
            "mode": "markers",
            "text": list(dataset_by_year_and_cont["country"]),
            "marker": {
                "sizemode": "area",
                "sizeref": 200000,
                "size": list(dataset_by_year_and_cont["pop"])
            },
            "name": continent
        }
        frame["data"].append(data_dict)

    fig_dict["frames"].append(frame)
    slider_step = {"args": [
        [year],
        {"frame": {"duration": 300, "redraw": False},
         "mode": "immediate",
         "transition": {"duration": 300}}
    ],
        "label": year,
        "method": "animate"}
    sliders_dict["steps"].append(slider_step)


fig_dict["layout"]["sliders"] = [sliders_dict]

fig = go.Figure(fig_dict)

fig.show()

在这里插入图片描述

三、MRI 体积切片的可视化

# 导入数据
import time
import numpy as np

from skimage import io
# 'https://s3.amazonaws.com/assets.datacamp.com/blog_assets/attention-mri.tif'
vol = io.imread("f:/attention-mri.tif")
volume = vol.T
r, c = volume[0].shape

# 定义框架
import plotly.graph_objects as go
nb_frames = 68

fig = go.Figure(frames=[go.Frame(data=go.Surface(
    z=(6.7 - k * 0.1) * np.ones((r, c)),
    surfacecolor=np.flipud(volume[67 - k]),
    cmin=0, cmax=200
    ),
    name=str(k) # 需要命名帧,动画才能正常运行
    )
    for k in range(nb_frames)])

# 添加动画开始前要显示的数据
fig.add_trace(go.Surface(
    z=6.7 * np.ones((r, c)),
    surfacecolor=np.flipud(volume[67]),
    colorscale='Gray',
    cmin=0, cmax=200,
    colorbar=dict(thickness=20, ticklen=4)
    ))


def frame_args(duration):
    return {
            "frame": {"duration": duration},
            "mode": "immediate",
            "fromcurrent": True,
            "transition": {"duration": duration, "easing": "linear"},
        }

sliders = [
            {
                "pad": {"b": 10, "t": 60},
                "len": 0.9,
                "x": 0.1,
                "y": 0,
                "steps": [
                    {
                        "args": [[f.name], frame_args(0)],
                        "label": str(k),
                        "method": "animate",
                    }
                    for k, f in enumerate(fig.frames)
                ],
            }
        ]

# Layout
fig.update_layout(
         title='体积数据中的切片',
         width=600,
         height=600,
         scene=dict(
                    zaxis=dict(range=[-0.1, 6.8], autorange=False),
                    aspectratio=dict(x=1, y=1, z=1),
                    ),
         updatemenus = [
            {
                "buttons": [
                    {
                        "args": [None, frame_args(50)],
                        "label": "▶", # play symbol
                        "method": "animate",
                    },
                    {
                        "args": [[None], frame_args(0)],
                        "label": "◼", # pause symbol
                        "method": "animate",
                    },
                ],
                "direction": "left",
                "pad": {"r": 10, "t": 70},
                "type": "buttons",
                "x": 0.1,
                "y": 0,
            }
         ],
         sliders=sliders
)

fig.show()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/171851.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

23种设计模式(九)——抽象工厂模式【对象创建】

文章目录 意图什么时候使用抽象工厂真实世界类比解决方案抽象工厂模式的实现抽象工厂模式的优缺点亦称: Abstract Factory 意图 抽象工厂是创建型设计模式,它强调了一系列相关产品对象(属于同一个产品族)的创建过程,它和工厂方法模式的侧重点不同,工厂方法模式更加侧重于…

JUC面试(四)——ABA问题

ABA问题 从AtomicInteger引出下面的问题 CAS -> Unsafe -> CAS底层思想 -> ABA -> 原子引用更新 -> 如何规避ABA问题 假设现在有两个线程,分别是T1 和 T2,然后T1执行某个操作的时间为10秒,T2执行某个时间的操作是2秒&#…

Python---人生重开模拟器(简版)

专栏:python 个人主页:HaiFan. 专栏简介:本专栏主要更新一些python的基础知识,也会实现一些小游戏和通讯录,学时管理系统之类的,有兴趣的朋友可以关注一下。 人生重开模拟器思维导图前言一、设置初始属性1.…

〖百宝书-思维锻炼③〗——三心理论——成功的来源

大家好,我是涵子,今天我们来聊聊三心理论。 💬 人生格言:Stay foolish, stay kind.💬 📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 &a…

Ae 效果详解:CC Snowfall

效果/模拟/CC SnowfallEffects/Simulation/CC Snowfall示例CC Snowfall (下雪效果),可用来模拟带景深、光效和运动模糊的下雪效果。Flakes 雪花片数用于设置雪花片的数量。默认值 10000。Size 大小用于设置雪花片的大小。默认值 3.00。Variat…

连续系统PID的Simulink仿真-3

利用简化S函数,实现连续系统PID的Simulink仿真-2中S函数同样的功能。利用S函数简化形式实现被控对象的表达、控制器的设计及仿真结果的输出。在简化S函数中,flag-0时为S函数初始化,其中 sys包括6个参数:第1个参数表示连续系统的阶数;第2个参数…

DBCO-PEG-4ARM,四臂聚乙二醇二苯基环辛炔,4Arm PEG-DBCO

●中文名:四臂-聚乙二醇-二苯基环辛炔 ●英文名:4Arm PEG-DBCO,DBCO PEG 4ARM ●外观以及性质: ​4Arm PEG-DBCO产物呈固体或粘性液体,取决于PEG分子量,高分子DBCO功能化PEG,“点击化学"…

【JavaScript】事件相关知识详解

💻 【JavaScript】事件相关知识详解🏠专栏:JavaScript 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向:目前主攻前端…

CES 2023:高通从移动互联深入布局未来智驾

作为全球规模最大、影响最为广泛的国际消费电子展,CES曾经因为三年疫情而无奈中断,如今终于在2023年1月重返美国拉斯维加斯。而不管是CES 2023的3200多家参展企业,还是数量超过10万的现场观众,当他们走出位于拉斯维加斯会议中心西…

02Docker镜像

Docker基础2(镜像) 一、Docker镜像介绍 1.1 简介 镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配…

《Buildozer打包实战指南》第六节 buildozer.spec配置文件中的其他参数

目录 android.permissions android.features android.api android.minapi android.sdk android.ndk android.ndk_api android.private_storage android.ndk_path android.sdk_path android.ant_path android.skip_update android.accept_sdk_license android.a…

【Linux】基础:线程的概念

【Linux】基础:线程的概念 摘要:本文介绍Linux下的线程概念,首先将会线程在系列教材中的定义进行抛出,从常规的操作系统进行理解线程的概念,在具体说明Linux下的进线程的管理与组织方式,以及由于该组织方式…

2022年度笔记本十大热门品牌销量排行榜

近年来,由于大环境的改变,线上教育、线上办公等的需求使得平板电脑出货量逐步提升。同时,5G时代来临,万物互联是未来的趋势,手机由于操作系统和交互上的局限性,笔记本电脑将会扮演更加重要的角色。未来&…

Arduino开发ESP8266连接无线路由器

实现ESP8266连接一个WIFI路由器ESP8266选择多个路由器中信号将强的进行连接源代码如下/* ESP8266模块连接网络实验1、代码段1实现连接无线路由器实验2、代码段2实现esp8266搜索已存在网络中质量较好的并进行连接*/#include <ESP8266WiFi.h> // 提供 Wi-Fi 功能的库#inclu…

监控安防人员入门基础

1、 决定视频流畅程度的是以下哪个属性&#xff1f; A、分辨率 B、率上限 C、帧率 D、编码方式 题解&#xff1a;一幅完整的视频画面为一帧&#xff0c;每秒显示的帧的数目为帧率&#xff0c;帧率越高&#xff0c;视频更流畅。因此答案是&#xff1a;C 2、 关于图像分辨率和…

solr业务域配置

SolrSolr作为一个Java开发的高性能&#xff0c;用于对查询性能进行优化的全文搜索服务器&#xff0c;它的使用需要配置业务域&#xff1a;第一步是添加中文分析器上传中文分析器并解压&#xff0c;复制jar包到solr的lib文件夹下&#xff1a;cp IKAnalyzer2012FF_u1.jar /usr/lo…

FA-PEG-DBCO,DBCO-PEG-Folate,叶酸聚乙二醇环辛炔

●中文名&#xff1a;叶酸聚乙二醇环辛炔&#xff0c;叶酸聚乙二醇二苯基环辛炔&#xff0c;DBCO-PEG-叶酸 ●英文名&#xff1a;FA-PEG-DBCO &#xff0c; Folate-PEG-DBCO&#xff0c;DBCO-PEG- FA&#xff0c;DBCO-PEG-Folate&#xff0c;DBCO-PEG- Folic acid ●外观以及…

使用集简云将UpTimer同步到Notion

使用UpTimer同步到Notion 对于集简云我们应当非常熟悉了&#xff0c;之前讲过很多流程啦~ 利用集简云将Notion数据库更新订阅到Outlook和微信[1] 【干货分享】集简云 2步轻松定制个人RSS阅读器 |高效获取信息[2] 释放双手|自动化NOTION的最佳平台推荐|NOTION同步滴答清单|懒人[…

【人工智能原理自学】高维空间:机器如何面对越来越复杂的问题

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;笔记来自B站UP主Ele实验室的《小白也能听懂的人工智能原理》。 &#x1f514;本文讲解高维空间&#xff1a;机器如何面对越来越复杂的问题&#xff0c;一起卷起来叭&#xff01…

使用TortoiseGit同步项目到GitHub简单教程

1.TortoiseGit简介与安装 TortoiseGit是Git的Windows桌面可视化工具&#xff0c;通过软件的操作来实现git命令的效果&#xff0c;对git小白较友好。TortoiseGit可以通过官网https://tortoisegit.org/下载&#xff0c;下载之后即可按照普通软件的方式进行安装&#xff0c;每一步…