考虑使用自定义网格线的3D条形图:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.ticker import MultipleLocator
# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused import
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111, projection='3d')
ax.xaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.zaxis.set_major_locator(MultipleLocator(2))
nx = 10
ny = 10
colors = cm.tab20(np.linspace(0, 1, nx))
width = depth = 0.1
for x in np.arange(nx):
for y in np.arange(ny):
ax.bar3d(x, y, 0, width, depth, x+y, shade=False, color = colors[x], edgecolor = 'black')
plt.show()
如何放置横条,使横条在xy平面中的网格线彼此交叉处居中?
我在想类似的东西
ax.bar3d(x+0.5*depth, y+0.5*width, ...)
对我来说,尚不清楚matplotlib使用的偏移量是什么。它应适用于所有depth
和width
值。
对于2D条形图,有一个参数align = 'center'
,但似乎不适用于3D。
答案 0 :(得分:0)
在您看来,坐标转换实际上只是与轴边距结合的投影。因此,即使这些条正确放置在其中心,它们的外观也会偏移,并且该偏移取决于轴的大小,视角等。
此问题解答中原则上给出了解决方案: Removing axes margins in 3D plot
您可以通过减去条形图宽度的一半来使条形图居中,并添加一个补丁以消除z轴的空白。然后将z的下限设置为0,将条形图钉固定到网格上,并使它们在任何视角下居中。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.ticker import MultipleLocator
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.axis3d import Axis
def _get_coord_info_new(self, renderer):
mins, maxs, cs, deltas, tc, highs = self._get_coord_info_old(renderer)
correction = deltas * [0,0,1.0/4]
mins += correction
maxs -= correction
return mins, maxs, cs, deltas, tc, highs
if not hasattr(Axis, "_get_coord_info_old"):
Axis._get_coord_info_old = Axis._get_coord_info
Axis._get_coord_info = _get_coord_info_new
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111, projection='3d')
ax.xaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.zaxis.set_major_locator(MultipleLocator(2))
nx = 10
ny = 10
colors = cm.tab20(np.linspace(0, 1, nx))
width = depth = 0.1
for x in np.arange(nx):
for y in np.arange(ny):
ax.bar3d(x-width/2., y-depth/2., 0, width, depth, x+y, shade=False,
color = colors[x], edgecolor = 'black')
ax.set_zlim(0,None)
plt.show()