How to customize axes in 3D hist python/matplotlib

匿名 (未验证) 提交于 2019-12-03 02:23:02

问题:

I am trying to plot this data set using 3D bar

  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 

I have written the code here.

  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() 

But it doesn't seem to be the right way to do that? Can any one help by showing how do we customize axes ?

It works when I use plot

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

instead of bar3D

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

but I wanna use 3D histogram for better understading.

回答1:

It seems you're misunderstanding the parameters on the bar3d function:

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

  • Parameters x, y and z are the coordinates of the bars on the x, y and z axis respectively.
  • Parameters dx, dy and dz are the sizes of the bars on the x, y and z axis respectively.

For example, if you want to plot the following dataset:

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

You have to define these parameters like so:

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() 

This is:

  • You plot one bar in (1, 2003, 0) (x, y, z) with height 2.
  • You plot one bar in (2, 2008, 0) (x, y, z) with height 3.
  • Both bars have a size of 1 on the x and y axis, it could be less though, it's just an aesthetic issue.

The script above generates the following plot:

If you look at the image you'll notice some minor format problems:

  • Years are represented in exponential notation.
  • Bars are not centered on their (x, y) coordinates.

We can actually solve this with a few tweaks:

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() 

And finally this is what we'll get:



回答2:

There are too many places you got it wrong, so I'd just post what it should be like:

import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D  data = pd.DataFrame({'A': [1,1,2,2,2,3,1,1,1], 'B': [2003,2003,2008,2007,2007,2004,2004,2004,2004] ,'freq': [2,2,1,2,2,1,3,3,3] }) fig = plt.figure() ax = fig.add_subplot(111, 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') PV = pd.pivot_table(data, values='freq',rows='A',cols='B') xpos=np.arange(PV.shape[0]) ypos=np.arange(PV.shape[1]) xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25) xpos = xpos.flatten() ypos = ypos.flatten() zpos=np.zeros(PV.shape).flatten() dx=0.5 * np.ones_like(zpos) dy=0.5 * np.ones_like(zpos) dz=PV.values.ravel() dz[np.isnan(dz)]=0.  ax.bar3d(xpos,ypos,zpos,dx,dy,dz,color='b', alpha=0.5) ax.set_xticks([.5,1.5,2.5]) ax.set_yticks([.5,1.5,2.5,3.5]) ax.w_yaxis.set_ticklabels(PV.columns) ax.w_xaxis.set_ticklabels(PV.index) ax.set_xlabel('A') ax.set_ylabel('B') ax.set_zlabel('Occurrence')  plt.savefig("test.png", dpi=300) plt.show() 



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!