2012-01-18 73 views
8

我是Python新手(之前是IDL用户),所以我希望我以一种可以理解的方式提出这个问题。我一直在试图创建一个带有x个bin的极坐标图,其中bin中的数据被平均并赋予与该值相关的颜色。这似乎工作正常,同时使用plt.fill命令,我可以定义bin和填充颜色。问题出现在我尝试制作一个彩条时去解决。我不断收到状态为AttributeError的错误:'图'对象没有属性'autoscale_None'为plt.fill制作的阴影创建颜色条

任何建议将有帮助谢谢。

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib as mpl 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 
from matplotlib.pyplot import figure, show, rc, grid 
import pylab 

r = np.arange(50)/5. 
rstep = r[1] - r[0] 
theta = np.arange(50)/50.*2.*np.pi 
tstep = theta[1] - theta[0] 
colorv = np.arange(50)/50. 

# force square figure and square axes looks better for polar, IMO 
width, height = mpl.rcParams['figure.figsize'] 
size = min(width, height) 
# make a square figure 
fig = figure(figsize=(size, size)) 
ax = fig.add_axes([0.1, 0.1, .8, .8])#, polar=True) 

my_cmap = cm.jet 
for j in range(len(r)): 
    rbox = np.array([r[j], r[j], r[j]+ rstep, r[j] + rstep]) 
    for i in range(len(theta)): 
     thetabox = np.array([theta[i], theta[i] + tstep, theta[i] + tstep, theta[i]]) 
     x = rbox*np.cos(thetabox) 
     y = rbox*np.sin(thetabox) 
     plt.fill(x,y, facecolor = my_cmap(colorv[j])) 



# Add colorbar, make sure to specify tick locations to match desired ticklabels 
cbar = fig.colorbar(fig, ticks=[np.min(colorv), np.max(colorv)]) 
cb = plt.colorbar() 
plt.show() 

*这里是我的真实数据稍微好一点的例子,有洞失踪无处不在,所以在这个例子中,我只是做了一个很大的圆的四分之一。当我尝试啮合时,代码似乎尝试插入这些区域。

r = np.arange(50)/50.*7. + 3. 
rstep = r[1] - r[0] 
theta = np.arange(50)/50.*1.5*np.pi - np.pi 
tstep = theta[1] - theta[0] 
colorv = np.sin(r/10.*np.pi) 

# force square figure and square axes looks better for polar, IMO 
width, height = mpl.rcParams['figure.figsize'] 
size = min(width, height) 
# make a square figure 
fig = figure(figsize=(size, size)) 
ax = fig.add_axes([0.1, 0.1, .8, .8])#, polar=True) 

my_cmap = cm.jet 

for j in range(len(r)): 
    rbox = np.array([r[j], r[j], r[j]+ rstep, r[j] + rstep]) 
    for i in range(len(theta)): 
     thetabox = np.array([theta[i], theta[i] + tstep, theta[i] + tstep, theta[i]]) 
     x = rbox*np.cos(thetabox) 
     y = rbox*np.sin(thetabox) 
     plt.fill(x,y, facecolor = my_cmap(colorv[j])) 


# Add colorbar, make sure to specify tick locations to match desired ticklabels 
#cbar = fig.colorbar(fig, ticks=[np.min(colorv), np.max(colorv)]) 
#cb = plt.colorbar() 
plt.show() 

然后与参与啮合...

从matplotlib.mlab进口的GridData

r = np.arange(50)/5. 
rstep = r[1] - r[0] 
theta = np.arange(50)/50.*1.5*np.pi - np.pi 
tstep = theta[1] - theta[0] 
colorv = np.sin(r/10.*np.pi) 

# force square figure and square axes looks better for polar, IMO 
width, height = mpl.rcParams['figure.figsize'] 
size = min(width, height) 
# make a square figure 
fig = figure(figsize=(size, size)) 
ax = fig.add_axes([0.1, 0.1, .8, .8])#, polar=True) 

my_cmap = cm.jet 

x = r*np.cos(theta) 
y = r*np.sin(theta) 
X,Y = np.meshgrid(x,y) 

data = griddata(x,y,colorv,X,Y) 
cax = plt.contourf(X,Y, data) 
plt.colorbar() 

# Add colorbar, make sure to specify tick locations to match desired ticklabels 
#cbar = fig.colorbar(fig, ticks=[np.min(colorv), np.max(colorv)]) 
#cb = plt.colorbar() 
plt.show() 

回答

1

所以我找到了解决方法。由于我知道一个我肯定不会有数据的地区,因此我在那里绘制了一些图。我确信这些数据涵盖了我灌注的全部范围。然后我将其覆盖(无论如何,这个区域将会被覆盖,它显示了“地球”所在的位置)。现在,我可以继续使用我最初使用的plt.fill,并使用随机盆栽数据中的颜色条。我知道这可能不是正确的方式,但它可以工作,并且不会尝试插入我的数据。

非常感谢您帮助完成此排序。如果你知道更好的方法,我很乐意听到它!

hid = plt.pcolormesh(X,Y, data, antialiased=True) 

#here we cover up the region that we just plotted in 
r3 = [1 for i in range(360)] 
theta3 = np.arange(360)*np.pi/180. 
plt.fill(theta3, r3, 'w') 

#now we can go through and fill in all the regions 
for j in range(len(r)): 
    rbox = np.array([r[j], r[j], r[j]+ rstep, r[j] + rstep]) 
    for i in range(len(theta)): 
     thetabox = np.array([theta[i], theta[i] + tstep, theta[i] + tstep, theta[i]]) 
     x = rbox*np.cos(thetabox) 
     y = rbox*np.sin(thetabox) 
     colorv = np.sin(r[j]/10.*np.pi) 
     plt.fill(thetabox,rbox, facecolor = my_cmap(colorv)) 
#And now we can plot the color bar that fits the data Tada :) 
plt.colorbar() 
plt.show() 

Output of above code

7

colorbar需要的东西是ScalarMappable一个实例,以便从他们做出一个彩条。

因为你手动设置每个瓷砖,没有什么本质上有一个彩条。

有很多方法可以从你的色彩地图中伪造它,但在这种情况下,有一个更简单的解决方案。

pcolormesh完全符合你的要求,而且速度会更快。

举个例子:

import numpy as np 
import matplotlib.pyplot as plt 

# Linspace makes what you're doing _much_ easier (and includes endpoints) 
r = np.linspace(0, 10, 50) 
theta = np.linspace(0, 2*np.pi, 50) 

fig = plt.figure() 
ax = fig.add_subplot(111, projection='polar') 

# "Grid" r and theta into 2D arrays (see the docs for meshgrid) 
r, theta = np.meshgrid(r, theta) 
cax = ax.pcolormesh(theta, r, r, edgecolors='black', antialiased=True) 

# We could just call `plt.colorbar`, but I prefer to be more explicit 
# and pass in the artist that I want it to extract colors from. 
fig.colorbar(cax) 

plt.show() 

enter image description here

或者,如果你愿意的非极性轴,如您的示例代码:

import numpy as np 
import matplotlib.pyplot as plt 

r = np.linspace(0, 10, 50) 
theta = np.linspace(0, 2*np.pi, 50) 

# "Grid" r and theta and convert them to cartesian coords... 
r, theta = np.meshgrid(r, theta) 
x, y = r * np.cos(theta), r * np.sin(theta) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.axis('equal') 

cax = ax.pcolormesh(x, y, r, edgecolors='black', antialiased=True) 

fig.colorbar(cax) 

plt.show() 

enter image description here

注意:如果您希望边界线稍暗一些,只需指定linewidth=0.5或类似于pcolormesh的东西。

最后,如果您确实想从原始代码中的色彩地图直接制作色条,您可以从中创建一个ScalarMappable实例并将其传递给colorbar。它比听起来容易,但它有点冗长。

举个例子,在你的原代码,如果你这样做了以下内容:

cax = cm.ScalarMappable(cmap=my_cmap) 
cax.set_array(colorv) 
fig.colorbar(cax) 

应该做你想要什么。

+1

在一个侧面说明,在'抗锯齿= TRUE' kwarg一般不会是必要的matplotlib命令(对大部分事情默认值)。由于性能原因,“pcolormesh”默认为无抗锯齿,因为网格“单元”通常是垂直的,并且看起来没有抗锯齿。在这种情况下,单元格不是垂直的,并且性能影响不会太差,因此打开抗锯齿功能打开网格是个好主意。 – 2012-01-18 20:15:10

+0

+1,btw:“有很多方法可以从你的色彩地图中伪造它”请问,你能给出一些提示/示例吗?我一直试图从OP代码中取出色条,但没有成功...... – joaquin 2012-01-18 20:30:54

+0

我正在考虑使用代理艺术家,但我认为可能有更清晰的方法。我会添加一个例子。 – 2012-01-18 20:35:24