简体   繁体   English

Matplotlib 3D条形图:轴问题

[英]Matplotlib 3D Bar chart: axis issue

I am having issue with getting data on x,y,z axis..below is my code. 我在获取x,y,z轴上的数据时遇到问题。下面是我的代码。 Is there any issue with the way i have defined range(dx,dy.dz) for different axis. 我为不同轴定义range(dx,dy.dz)的方式是否有问题。

result=[['122', '109', '2343', '220', '19'],
 ['15', '407', '37', '10', '102'],
 ['100', '100', '100', '100', '100'],
 ['113', '25', '19', '31', '112'],
 ['43', '219', '35', '33', '14'],
 ['132', '108', '256', '119', '14'],
 ['22', '48', '352', '51', '438']]

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.dates as dates

def format_date(x, pos=None):
     return dates.num2date(x).strftime('%m/%d/%Y')

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

xpos=[10/11/2013,10/12/2013,10/13/2013,10/14/2013,10/15/2013]
ypos=['A1','C1','G1','M1','M2','M3','P1']
zpos=result

dx=[5]
dy=[7]
dz=[7]
ax1.w_xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
ax1.bar3d(xpos,ypos,zpos,dx,dy,dz,color='#00ceaa')
plt.show()

I am getting below error: 我得到以下错误:


TypeError                                 Traceback (most recent call last)
<ipython-input-45-02cd8e7ee228> in <module>()
     18 dz=[17]
     19 ax1.w_xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
---> 20 ax1.bar3d(xpos,ypos,zpos,dx,dy,dz,color='#00ceaa')
     21 plt.show()

C:\Users\Andalib\Anaconda\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py in bar3d(self, x, y, z, dx, dy, dz, color, zsort, *args, **kwargs)
   2316             maxx = max(xi + dxi, maxx)
   2317             miny = min(yi, miny)
-> 2318             maxy = max(yi + dyi, maxy)
   2319             minz = min(zi, minz)
   2320             maxz = max(zi + dzi, maxz)

TypeError: cannot concatenate 'str' and 'int' objects

There are the following issues in your code: 您的代码中存在以下问题:

  • xpos and ypos are usually a flatenned meshgrid with the positions of the base of the 3D bars xposypos通常是带有3D条形图的底部位置的平面网格
  • zpos gives the position of the base along the z axis, which is usually zero unless you want the bars looking like they are flying zpos给出沿z轴的基座位置,该位置通常为零,除非您希望这些条看起来像在飞行
  • xpos , ypos and zpos must have the same flattened shape and must all be 1-D arrays xposyposzpos必须具有相同的展平形状,并且都必须是1-D数组

Since you know the positions for each value you can use a np.arange() to create the positions xpos and ypos , and afterwards set the tick labels. 由于您知道每个值的位置,因此可以使用np.arange()创建位置xposypos ,然后设置刻度标签。

The example code is: 示例代码为:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm

result=[['122', '109', '2343', '220', '19'],
 ['15', '407', '37', '10', '102'],
 ['100', '100', '100', '100', '100'],
 ['113', '25', '19', '31', '112'],
 ['43', '219', '35', '33', '14'],
 ['132', '108', '256', '119', '14'],
 ['22', '48', '352', '51', '438']]

result = np.array(result, dtype=np.int)

fig=plt.figure(figsize=(5, 5), dpi=150)
ax1=fig.add_subplot(111, projection='3d')

xlabels = np.array(['10/11/2013', '10/12/2013', '10/13/2013',
                    '10/14/2013', '10/15/2013'])
xpos = np.arange(xlabels.shape[0])
ylabels = np.array(['A1','C1','G1','M1','M2','M3','P1'])
ypos = np.arange(ylabels.shape[0])

xposM, yposM = np.meshgrid(xpos, ypos, copy=False)

zpos=result
zpos = zpos.ravel()

dx=0.5
dy=0.5
dz=zpos

ax1.w_xaxis.set_ticks(xpos + dx/2.)
ax1.w_xaxis.set_ticklabels(xlabels)

ax1.w_yaxis.set_ticks(ypos + dy/2.)
ax1.w_yaxis.set_ticklabels(ylabels)

values = np.linspace(0.2, 1., xposM.ravel().shape[0])
colors = cm.rainbow(values)
ax1.bar3d(xposM.ravel(), yposM.ravel(), dz*0, dx, dy, dz, color=colors)
plt.show()

which gives: 这使:

在此处输入图片说明

you can also use the values array proportional to dz : 您还可以使用与dz成比例的values数组:

values = (dz-dz.min())/np.float_(dz.max()-dz.min())

在此处输入图片说明

As the error suggests, your result list has to contain integers, and not strings. 如错误所示, result列表必须包含整数,而不是字符串。 You can convert it to integers with list comprehension: 您可以使用列表理解将其转换为整数:

result = [[int(i) for i in sublist] for sublist in result]

Or, better yet, you can use np.array : 或者,更好的是,您可以使用np.array

import numpy as np
result = np.array(result, dtype=np.int)

Update : 更新

As bar3d documentation (and example ) suggest, ipos arrays should hold the positions of bars; 正如bar3d 文档 (和example )所建议的那样, ipos数组应保留bar的位置; di arrays should hold the distances between bars. di数组应保持条形之间的距离。 Your xpos and ypos lists hold what is called the tick labels. 您的xposypos列表保存称为刻度线的标签。 So, you need to change these and then set tick labels of relevant axes to given xpos and ypos . 因此,您需要更改它们,然后将相关轴的刻度标签设置为给定的xposypos According tho the example provided, you can do it in the following way: 根据提供的示例,您可以通过以下方式进行操作:

xpos, ypos = np.meshgrid(np.arange(5)+0.5, np.arange(7)+0.5)
xpos = xpos.flatten()
ypos = ypos.flatten()
zpos = np.zeros(5*7)
dx = np.ones_like(zpos)
dy = dx.copy()
dz = result.flatten()
xticks=['','10/11/2013','10/12/2013','10/13/2013','10/14/2013','10/15/2013']
yticks=['','A1','C1','G1','M1','M2','M3','P1']
ax1.set_xticklabels(xticks)
ax1.set_yticklabels(yticks)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM