I have 3 columns on my table, A (str)
, B (str)
and C (str)
. On my pivot table, column C
is broken down to its sub-categories, say c1 (str)
to c5 (str)
. As these subcategories are the headings, the values they contain are the counts of A
and B
happening together with respect to that subcategory. Consider this example:
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()})
I can use the 3D column chart options on excel to create 3D visualization, such that the values of c1
to c5
columns appear on the z-axis
, i.e. the height of the columns. Excel joins columns A
and B
together on one axis of the chart.
Question: How can I draw a similar 3D column graph in python?
I tried using matplotlib, and the example here 3D Bar Chart with Matplotlib like this:
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')
but I am getting the following error which I think is caused by having both 1D and 2D arrays.
<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```