plotly 热图的缓慢浏览器渲染
slow browser rendering of plotly heatmap
我正在渲染 212 行 x 64 列 DF 的整数 (final_df),范围从 0 到 6 作为(无注释)绘图注释热图。我在我的浏览器 (microsoft edge) 中使用来自 fig.write_html()
的文件执行此操作。最终的热图在我的浏览器中呈现得非常慢,以至于我收到 'page not responding' 警告,而且图表的任何缩放 in/out 也非常慢。鉴于 df 没有那么大,这令人惊讶。
任何人都可以建议这是为什么以及如何加快速度吗?
谢谢,
蒂姆
def discrete_colorscale(bvals, colors):
#https://chart-studio.plotly.com/~empet/15229/heatmap-with-a-discrete-colorscale/#/
"""
bvals - list of values bounding intervals/ranges of interest
colors - list of rgb or hex colorcodes for values in [bvals[k], bvals[k+1]],0<=k < len(bvals)-1
returns the plotly discrete colorscale
"""
if len(bvals) != len(colors)+1:
raise ValueError('len(boundary values) should be equal to len(colors)+1')
bvals = sorted(bvals)
nvals = [(v-bvals[0])/(bvals[-1]-bvals[0]) for v in bvals] #normalized values
dcolorscale = [] #discrete colorscale
for k in range(len(colors)):
dcolorscale.extend([[nvals[k], colors[k]], [nvals[k+1], colors[k]]])
return dcolorscale
#final_df is a 212 row x 64 col df of ints ranging from 0 to 6
#cell_df is an empty 212x64 df of empty strings to remove cell labelling behaviour
cell_df = final_df.applymap(lambda x: annot_map.get(x, x))
cell_labels = cell_df.values.tolist()
bvals = [0,1,2,3,4,5,6,7]
colors_map = ['rgb(244,244,255)', #whiteish
'rgb(255, 128, 0)', #orange
'rgb(255,0,0)', #red
'rgb(0, 0, 255)', #blue
'rgb(128, 128, 128)', #grey
'rgb(0, 255, 0)', #green
'rgb(192, 192, 192)'] #light grey
dcolorsc = discrete_colorscale(bvals, colors_map)
bvals = np.array(bvals)
tickvals = [np.mean(bvals[k:k+2]) for k in range(len(bvals)-1)]
ticktext = ['param 1',
'param 2',
'param 3',
'param 4',
'param 5',
'param 6',
'param 7']
fig_df = ff.create_annotated_heatmap(final_df.values.tolist(),
x= list(final_df.columns),
y=list(final_df.index),
annotation_text = cell_labels,
colorscale=dcolorsc,
colorbar = dict(thickness=25,
tickvals=tickvals,
ticktext=ticktext),
showscale = True,
zmin=0, zmax=7,
ygap = 1,
xgap = 1,
)
fig_df.update_layout(
xaxis={'title' : 'ID 1'},
yaxis = {'title' : 'ID 2'},
yaxis_nticks = len(final_df.index),
xaxis_nticks = len(final_df.columns)
)
fig_df.write_html(results_file_df)
我怀疑这些注释对于 plotly 渲染来说非常昂贵。可能是即使你将一个 212x64 的空字符串数组传递给 annotation_text
参数,plotly 仍然必须遍历它们以确定没有要添加的注释。
我用 0-6 的随机整数创建了一个 212x64 数组,它在我的浏览器中呈现也很慢,我收到了与您相同的“页面未响应”警告。
当我使用 go.heatmap
时,我能够获得看起来与 ff.create_annotated_heatmap
相同的情节,这将执行时间从 5-6 秒缩短到 0.66 秒,并且它还在浏览器中响应更快。
这似乎比创建带注释的热图而不使用注释更直接(是否有特定原因需要 ff.create_annotated_heatmap 而不是 go.heatmap?)
import numpy as np
import pandas as pd
import plotly.figure_factory as ff
import plotly.graph_objects as go
import time
start_time = time.time()
def discrete_colorscale(bvals, colors):
#https://chart-studio.plotly.com/~empet/15229/heatmap-with-a-discrete-colorscale/#/
"""
bvals - list of values bounding intervals/ranges of interest
colors - list of rgb or hex colorcodes for values in [bvals[k], bvals[k+1]],0<=k < len(bvals)-1
returns the plotly discrete colorscale
"""
if len(bvals) != len(colors)+1:
raise ValueError('len(boundary values) should be equal to len(colors)+1')
bvals = sorted(bvals)
nvals = [(v-bvals[0])/(bvals[-1]-bvals[0]) for v in bvals] #normalized values
dcolorscale = [] #discrete colorscale
for k in range(len(colors)):
dcolorscale.extend([[nvals[k], colors[k]], [nvals[k+1], colors[k]]])
return dcolorscale
#final_df is a 212 row x 64 col df of ints ranging from 0 to 6
#cell_df is an empty 212x64 df of empty strings to remove cell labelling behaviour
## recreate your dfs
np.random.seed(42)
final_df = pd.DataFrame(np.random.randint(0,6,size=(212, 64)), columns=list(range(64)))
# cell_df = final_df.applymap(lambda x: annot_map.get(x, x))
cell_df = pd.DataFrame(np.array(['']*212*64).reshape(212,64), columns=list(range(64)))
cell_labels = cell_df.values.tolist()
bvals = [0,1,2,3,4,5,6,7]
colors_map = ['rgb(244,244,255)', #whiteish
'rgb(255, 128, 0)', #orange
'rgb(255,0,0)', #red
'rgb(0, 0, 255)', #blue
'rgb(128, 128, 128)', #grey
'rgb(0, 255, 0)', #green
'rgb(192, 192, 192)'] #light grey
dcolorsc = discrete_colorscale(bvals, colors_map)
bvals = np.array(bvals)
tickvals = [np.mean(bvals[k:k+2]) for k in range(len(bvals)-1)]
ticktext = ['param 1',
'param 2',
'param 3',
'param 4',
'param 5',
'param 6',
'param 7']
# fig_df = ff.create_annotated_heatmap(final_df.values.tolist(),
# x= list(final_df.columns),
# y=list(final_df.index),
# annotation_text = cell_labels,
# colorscale=dcolorsc,
# colorbar = dict(thickness=25,
# tickvals=tickvals,
# ticktext=ticktext),
# showscale = True,
# zmin=0, zmax=7,
# ygap = 1,
# xgap = 1,
# )
fig_df = go.Figure([go.Heatmap(
z=final_df,
colorscale=dcolorsc,
colorbar=dict(
thickness=25,
tickvals=tickvals,
ticktext=ticktext),
showscale=True,
zmin=0, zmax=7,
ygap=1,
xgap=1,
)
])
fig_df.update_layout(
xaxis={'title' : 'ID 1'},
yaxis = {'title' : 'ID 2'},
yaxis_nticks = len(final_df.index),
xaxis_nticks = len(final_df.columns)
)
fig_df.show()
print(f"Program executed in {time.time() - start_time} seconds")
## original code with figure_factory annotated heatmap: Program executed in 5.351915121078491 seconds
## modified code with graph_objects heatmap: Program executed in 0.6627509593963623 seconds
# fig_df.write_html(results_file_df)
我正在渲染 212 行 x 64 列 DF 的整数 (final_df),范围从 0 到 6 作为(无注释)绘图注释热图。我在我的浏览器 (microsoft edge) 中使用来自 fig.write_html()
的文件执行此操作。最终的热图在我的浏览器中呈现得非常慢,以至于我收到 'page not responding' 警告,而且图表的任何缩放 in/out 也非常慢。鉴于 df 没有那么大,这令人惊讶。
任何人都可以建议这是为什么以及如何加快速度吗?
谢谢, 蒂姆
def discrete_colorscale(bvals, colors):
#https://chart-studio.plotly.com/~empet/15229/heatmap-with-a-discrete-colorscale/#/
"""
bvals - list of values bounding intervals/ranges of interest
colors - list of rgb or hex colorcodes for values in [bvals[k], bvals[k+1]],0<=k < len(bvals)-1
returns the plotly discrete colorscale
"""
if len(bvals) != len(colors)+1:
raise ValueError('len(boundary values) should be equal to len(colors)+1')
bvals = sorted(bvals)
nvals = [(v-bvals[0])/(bvals[-1]-bvals[0]) for v in bvals] #normalized values
dcolorscale = [] #discrete colorscale
for k in range(len(colors)):
dcolorscale.extend([[nvals[k], colors[k]], [nvals[k+1], colors[k]]])
return dcolorscale
#final_df is a 212 row x 64 col df of ints ranging from 0 to 6
#cell_df is an empty 212x64 df of empty strings to remove cell labelling behaviour
cell_df = final_df.applymap(lambda x: annot_map.get(x, x))
cell_labels = cell_df.values.tolist()
bvals = [0,1,2,3,4,5,6,7]
colors_map = ['rgb(244,244,255)', #whiteish
'rgb(255, 128, 0)', #orange
'rgb(255,0,0)', #red
'rgb(0, 0, 255)', #blue
'rgb(128, 128, 128)', #grey
'rgb(0, 255, 0)', #green
'rgb(192, 192, 192)'] #light grey
dcolorsc = discrete_colorscale(bvals, colors_map)
bvals = np.array(bvals)
tickvals = [np.mean(bvals[k:k+2]) for k in range(len(bvals)-1)]
ticktext = ['param 1',
'param 2',
'param 3',
'param 4',
'param 5',
'param 6',
'param 7']
fig_df = ff.create_annotated_heatmap(final_df.values.tolist(),
x= list(final_df.columns),
y=list(final_df.index),
annotation_text = cell_labels,
colorscale=dcolorsc,
colorbar = dict(thickness=25,
tickvals=tickvals,
ticktext=ticktext),
showscale = True,
zmin=0, zmax=7,
ygap = 1,
xgap = 1,
)
fig_df.update_layout(
xaxis={'title' : 'ID 1'},
yaxis = {'title' : 'ID 2'},
yaxis_nticks = len(final_df.index),
xaxis_nticks = len(final_df.columns)
)
fig_df.write_html(results_file_df)
我怀疑这些注释对于 plotly 渲染来说非常昂贵。可能是即使你将一个 212x64 的空字符串数组传递给 annotation_text
参数,plotly 仍然必须遍历它们以确定没有要添加的注释。
我用 0-6 的随机整数创建了一个 212x64 数组,它在我的浏览器中呈现也很慢,我收到了与您相同的“页面未响应”警告。
当我使用 go.heatmap
时,我能够获得看起来与 ff.create_annotated_heatmap
相同的情节,这将执行时间从 5-6 秒缩短到 0.66 秒,并且它还在浏览器中响应更快。
这似乎比创建带注释的热图而不使用注释更直接(是否有特定原因需要 ff.create_annotated_heatmap 而不是 go.heatmap?)
import numpy as np
import pandas as pd
import plotly.figure_factory as ff
import plotly.graph_objects as go
import time
start_time = time.time()
def discrete_colorscale(bvals, colors):
#https://chart-studio.plotly.com/~empet/15229/heatmap-with-a-discrete-colorscale/#/
"""
bvals - list of values bounding intervals/ranges of interest
colors - list of rgb or hex colorcodes for values in [bvals[k], bvals[k+1]],0<=k < len(bvals)-1
returns the plotly discrete colorscale
"""
if len(bvals) != len(colors)+1:
raise ValueError('len(boundary values) should be equal to len(colors)+1')
bvals = sorted(bvals)
nvals = [(v-bvals[0])/(bvals[-1]-bvals[0]) for v in bvals] #normalized values
dcolorscale = [] #discrete colorscale
for k in range(len(colors)):
dcolorscale.extend([[nvals[k], colors[k]], [nvals[k+1], colors[k]]])
return dcolorscale
#final_df is a 212 row x 64 col df of ints ranging from 0 to 6
#cell_df is an empty 212x64 df of empty strings to remove cell labelling behaviour
## recreate your dfs
np.random.seed(42)
final_df = pd.DataFrame(np.random.randint(0,6,size=(212, 64)), columns=list(range(64)))
# cell_df = final_df.applymap(lambda x: annot_map.get(x, x))
cell_df = pd.DataFrame(np.array(['']*212*64).reshape(212,64), columns=list(range(64)))
cell_labels = cell_df.values.tolist()
bvals = [0,1,2,3,4,5,6,7]
colors_map = ['rgb(244,244,255)', #whiteish
'rgb(255, 128, 0)', #orange
'rgb(255,0,0)', #red
'rgb(0, 0, 255)', #blue
'rgb(128, 128, 128)', #grey
'rgb(0, 255, 0)', #green
'rgb(192, 192, 192)'] #light grey
dcolorsc = discrete_colorscale(bvals, colors_map)
bvals = np.array(bvals)
tickvals = [np.mean(bvals[k:k+2]) for k in range(len(bvals)-1)]
ticktext = ['param 1',
'param 2',
'param 3',
'param 4',
'param 5',
'param 6',
'param 7']
# fig_df = ff.create_annotated_heatmap(final_df.values.tolist(),
# x= list(final_df.columns),
# y=list(final_df.index),
# annotation_text = cell_labels,
# colorscale=dcolorsc,
# colorbar = dict(thickness=25,
# tickvals=tickvals,
# ticktext=ticktext),
# showscale = True,
# zmin=0, zmax=7,
# ygap = 1,
# xgap = 1,
# )
fig_df = go.Figure([go.Heatmap(
z=final_df,
colorscale=dcolorsc,
colorbar=dict(
thickness=25,
tickvals=tickvals,
ticktext=ticktext),
showscale=True,
zmin=0, zmax=7,
ygap=1,
xgap=1,
)
])
fig_df.update_layout(
xaxis={'title' : 'ID 1'},
yaxis = {'title' : 'ID 2'},
yaxis_nticks = len(final_df.index),
xaxis_nticks = len(final_df.columns)
)
fig_df.show()
print(f"Program executed in {time.time() - start_time} seconds")
## original code with figure_factory annotated heatmap: Program executed in 5.351915121078491 seconds
## modified code with graph_objects heatmap: Program executed in 0.6627509593963623 seconds
# fig_df.write_html(results_file_df)