2012-01-18 24 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