如何使用不确定条或等价物创建 3D 曲面图?
How can a 3D surface plot be created with uncertainty bars or equivalent?
目标是创建一个 3D 表面图,其中包含不确定条或其他一些清晰的不确定性可视化,如下所示:
目前,我有以下情节:
这是使用以下代码生成的:
from io import StringIO
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
import seaborn as sns
data_string = StringIO(
"""
V1, V2, V3, V4, V5
110,111,109,107,108
101,101,102,102,102
102,102,103,103,103
103,103,104,104,104
100,101,100,100,100
"""
)
uncertainties_string = StringIO(
"""
V1U,V2U,V3U,V4U,V5U
5, 5, 5, 5, 7
5, 5, 3, 5, 5
6, 5, 5, 5, 5
5, 6, 5, 2, 5
5, 5, 5, 5, 5
"""
)
data = pd.read_csv(data_string)
uncertainties = pd.read_csv(uncertainties_string)
df = data.unstack().reset_index()
df.columns = ["X", "Y", "Z"]
df['X'] = pd.Categorical(df['X'])
df['X'] = df['X'].cat.codes
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.jet, linewidth=0.01)
fig.colorbar(surf)
plt.show()
我不确定是否有 built-in 功能,但我玩得很开心:
我为每个数据点制作了两个误差线(一个用于上面的部分,一个用于下面的部分),并用不同的 zorder
绘制它们:
# get errors into the same format as data
df_unc = uncertainties.unstack().reset_index()
df_unc.columns = ["X", "Y", "Z"]
df_unc['X'] = pd.Categorical(df_unc['X'])
df_unc['X'] = df_unc['X'].cat.codes
# compute lower and upper values for errorbars
df['z_low'] = df['Z'] - df_unc['Z']
df['z_high'] = df['Z'] + df_unc['Z']
# plot surface with middle value for zorder
surf = ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.jet, linewidth=0.01, zorder=2)
# plot lines with lower and higher zorder, respectively
for ix, row in df.iterrows():
ax.plot((row['Y'], row['Y']), (row['X'], row['X']), (row['z_low'], row['Z']), c='k', zorder=1)
ax.plot((row['Y'], row['Y']), (row['X'], row['X']), (row['Z'], row['z_high']), c='k', zorder=3)
目标是创建一个 3D 表面图,其中包含不确定条或其他一些清晰的不确定性可视化,如下所示:
目前,我有以下情节:
这是使用以下代码生成的:
from io import StringIO
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
import seaborn as sns
data_string = StringIO(
"""
V1, V2, V3, V4, V5
110,111,109,107,108
101,101,102,102,102
102,102,103,103,103
103,103,104,104,104
100,101,100,100,100
"""
)
uncertainties_string = StringIO(
"""
V1U,V2U,V3U,V4U,V5U
5, 5, 5, 5, 7
5, 5, 3, 5, 5
6, 5, 5, 5, 5
5, 6, 5, 2, 5
5, 5, 5, 5, 5
"""
)
data = pd.read_csv(data_string)
uncertainties = pd.read_csv(uncertainties_string)
df = data.unstack().reset_index()
df.columns = ["X", "Y", "Z"]
df['X'] = pd.Categorical(df['X'])
df['X'] = df['X'].cat.codes
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.jet, linewidth=0.01)
fig.colorbar(surf)
plt.show()
我不确定是否有 built-in 功能,但我玩得很开心:
我为每个数据点制作了两个误差线(一个用于上面的部分,一个用于下面的部分),并用不同的 zorder
绘制它们:
# get errors into the same format as data
df_unc = uncertainties.unstack().reset_index()
df_unc.columns = ["X", "Y", "Z"]
df_unc['X'] = pd.Categorical(df_unc['X'])
df_unc['X'] = df_unc['X'].cat.codes
# compute lower and upper values for errorbars
df['z_low'] = df['Z'] - df_unc['Z']
df['z_high'] = df['Z'] + df_unc['Z']
# plot surface with middle value for zorder
surf = ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.jet, linewidth=0.01, zorder=2)
# plot lines with lower and higher zorder, respectively
for ix, row in df.iterrows():
ax.plot((row['Y'], row['Y']), (row['X'], row['X']), (row['z_low'], row['Z']), c='k', zorder=1)
ax.plot((row['Y'], row['Y']), (row['X'], row['X']), (row['Z'], row['z_high']), c='k', zorder=3)