Skip to main content
 首页 » 编程设计

python之如何在 3D hist python/matplotlib 中自定义轴

2025年05月04日15zengkefu

我正在尝试使用 3D 条形图绘制此数据集

  B    A   freq 
  1  2003     2 
  1  2003     2 
  2  2008     1 
  2  2007     2 
  2  2007     2 
  3  2004     1 
  1  2004     3 
  1  2004     3 
  1  2004     3 

我在这里写了代码。

  data = pandas.DataFrame({'A':[2003,2003,2008,2007,2007,2004,2004,2004,2004] , 'B': [1,1,2,2,2,3,1,1,1] ,'C': [2,2,1,2,2,1,3,3,3] }) 
        fig = plt.figure() 
        ax = plt.axes(projection='3d') 
        # put 0s on the y-axis, and put the y axis on the z-axis 
 
        #ax.plot(data.A.values, data.B.values,data.freq.values, marker='o', linestyle='--', color="blue", label='ys=0, zdir=z') 
        xpos= range(len( data.A.values)) 
        ypos= range(len( data.B.values)) 
        zpos= range(len( data.freq.values)) 
 
        ax.bar3d(xpos, ypos, zpos, data.A.values, data.B.values,data.freq.values, color='b', alpha=0.5) 
 
        x_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) 
        ax.xaxis.set_major_formatter(x_formatter) 
 
        ax.set_xticks(data.A.values) 
        ax.set_yticks(data.B.values) 
        ax.set_zticks(data.freq.values) 
 
 
        plt.savefig("test.png", dpi=300) 
        plt.show() 

但这似乎不是正确的做法?任何人都可以通过展示我们如何自定义轴来提供帮助吗?

当我使用 plot 时它有效

ax.plot(data.A.values, data.B.values,data.freq.values,marker='o', linestyle='--', color='r') 

代替 bar3D

ax.bar3d(xpos, ypos, zpos, data.A.values, data.B.values,data.freq.values, color='b', alpha=0.5) 

但我想使用 3D 直方图来更好地理解。

请您参考如下方法:

看来您误解了 bar3d 函数的参数:

bar3d(x, y, z, dx, dy, dz)

  • 参数x、y和z分别是条在x、y和z轴上的坐标。
  • 参数 dx、dy 和 dz 分别是 x、y 和 z 轴上条形的大小。

例如,如果您想绘制以下数据集:

{'A': [1, 2], 'B': [2003, 2008] ,'freq': [2, 3] }

您必须像这样定义这些参数:

import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
 
xpos = [1, 2] 
ypos = [2003, 2008] 
zpos = [0, 0] 
 
dx = 1 
dy = 1 
dz = [2, 3] 
 
fig = plt.figure() 
ax = plt.axes(projection='3d') 
ax.bar3d(xpos, ypos, zpos, dx, dy, dz) 
plt.show() 

这是:

  • 您在 (1, 2003, 0) (x, y, z) 中绘制一个高度为 2 的条。
  • 您在 (2, 2008, 0) (x, y, z) 中绘制一个高度为 3 的条。
  • 两个条形在 x 轴和 y 轴上的大小均为 1,但可能更小,这只是一个美学问题。

上面的脚本生成如下图:

如果您查看图像,您会发现一些小的格式问题:

  • 年份以指数表示法表示。
  • 条形图不以它们的 (x, y) 坐标为中心。

我们实际上可以通过一些调整来解决这个问题:

import matplotlib 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
 
xpos = [1, 2] 
ypos = [2003, 2008] 
zpos = [0, 0] 
 
dx = 1 
dy = 1 
dz = [2, 3] 
 
# Move each (x, y) coordinate to center it on the tick 
 
xpos = map(lambda x: x - 0.5, xpos) 
ypos = map(lambda y: y - 0.5, ypos) 
 
fig = plt.figure() 
ax = plt.axes(projection='3d') 
ax.bar3d(xpos, ypos, zpos, dx, dy, dz) 
 
# Do not print years in exponential notation 
 
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) 
ax.yaxis.set_major_formatter(y_formatter) 
 
plt.show() 

最后这就是我们将得到的: