Plotly与Python:如何使用帧和滑块绘制两个热图?

huangapple go评论69阅读模式
英文:

Plotly with python: how to plot two heatmaps using frames and slider?

问题

我需要帮忙在Python中创建一个复合动画的Plotly图表。

这个代码接受两个numpy数组,数组包含两个维度(数组的数组,而不是矩阵),这些数组包含空值,并将它们绘制为热图。相对简单,coloraxis行只是为了正确放置颜色刻度条。

我能制作需要的动态/动画图表的一半,只显示在 "double_hm_plot" 中的一个热图,使用了如下的滑块: (results: Single dynamic chart)

英文:

I need help creating a composite animated plotly chart in python.

The static version of such chart would be something like this
Double static chart, which is done with the following code in python:

def double_hm_plot(vec1, vec2):
    fig = plotly.subplots.make_subplots(rows=1, cols=2, shared_yaxes=True, shared_xaxes=True)
    fig.add_trace(go.Heatmap(z=vec1.T, coloraxis='coloraxis1'), row=1, col=1)
    fig.add_trace(go.Heatmap(z=vec2.T, coloraxis='coloraxis2'), row=1, col=2)
    fig.update_layout(
        legend=dict(x=0.5, xanchor='center', y=1, yanchor='bottom', orientation='h'),
        coloraxis1=dict(colorscale='jet', colorbar_x=-0.20, colorbar_thickness=10),
        coloraxis2=dict(colorscale='jet', colorbar_x=1.00, colorbar_thickness=10),
        width=600, height=700)
    fig.show()

double_hm_plot(files['gas'][-1], files['solid'][-1])

The code takes two numpy arrays with two dimensions (arrays of arrays, not matrices) which contain null values and plot them as heatmaps. Relatively simple, and the coloraxis lines are just for placing the colorscales bars correctly.

I was able to make the only half of the dynamic/animated chart which I need, with only one of the heatmaps shown in "double_hm_plot", using a slider such as follows: (results: Single dynamic chart)

structure = files['gas'][1:]
min_scale, max_scale = np.min(np.min(np.min(structure))), np.max(np.max(np.max(structure)))
frames = [go.Frame(data=go.Heatmap(z=frame.T, colorscale='Turbo', 
                                   zauto=False,
                                   zmin=min_scale, zmax=max_scale
                                   ), name=i) for i, frame in enumerate(structure)]

go.Figure(data=frames[0].data, frames=frames).update_layout(
    sliders=[{"steps": [{"args":[[f.name],{"frame": {"duration": 0, "redraw": True}, "mode": "immediate",},],
                         "label":f.name, "method": "animate",}
                        for f in frames],}],
    height=600, width=300,
    yaxis={"title": 'y [m/10]'},
    xaxis={"title": 'r [m/10]', 'side': 'top'},
    title_x=0.5,
)

This second code works with one more dimension for time, and plots roughly the same way.

How could i use two side by side plots (such as in "double_hm_plot") with this slider?

I've tried a lot of things and nothing seems to work. Things like: composing frames with multiple "go.heatmap" objects, using multiple frames in the figure etc.

On the documentations I did not find much help also.

Is there any help, is this even possible?

Files for example testing: https://drive.google.com/drive/folders/1Vpt_HfJxCsYoghvwerzfHEpJAq6MJHE1?usp=share_link

EDIT:

Data loading:

# Processed loading
files = {
    'gas': np.load('gas.npy'), #insert here the path on your OS
    'solid': np.load('solid.npy')
}

答案1

得分: 0

我在Plotly社区找到了在线图的子图上使用滑块的示例,所以我根据此示例基于你的数据创建了一个带有滑块的子图。关键是由于有两个子图,控制显示内容的单位也是两个。控制显示和隐藏的列表每2个真单位滑动一次。为了运行500个图,也需要大量的CPU计算能力,所以我将它减少到50个图。

import numpy as np
import plotly.subplots
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 处理加载
files = {
    'gas': np.load('./data/gas.npy'),  # 在此处插入你的操作系统上的路径
    'solid': np.load('./data/solid.npy')
}

vec1 = files['gas'][::10]
vec2 = files['solid'][::10]

fig = make_subplots(rows=1, cols=2, shared_yaxes=True, shared_xaxes=True)

for step in range(len(vec1)):
    fig.append_trace(
        go.Heatmap(
            z=vec1[step].T,
            name=str(step),
            visible=False,
            zauto=False,
            colorscale='jet',
            coloraxis='coloraxis1'
        ), row=1, col=1)

    fig.append_trace(
        go.Heatmap(
            z=vec2[step].T,
            name=str(step),
            visible=False,
            zauto=False,
            colorscale='jet',
            coloraxis='coloraxis2'
        ), row=1, col=2)

steps = []

for i in range(0, len(fig.data), 2):
    step = dict(
        method="restyle",
        args=["visible", [False] * len(fig.data)],
    )
    step["args"][1][i:i + 2] = [True, True]
    steps.append(step)

sliders = [dict(
    active=0,
    currentvalue={"prefix": "index:"},
    pad={"t": 50},
    steps=steps
)]

fig.update_layout(sliders=sliders, template="plotly_white")

fig.update_layout(
    legend=dict(x=0.5, xanchor='center', y=1, yanchor='bottom', orientation='h'),
    coloraxis1=dict(colorscale='jet', colorbar_x=-0.3, colorbar_thickness=10),
    coloraxis2=dict(colorscale='jet', colorbar_x=1.00, colorbar_thickness=10),
    width=600, height=700)
fig.update_layout(
    yaxis={"title": 'y [m/10]'},
    xaxis={"title": 'r [m/10]', 'side': 'bottom'},
    title_x=0.5,
)

fig.update_layout(width=600, height=700)

fig.show()
英文:

I found an example of using a slider on a subplot of a line chart in the plotly community, so I created a subplot with a slider from your data based on it. The point is that since it is two subplots, the units that control what is displayed are also two each. The list that controls which to show and hide slides by 2 true units each. 500 graphs would also require a lot of CPU power to run, so I've made it 50 graphs.

import numpy as np
import plotly.subplots
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Processed loading
files = {
'gas': np.load('./data/gas.npy'), #insert here the path on your OS
'solid': np.load('./data/solid.npy')
}
vec1 = files['gas'][::10]
vec2 = files['solid'][::10]
fig = make_subplots(rows=1, cols=2, shared_yaxes=True, shared_xaxes=True)
for step in range(len(vec1)):
fig.append_trace(
go.Heatmap(
z=vec1[step].T,
name=str(step),
visible=False,
zauto=False,
colorscale='jet',
coloraxis='coloraxis1'
),row=1, col=1)
fig.append_trace(
go.Heatmap(
z=vec2[step].T,
name=str(step),
visible=False,
zauto=False,
colorscale='jet',
coloraxis='coloraxis2'
),row=1, col=2)
steps = []
for i in range(0, len(fig.data), 2):
step = dict(
method="restyle",
args=["visible", [False] * len(fig.data)],
)
step["args"][1][i:i+2] = [True, True]
steps.append(step)
sliders = [dict(
active=0,
currentvalue={"prefix": "index:"},
pad={"t": 50},
steps=steps
)]
fig.update_layout(sliders=sliders, template ="plotly_white")
fig.update_layout(
legend=dict(x=0.5, xanchor='center', y=1, yanchor='bottom', orientation='h'),
coloraxis1=dict(colorscale='jet', colorbar_x=-0.3, colorbar_thickness=10),
coloraxis2=dict(colorscale='jet', colorbar_x=1.00, colorbar_thickness=10),
width=600, height=700)
fig.update_layout(
yaxis={"title": 'y [m/10]'},
xaxis={"title": 'r [m/10]', 'side': 'bottom'},
title_x=0.5,
)
fig.update_layout(width=600,height=700)
fig.show()

Plotly与Python:如何使用帧和滑块绘制两个热图?

huangapple
  • 本文由 发表于 2023年5月7日 12:19:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定