Ale*_*ord 8 python matplotlib colorbar
我是Python的新手(之前是IDL用户)所以我希望我能以一种可以理解的方式问这个问题.我一直在尝试创建一个带有x个bin的极坐标图,其中bin中的数据被平均并给出与该值相关联的颜色.这似乎在使用plt.fill命令时工作正常,我可以在其中定义bin然后填充填充颜色.当我尝试制作一个颜色条时,问题就来了.我一直收到状态AttributeError的错误:'Figure'对象没有属性'autoscale_None'
任何建议都会有所帮助,谢谢.
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()
Run Code Online (Sandbox Code Playgroud)
*这里是我的真实数据的一个稍微好一点的例子,到处都有漏洞,所以在这个例子中,我只是在圆圈的四分之一处做了一个大的.当我尝试网格化时,代码似乎试图在这些区域上进行插值.
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()
Run Code Online (Sandbox Code Playgroud)
然后涉及到一个网格...
来自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()
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
或者,如果您更喜欢非极轴,如示例代码中所示:
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()
Run Code Online (Sandbox Code Playgroud)
注意:如果你更喜欢边界线不那么暗,只需指定linewidth=0.5
或类似的东西pcolormesh
.
最后,如果您确实希望直接从原始代码中的colormap生成颜色条,则可以ScalarMappable
从中创建一个实例并将其传递给colorbar
.它比听起来容易,但它有点冗长.
例如,在原始代码中,如果您执行以下操作:
cax = cm.ScalarMappable(cmap=my_cmap)
cax.set_array(colorv)
fig.colorbar(cax)
Run Code Online (Sandbox Code Playgroud)
它应该做你想要的.
所以我找到了一个解决方法。因为我知道某个区域肯定没有数据,所以我在那里绘制了一些数据。我已确保数据涵盖了我正在灌封的整个范围。然后我将其覆盖(无论如何,该区域都会被覆盖,它显示了“地球”所在的位置)。现在我可以像原来一样使用 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()
Run Code Online (Sandbox Code Playgroud)