首页 > 解决方案 > 将数据透视表转为 3D 图形

问题描述

我的桌子上有 3 列A (str)B (str)C (str)。在我的数据透视表上,列C被分解为其子类别,c1 (str)例如c5 (str). 由于这些子类别是标题,因此它们包含的值是该子类别的计数AB一起发生的事件。考虑这个例子:

df = pd.DataFrame({'A': '100 200 100 200'.split(),
                   'B': 'foo foo bar bar'.split(),
                   'c1': np.arange(4),
                   'c2': '5 0 8 2'.split(), 
                   'c3': '0 2 1 0'.split(), 
                   'c4': np.arange(4), 
                   'c5': '9 7 4 3'.split()})

我可以使用 excel 上的 3D 柱形图选项来创建 3D 可视化,使得c1toc5列的值出现在 上z-axis,即列的高度。Excel在图表的一个轴上连接列A和在一起。B

问题:如何在 python 中绘制类似的 3D 柱形图?

我尝试使用 matplotlib,这里的示例3D Bar Chart with Matplotlib如下所示:

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import style
style.use('ggplot')

fig = plt.figure()
ax1 = fig.add_subplot(111, projection='3d')

x3 = df.columns[2:]
y3 = df['B'] + df['A']
z3 = np.zeros(5)

dx = np.ones(5)
dy = np.ones(5)
dz = df.iloc[:, 2:]

ax1.bar3d(x3, y3, z3, dx, dy, dz)

ax1.set_xlabel('A')
ax1.set_ylabel('B')
ax1.set_zlabel('C Count')

但我收到以下错误,我认为这是由一维和二维数组引起的。

<ipython-input-21-c88ff0ea352d> in <module>
     10 dz = df.iloc[:, 2:]
     11 
---> 12 ax1.bar3d(x3, y3, z3, dx, dy, dz)
     13 
     14 

C:\Anaconda\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py in bar3d(self, x, y, z, dx, dy, dz, color, zsort, shade, *args, **kwargs)
   2480 
   2481         x, y, z, dx, dy, dz = np.broadcast_arrays(
-> 2482             np.atleast_1d(x), y, z, dx, dy, dz)
   2483         minx = np.min(x)
   2484         maxx = np.max(x + dx)

C:\Anaconda\lib\site-packages\numpy\lib\stride_tricks.py in broadcast_arrays(*args, **kwargs)
    257     args = [np.array(_m, copy=False, subok=subok) for _m in args]
    258 
--> 259     shape = _broadcast_shape(*args)
    260 
    261     if all(array.shape == shape for array in args):

C:\Anaconda\lib\site-packages\numpy\lib\stride_tricks.py in _broadcast_shape(*args)
    191     # use the old-iterator because np.nditer does not handle size 0 arrays
    192     # consistently
--> 193     b = np.broadcast(*args[:32])
    194     # unfortunately, it cannot handle 32 or more arguments directly
    195     for pos in range(32, len(args), 31):

ValueError: shape mismatch: objects cannot be broadcast to a single shape```

标签: pythonpython-3.xpandasnumpymatplotlib

解决方案


推荐阅读