我正在使用plotly绘制4d虹膜数据集的scatter3d投影。为了在同一图中显示所有4种可能的投影,我正在使用滑块。但是,当从一个投影“滑动”到下一个投影时,轴标题不变。通常我会使用fig.update_layout()
,但是那是行不通的。如何使用滑块更改它们?
以下是参考代码:
import numpy as np
import plotly.graph_objects as go
from matplotlib import cm
from itertools import combinations
def nd2scatter3d(X, labels = None, features = None, plot_axes = None, hovertext = None):
"""
Parameters
----------
X : array-like, shape = (n_samples, n_features).
labels : 1d int array, shape = (n_samples), optional, default None.
Target or clustering labels for each sample.
Defaults to np.ones(n_samples).
features : list, len = n_features, optional, default None.
List of feature names.
Defaults to numeric labeling.
plot_axes : list of 3-tuples, optional, default None.
List of axes to include in 3d projections. i.e. [(0,1,2), (0,1,3)] displays
projections along the 4th axis and 3rd axis in that order.
Defaults to all possible axes combinations.
hovertext : list, len = n_samples, optional, default None.
List of text to display on mouse hover.
Defaults to no text on hover.
"""
if labels is None:
labels = np.ones(X.shape[0]).astype(int)
if features is None:
features = np.arange(X.shape[1]).astype(str)
if plot_axes is None:
plot_axes = list(combinations(np.arange(X.shape[1]), 3))
if hovertext is None:
hoverinfo = 'none'
else:
hoverinfo = 'text'
fig = go.Figure()
for i in range(len(plot_axes)):
fig.add_trace(
go.Scatter3d(
visible=False,
x=X[:, plot_axes[i][0]],
y=X[:, plot_axes[i][1]],
z=X[:, plot_axes[i][2]],
mode='markers',
marker=dict(
size=3,
color = [list(cm.tab10.colors[c]) for c in labels],
opacity=1
),
hovertemplate=None,
hoverinfo= hoverinfo,
hovertext = hovertext,
),)
fig.data[0].visible = True
steps = []
for i in range(len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": features[plot_axes[i][0]] + ' vs. ' + features[plot_axes[i][1]] + ' vs. ' + features[plot_axes[i][2]]}, # layout attribute
],
label = str(plot_axes[i]),
)
step["args"][0]["visible"][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "Projection: "},
pad={"t": 10},
steps=steps,
)]
fig.update_layout(
sliders=sliders
)
fig.update_layout(width=900, height = 500, margin=dict(r=45, l=45, b=10, t=50),
showlegend=False)
fig.update_layout(scene_aspectmode='cube',
scene2_aspectmode='cube',
scene3_aspectmode='cube',
scene4_aspectmode='cube',
scene = dict(
xaxis_title = features[plot_axes[0][0]],
yaxis_title = features[plot_axes[0][1]],
zaxis_title = features[plot_axes[0][2]],),
scene2 = dict(
xaxis_title = features[plot_axes[1][0]],
yaxis_title = features[plot_axes[1][1]],
zaxis_title = features[plot_axes[1][2]],),
scene3 = dict(
xaxis_title = features[plot_axes[2][0]],
yaxis_title = features[plot_axes[2][1]],
zaxis_title = features[plot_axes[2][2]],),
scene4 = dict(
xaxis_title = features[plot_axes[3][0]],
yaxis_title = features[plot_axes[3][1]],
zaxis_title = features[plot_axes[3][2]],)
)
fig.show()
要更新轴标题,您需要在滑块条目中包括它。可能有助于参考plotly's js document on update
。
因此,而不是此块:
update
使用类似的东西:
for i in range(len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": features[plot_axes[i][0]] + ' vs. '
+ features[plot_axes[i][1]] + ' vs. ' + features[plot_axes[i][2]]},
],
label = str(plot_axes[i]),
)
这将创建一个条目,该条目将在滑块更改时更新数据和标题以及轴标题。