Создание цветовой полосы для участка, сделанного с plt.заполнить

Я новичок в Python (был пользователем IDL до руки), поэтому я надеюсь, что я спрашиваю Это понятным образом. Я пытался создать полярный график с числом ячеек x, где данные в ячейке усредняются и задается цвет, связанный с этим значением. Кажется, это работает нормально при использовании plt.команда fill, где я могу определить бункер, а затем цвет заливки. Проблема возникает, когда я пытаюсь сделать цветовую полосу, чтобы пойти с ней. Я продолжаю получать ошибки, которые state 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()

* вот немного лучший пример моих реальных данных, везде отсутствуют отверстия, поэтому в этом примере я только что сделал большой в четверти круга. Когда я пробовал цепляться, код, похоже, пытается интерполировать эти области.

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

2 ответов


colorbar нужны вещи, чтобы быть экземпляром ScalarMappable для того, чтобы сделать colorbar из них.

поскольку вы вручную устанавливаете каждую плитку, нет ничего, что по существу имеет цветовую панель.

есть несколько способов подделать его из вашей цветовой карты, но в этом случае есть гораздо более простое решение.

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.

наконец, если вы хотите напрямую сделать colorbar из цветовой карты в исходном коде, вы создадите экземпляр ScalarMappable от него и передать это colorbar. Это проще. чем это звучит, но это немного многословно.

в качестве примера в исходном коде, если вы сделаете что-то вроде следующего:

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

он должен делать то, что вы хотите.


поэтому я нашел обходной путь. Поскольку я знаю регион, где у меня определенно не будет данных, я построил там некоторые. Я убедился, что данные охватывают весь диапазон того, что я заливаю. Затем я покрываю его (этот регион все равно будет покрыт, он показывает, где находится "Земля"). Теперь я могу использовать plt.заполните, как я изначально, и используйте цветовую полосу из случайно помещенных данных. Я знаю, что это, вероятно, неправильный способ, но он работает и не пытается интерполируйте мои данные.

большое спасибо за помощь в сортировке. и если вы знаете лучший способ, я был бы рад это услышать!

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