Blu*_*482 2 python plot matplotlib pandas plotly
我有许多可变长度的二维序列,即列表列表,其中每个子列表都是一个序列。我想在 3d 可视化中投影这些序列/行/子列表,将时间步长作为另一个维度。到目前为止,我未能使用plotly.express.
import plotly.express as px
t = [[ii+1 for ii in range(len(features[i]))] for i in range(len(labels))]
x0 = [[x[0] for x in features[i]] for i in range(len(labels))]
x1 = [[x[1] for x in features[i]] for i in range(len(labels))]
df = pd.DataFrame(dict(
X=[tii for ti in t for tii in ti],
Y=[xii for xi in x0 for xii in xi],
Z=[xii for xi in x1 for xii in xi],
color=[aa for a in labels for aa in a]
))
fig = px.line_3d(df, x="X", y="Y", z="Z", color="color")
fig.show
Run Code Online (Sandbox Code Playgroud)
这就是我得到的,这不是我真正想要的。它将所有具有公共标签的案例/子列表视为一个单独的序列,因此我们在每一行的末尾看到它回到它开始的地方。我已经查看了如何在 for 循环(就像 matplotlib)中迭代地绘制它(基本上在每次迭代时创建一个新的 Pandas 数据框并绘制它),但是没有成功。请问有人有这方面的经验吗?非常感激!
一个 mcve 如下:
import plotly.express as px
import numpy as np
import pandas as pd
features = [np.random.rand(4,2).tolist(),
np.random.rand(5,2).tolist(),
np.random.rand(6,2).tolist(),
np.random.rand(5,2).tolist(),
np.random.rand(9,2).tolist()]
labels = [[1, 1, 1, 1], [1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2], [0, 0, 0, 0, 0, 0, 0, 0, 0]]
t = [[ii+1 for ii in range(len(features[i]))] for i in range(len(labels))]
x0 = [[x[0] for x in features[i]] for i in range(len(labels))]
x1 = [[x[1] for x in features[i]] for i in range(len(labels))]
df2 = pd.DataFrame(dict(
X=[tii for ti in t for tii in ti],
Y=[xii for xi in x0 for xii in xi],
Z=[xii for xi in x1 for xii in xi],
color=[aa for a in labels for aa in a]
))
fig1 = px.line_3d(df2, x="X", y="Y", z="Z", color="color")
fig1.show()
Run Code Online (Sandbox Code Playgroud)
您基本上会看到 3 行而不是 5 行。
您的问题是您对不同的跟踪使用相同的标签。这里有一个循环的解决方法
import numpy as np
import plotly.graph_objs as go
features = [np.random.rand(4,2).tolist(),
np.random.rand(5,2).tolist(),
np.random.rand(6,2).tolist(),
np.random.rand(5,2).tolist(),
np.random.rand(9,2).tolist()]
labels = [[1, 1, 1, 1],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
fig = go.Figure()
for i, feat in enumerate(features):
feat = np.array(feat)
fig.add_trace(
go.Scatter3d(
x=np.arange(len(feat)),
y=feat[:,0],
z=feat[:,1],
mode='lines',
hovertext=labels[i]
)
)
fig.show()
Run Code Online (Sandbox Code Playgroud)
您可能需要使用跟踪名称。
希望它并不太复杂,但它的目的是尽可能通用
import numpy as np
import plotly.graph_objs as go
from itertools import cycle
def plotly_color_map(names):
# From https://stackoverflow.com/a/44727682
plotly_colors = cycle(['#1f77b4', # muted blue
'#ff7f0e', # safety orange
'#2ca02c', # cooked asparagus green
'#d62728', # brick red
'#9467bd', # muted purple
'#8c564b', # chestnut brown
'#e377c2', # raspberry yogurt pink
'#7f7f7f', # middle gray
'#bcbd22', # curry yellow-green
'#17becf' # blue-teal
])
return dict(zip(names, plotly_colors))
features = [np.random.rand(4,2).tolist(),
np.random.rand(5,2).tolist(),
np.random.rand(6,2).tolist(),
np.random.rand(5,2).tolist(),
np.random.rand(9,2).tolist()]
labels = [[1, 1, 1, 1],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
legend_groups = [l[0] for l in labels]
traces = [False if (len(legend_groups[:i])>0 and l in legend_groups[:i])
else True for i, l in enumerate(legend_groups)]
cm = plotly_color_map(set(legend_groups))
fig = go.Figure()
for i, feat in enumerate(features):
feat = np.array(feat)
fig.add_trace(
go.Scatter3d(
x=np.arange(len(feat)),
y=feat[:,0],
z=feat[:,1],
mode='lines',
line={"color":cm[legend_groups[i]]},
legendgroup=legend_groups[i],
hovertext=labels[i],
showlegend=traces[i],
name="label_{}".format(legend_groups[i])
)
)
fig.show()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1774 次 |
| 最近记录: |