Python Plotly:如何将图像添加到 3D 散点图
Python Plotly: How to add an image to a 3D scatter plot
我正在尝试在 3D 散点图中可视化多个 2d 轨迹 (x, y),其中 z 轴是时间。
import numpy as np
import pandas as pd
import plotly.express as px
# Sample data: 3 trajectories
t = np.linspace(0, 10, 200)
df = pd.concat([pd.DataFrame({'x': 900 * (1 + np.cos(t + 5 * i)), 'y': 400 * (1 + np.sin(t)), 't': t, 'id': f'id000{i}'}) for i in [0, 1, 2]])
# 3d scatter plot
fig = px.scatter_3d(df, x='x', y='y', z='t', color='id', )
fig.update_traces(marker=dict(size=2))
fig.show()
我有一个 .png 地图文件,大小为:2000x1000。轨迹的 (x, y) 坐标对应于地图的像素位置。
我想在 3d 散点图的 "floor" 上查看地图图像。
我试过用这个代码添加图像:
from scipy import misc
img = misc.imread('images/map_bg.png')
fig2 = px.imshow(img)
fig.add_trace(fig2.data[0])
fig.show()
但结果是在背景中有一个独立的图像作为一个单独的图:
并且我想要散点图"floor"上的图像并随着散点图移动,如果我rotate/zoom。这是一个模拟:
补充说明:可以有任意数量的轨迹,对于我的应用程序,重要的是每个轨迹都自动绘制成不同的颜色。我正在使用 plotly.express
,但我可以使用其他 plotly 包,只要满足这些要求即可。
我 运行 遇到过同样的情况,我想在 3D 散点图中使用图像作为底面。在两个帖子 here and here 的帮助下,我已经能够创建以下 3d 散点图:
我在示例中使用了 plotly go,因此结果与 OP 中的代码略有不同。
import numpy as np
import pandas as pd
from PIL import Image
import plotly.graph_objects as go
from scipy import misc
im = misc.face()
im_x, im_y, im_layers = im.shape
eight_bit_img = Image.fromarray(im).convert('P', palette='WEB', dither=None)
dum_img = Image.fromarray(np.ones((3,3,3), dtype='uint8')).convert('P', palette='WEB')
idx_to_color = np.array(dum_img.getpalette()).reshape((-1, 3))
colorscale=[[i/255.0, "rgb({}, {}, {})".format(*rgb)] for i, rgb in enumerate(idx_to_color)]
# Sample data: 3 trajectories
t = np.linspace(0, 10, 200)
df = pd.concat([pd.DataFrame({'x': 400 * (1 + np.cos(t + 5 * i)), 'y': 400 * (1 + np.sin(t)), 't': t, 'id': f'id000{i}'}) for i in [0, 1, 2]])
# im = im.swapaxes(0, 1)[:, ::-1]
colors=df['t'].to_list()
# # 3d scatter plot
x = np.linspace(0,im_x, im_x)
y = np.linspace(0, im_y, im_y)
z = np.zeros(im.shape[:2])
fig = go.Figure()
fig.add_trace(go.Scatter3d(
x=df['x'],
y=df['y'],
z=df['t'],
marker=dict(
color=colors,
size=4,
)
))
fig.add_trace(go.Surface(x=x, y=y, z=z,
surfacecolor=eight_bit_img,
cmin=0,
cmax=255,
colorscale=colorscale,
showscale=False,
lighting_diffuse=1,
lighting_ambient=1,
lighting_fresnel=1,
lighting_roughness=1,
lighting_specular=0.5,
))
fig.update_layout(
title="My 3D scatter plot",
width=800,
height=800,
scene=dict(xaxis_visible=True,
yaxis_visible=True,
zaxis_visible=True,
xaxis_title="X",
yaxis_title="Y",
zaxis_title="Z" ,
))
fig.show()
我正在尝试在 3D 散点图中可视化多个 2d 轨迹 (x, y),其中 z 轴是时间。
import numpy as np
import pandas as pd
import plotly.express as px
# Sample data: 3 trajectories
t = np.linspace(0, 10, 200)
df = pd.concat([pd.DataFrame({'x': 900 * (1 + np.cos(t + 5 * i)), 'y': 400 * (1 + np.sin(t)), 't': t, 'id': f'id000{i}'}) for i in [0, 1, 2]])
# 3d scatter plot
fig = px.scatter_3d(df, x='x', y='y', z='t', color='id', )
fig.update_traces(marker=dict(size=2))
fig.show()
我有一个 .png 地图文件,大小为:2000x1000。轨迹的 (x, y) 坐标对应于地图的像素位置。
我想在 3d 散点图的 "floor" 上查看地图图像。
我试过用这个代码添加图像:
from scipy import misc
img = misc.imread('images/map_bg.png')
fig2 = px.imshow(img)
fig.add_trace(fig2.data[0])
fig.show()
但结果是在背景中有一个独立的图像作为一个单独的图:
并且我想要散点图"floor"上的图像并随着散点图移动,如果我rotate/zoom。这是一个模拟:
补充说明:可以有任意数量的轨迹,对于我的应用程序,重要的是每个轨迹都自动绘制成不同的颜色。我正在使用 plotly.express
,但我可以使用其他 plotly 包,只要满足这些要求即可。
我 运行 遇到过同样的情况,我想在 3D 散点图中使用图像作为底面。在两个帖子 here and here 的帮助下,我已经能够创建以下 3d 散点图:
我在示例中使用了 plotly go,因此结果与 OP 中的代码略有不同。
import numpy as np
import pandas as pd
from PIL import Image
import plotly.graph_objects as go
from scipy import misc
im = misc.face()
im_x, im_y, im_layers = im.shape
eight_bit_img = Image.fromarray(im).convert('P', palette='WEB', dither=None)
dum_img = Image.fromarray(np.ones((3,3,3), dtype='uint8')).convert('P', palette='WEB')
idx_to_color = np.array(dum_img.getpalette()).reshape((-1, 3))
colorscale=[[i/255.0, "rgb({}, {}, {})".format(*rgb)] for i, rgb in enumerate(idx_to_color)]
# Sample data: 3 trajectories
t = np.linspace(0, 10, 200)
df = pd.concat([pd.DataFrame({'x': 400 * (1 + np.cos(t + 5 * i)), 'y': 400 * (1 + np.sin(t)), 't': t, 'id': f'id000{i}'}) for i in [0, 1, 2]])
# im = im.swapaxes(0, 1)[:, ::-1]
colors=df['t'].to_list()
# # 3d scatter plot
x = np.linspace(0,im_x, im_x)
y = np.linspace(0, im_y, im_y)
z = np.zeros(im.shape[:2])
fig = go.Figure()
fig.add_trace(go.Scatter3d(
x=df['x'],
y=df['y'],
z=df['t'],
marker=dict(
color=colors,
size=4,
)
))
fig.add_trace(go.Surface(x=x, y=y, z=z,
surfacecolor=eight_bit_img,
cmin=0,
cmax=255,
colorscale=colorscale,
showscale=False,
lighting_diffuse=1,
lighting_ambient=1,
lighting_fresnel=1,
lighting_roughness=1,
lighting_specular=0.5,
))
fig.update_layout(
title="My 3D scatter plot",
width=800,
height=800,
scene=dict(xaxis_visible=True,
yaxis_visible=True,
zaxis_visible=True,
xaxis_title="X",
yaxis_title="Y",
zaxis_title="Z" ,
))
fig.show()