简而言之:我正在使用matplotlib
绘制一个scater情节和一个表面。我遇到了一个问题,因此表面总是被绘制在点的顶部,而不是应该在后面。
我想通过预处理点的颜色来解决这个问题,这样当表面覆盖时我得到“原始颜色”,这样表面就会出现在点后面。我使用color
值指定了HEX
个点。
我遇到的表面和点的问题类似于here所描述的问题。
以下是详细信息:
我在Matplotlib中有蓝色和红色点的3D散点图:
self.subplot_3d = self.subplot.scatter(x_red, y_red, z_red, s = 150, c = RED, depthshade = False, lw = 0, alpha = 1)
self.subplot_3d = self.subplot.scatter(x_blue, y_blue, z_blue, s = 150, c = BLUE, depthshade = False, lw = 0, alpha = 1)
点可线性分离 - 存在分离平面,分隔红点和蓝点。我使用
绘制平原self.plane = self.subplot.plot_surface(X, Y, Z, antialiased = True, color = RED_BACKGROUND, alpha = 0.5)
我想绘制两个图:在第一个图中,没有绘制分离平面 - 只有红色和蓝色点(左)。在第二个有一个分离平面(右)。
绘制分离平面后,我无法强制在红点和蓝点之间绘制平面(正如平面方程和点的位置所预期的那样)平面总是出现在所有要点。
我正在考虑的解决方案如下:“预处理”蓝点的颜色,以便当与透明平面的颜色重叠时,我获得原始的蓝色。通过这种方式,点将显示在平面的顶部,它应该“解决”我当前的问题。
我使用过HEX
color specification,我不确定在matplotlib中使用透明度时颜色是如何混合的。我正在寻找参考或建议如何“抵消”飞机的红色透明色,例如alpha = 0.2
。
换句话说,我想实现像sepicifiying这样的东西:
Blue = #0000FF
Red = #FF0000
PreProcBlue = "#-FF00FF"'
以PreProcBlue + Red = Blue
。
谢谢!
答案 0 :(得分:2)
一个问题是scatter
不尊重zorder
。因此,可以使用plot
代替。
我编写了一个比较plot
和scatter
的示例,绘制了z = 0下方的蓝点,z = 0处的平面和z = 0上方的红点。
在每种情况下,我使用-100,1,100的zorder分别用于蓝点,平面,红点。 (请注意,如果zorder中的差异较小或者所有都是正数,则会失败)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(12,6))
ax = fig.add_subplot(121, projection='3d', aspect="equal")
ax2 = fig.add_subplot(122, projection='3d', aspect="equal")
plt.subplots_adjust(0,0,1,1,0,0)
x = np.array([-1,1])
X,Y = np.meshgrid(x,x)
Z = np.zeros_like(X)
xr = np.random.rand(10,3)
xb = np.random.rand(10,3)
xb[:,2] = xb[:,2]-1.
ax2.set_title("scatter")
ax2.scatter(xb[:,0], xb[:,1], xb[:,2], s = 144, c = "b", depthshade = False, lw = 0, alpha = 1, zorder=-100)
ax2.plot_surface(X, Y, Z, antialiased = True, color = "#800000", alpha = 0.5, zorder=0)
ax2.scatter(xr[:,0], xr[:,1], xr[:,2], s = 144, c = "r", depthshade = False, lw = 0, alpha = 1, zorder=100)
ax.set_title("plot")
ax.plot(xb[:,0], xb[:,1], xb[:,2], c = "b", marker="o", markersize=12, lw = 0, alpha = 1, zorder=-100)
ax.plot_surface(X, Y, Z, antialiased = True, color = "#800000", alpha = 0.5, zorder=0)
ax.plot(xr[:,0], xr[:,1], xr[:,2], c = "r", marker="o", markersize=12, lw = 0, alpha = 1, zorder=100)
ax2.view_init(elev=32, azim=115)
ax.view_init(elev=32, azim=115)
def on_move(event):
if event.inaxes == ax:
ax2.view_init(elev=ax.elev, azim=ax.azim)
elif event.inaxes == ax2:
ax.view_init(elev=ax2.elev, azim=ax2.azim)
else:
return
fig.canvas.draw_idle()
c1 = fig.canvas.mpl_connect('motion_notify_event', on_move)
plt.savefig(__file__+".png")
plt.show()
从图中可以看出,plot
表现得与预期一致,显示平面上方的红点和下方的蓝点。
请注意,我使用了matplotlib 2.0.0来制作这些图;我不确定,1.5.3或以下是否相同。
为什么不能“预补偿”背景点的颜色与叠加层混合的一些见解,以便产生的颜色应该是完全蓝色:
我们保留RGBA colorsceme,其中每种颜色由元组(红色,绿色,蓝色,alpha)表示,其中每个通道可以取0
和1
之间的值。
生成的颜色应为全蓝色:
cres = (0,0,1,1)
。叠加层的颜色可以是半透明的红色:cover = (1,0,0,0.5)
。
然后可以使用通常的colormixing formulae来计算点的颜色
cdot = (1,0,2,1)
。
正如您所看到的,蓝色通道需要2
才能正常工作,这超出了颜色系统的范围。当然,您可能需要验证对于任何其他颜色cover
这仍然是正确的,但它已经直观清晰:对于任何混合使用透明色cover
,cdot
的蓝色频道将大于1
,从而产生不存在的颜色。