首页 > 解决方案 > matplotlib 曲面图隐藏了应该在前面的散点

问题描述

关于matplotlib 3d表面的另一个问题......我有代码可以将散点添加到matplotlib表面图。

从上面我遇到的问题是,无论您从哪个角度查看 ,该点总是出现在表面后面。从下面

如果我使用 3 条短线来标记同一个点来拼凑一个(诚然丑陋的)版本,它是可见的。 在此处输入图像描述

我已经关闭了这个depthshade功能,所以不是这个。任何人都可以解释发生了什么以及我如何纠正它?这是代码的简化版本:

import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

df = pd.DataFrame({10: {10: 1,15: 1,20: 1,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   15: {10: 4,15: 1,20: 1,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   20: {10: 6,15: 3,20: 1,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   25: {10: 7,15: 5,20: 3,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   30: {10: 9,15: 6,20: 4,25: 3,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   35: {10: 10,15: 7,20: 5,25: 4,30: 2,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   40: {10: 11,15: 8,20: 6,25: 4,30: 3,35: 2,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   45: {10: 12,15: 9,20: 7,25: 5,30: 4,35: 3,40: 2,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   50: {10: 13,15: 9,20: 7,25: 6,30: 5,35: 4,40: 3,45: 2,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   55: {10: 14,15: 10,20: 8,25: 7,30: 5,35: 4,40: 3,45: 3,50: 2,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   60: {10: 15,15: 11,20: 9,25: 7,30: 6,35: 5,40: 4,45: 3,50: 3,55: 2,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   65: {10: 16,15: 12,20: 9,25: 8,30: 6,35: 5,40: 5,45: 4,50: 3,55: 2,60: 2,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   70: {10: 17,15: 12,20: 10,25: 8,30: 7,35: 6,40: 5,45: 4,50: 4,55: 3,60: 2,65: 2,70: 1,75: 1,80: 1,85: 1,90: 1},
                   75: {10: 18,15: 13,20: 10,25: 9,30: 7,35: 6,40: 5,45: 5,50: 4,55: 3,60: 3,65: 2,70: 2,75: 1,80: 1,85: 1,90: 1},
                   80: {10: 19,15: 14,20: 11,25: 9,30: 8,35: 7,40: 6,45: 5,50: 4,55: 4,60: 3,65: 3,70: 2,75: 2,80: 1,85: 1,90: 1},
                   85: {10: 21,15: 14,20: 11,25: 10,30: 8,35: 7,40: 6,45: 6,50: 5,55: 4,60: 4,65: 3,70: 3,75: 2,80: 2,85: 1,90: 1},
                   90: {10: 23,15: 15,20: 12,25: 10,30: 9,35: 8,40: 7,45: 6,50: 5,55: 5,60: 4,65: 3,70: 3,75: 3,80: 2,85: 2,90: 1}})




xv, yv = np.meshgrid(df.index, df.columns)
ma = np.nanmax(df.values)
norm = matplotlib.colors.Normalize(vmin = 0, vmax = ma, clip = True)

fig = plt.figure(1)
ax = Axes3D(fig)
surf = ax.plot_surface(yv,xv,df, cmap='viridis_r', linewidth=0.3,
                       alpha = 0.8, edgecolor = 'k', norm=norm)
ax.scatter(25,35,4, c='k', depthshade=False, alpha = 1, s=100)

fig = plt.figure(2)
ax = Axes3D(fig)
surf = ax.plot_surface(yv,xv,df, cmap='viridis_r', linewidth=0.3,
                       alpha = 0.8, edgecolor = 'k', norm=norm)
line1_x = [25,25]
line1_y = [35,35]
line1_z = [3,5]

line2_x = [25,25]
line2_y = [33,37]
line2_z = [4,4]

line3_x = [23,27]
line3_y = [35,35]
line3_z = [4,4]

ax.plot(line1_x, line1_y, line1_z, alpha = 1, linewidth = 1, color='k')
ax.plot(line2_x, line2_y, line2_z, alpha = 1, linewidth = 1, color='k')
ax.plot(line3_x, line3_y, line3_z, alpha = 1, linewidth = 1, color='k')
plt.show()

标签: pythonmatplotlib

解决方案


好的,所以根据上面T 先生的评论,似乎没有直接的方法来处理这个问题。但是,有一种解决方法可以解决我正在尝试做的事情(突出显示表面上的特定点)。使用matplotlib.patchesmpl_toolkits.mplot3d.art3d模块,可以在图表上的适当点绘制一个圆圈,这似乎不受同一问题的影响。

一个例子

修改后的代码是:

import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D, art3d
from matplotlib.patches import Circle
import numpy as np

df = pd.DataFrame({10: {10: 1,15: 1,20: 1,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   15: {10: 4,15: 1,20: 1,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   20: {10: 6,15: 3,20: 1,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   25: {10: 7,15: 5,20: 3,25: 1,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   30: {10: 9,15: 6,20: 4,25: 3,30: 1,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   35: {10: 10,15: 7,20: 5,25: 4,30: 2,35: 1,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   40: {10: 11,15: 8,20: 6,25: 4,30: 3,35: 2,40: 1,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   45: {10: 12,15: 9,20: 7,25: 5,30: 4,35: 3,40: 2,45: 1,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   50: {10: 13,15: 9,20: 7,25: 6,30: 5,35: 4,40: 3,45: 2,50: 1,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   55: {10: 14,15: 10,20: 8,25: 7,30: 5,35: 4,40: 3,45: 3,50: 2,55: 1,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   60: {10: 15,15: 11,20: 9,25: 7,30: 6,35: 5,40: 4,45: 3,50: 3,55: 2,60: 1,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   65: {10: 16,15: 12,20: 9,25: 8,30: 6,35: 5,40: 5,45: 4,50: 3,55: 2,60: 2,65: 1,70: 1,75: 1,80: 1,85: 1,90: 1},
                   70: {10: 17,15: 12,20: 10,25: 8,30: 7,35: 6,40: 5,45: 4,50: 4,55: 3,60: 2,65: 2,70: 1,75: 1,80: 1,85: 1,90: 1},
                   75: {10: 18,15: 13,20: 10,25: 9,30: 7,35: 6,40: 5,45: 5,50: 4,55: 3,60: 3,65: 2,70: 2,75: 1,80: 1,85: 1,90: 1},
                   80: {10: 19,15: 14,20: 11,25: 9,30: 8,35: 7,40: 6,45: 5,50: 4,55: 4,60: 3,65: 3,70: 2,75: 2,80: 1,85: 1,90: 1},
                   85: {10: 21,15: 14,20: 11,25: 10,30: 8,35: 7,40: 6,45: 6,50: 5,55: 4,60: 4,65: 3,70: 3,75: 2,80: 2,85: 1,90: 1},
                   90: {10: 23,15: 15,20: 12,25: 10,30: 9,35: 8,40: 7,45: 6,50: 5,55: 5,60: 4,65: 3,70: 3,75: 3,80: 2,85: 2,90: 1}})




xv, yv = np.meshgrid(df.index, df.columns)
ma = np.nanmax(df.values)
norm = matplotlib.colors.Normalize(vmin = 0, vmax = ma, clip = True)

fig = plt.figure(1)
ax = Axes3D(fig)
surf = ax.plot_surface(yv,xv,df, cmap='viridis_r', linewidth=0.3,
                       alpha = 0.8, edgecolor = 'k', norm=norm)

p = Circle((25, 35), 3, ec='k', fc="none")
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=4, zdir="z")

plt.show()

推荐阅读