Затените «клетки» на полярном графике с помощью matplotlib

У меня есть набор регулярно распределенных точек (& # x3B8; = n * & # x3C0; / 6, r = 1 ... 8), каждая из которых имеет значение в [0, 1]. Я могу построить их с их значениями в Matplotlib, используя

polar(thetas, rs, c=values)

Но вместо того, чтобы иметь только скудную маленькую точку, я бы хотел закрасить соответствующую «клетку». (т.е. все до половины до соседних точек) с цветом, соответствующим значению точки:

Polar plot with shaded cells

(Обратите внимание, что здесь мои значения просто [0, .5, 1], в действительности они будут все между 0 и 1. Есть ли какой-нибудь прямой способ реализовать это (или что-то достаточно близкое) с помощью matplotlib? Проще ли думать об этом как о 2D-гистограмме?

Ответы на вопрос(3)

Решение Вопроса

Конечно! Просто используйтеpcolormesh на полярных осях.

Например.

import matplotlib.pyplot as plt
import numpy as np

# Generate some data...
# Note that all of these are _2D_ arrays, so that we can use meshgrid
# You'll need to "grid" your data to use pcolormesh if it's un-ordered points
theta, r = np.mgrid[0:2*np.pi:20j, 0:1:10j]
z = np.random.random(theta.size).reshape(theta.shape)


fig, (ax1, ax2) = plt.subplots(ncols=2, subplot_kw=dict(projection='polar'))


ax1.scatter(theta.flatten(), r.flatten(), c=z.flatten())
ax1.set_title('Scattered Points')

ax2.pcolormesh(theta, r, z)
ax2.set_title('Cells')

for ax in [ax1, ax2]:
    ax.set_ylim([0, 1])
    ax.set_yticklabels([])

plt.show()

enter image description here

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

Похоже, что это на регулярной сетке от вашего графика, хотя. В таком случае с gridding это довольно просто. Если он уже заказан, это может быть так же просто, как вызовreshape, В противном случае, простой цикл или использованиеnumpy.histogram2d с вашимz значения в качестве весов будут делать то, что вам нужно.

 31 мая 2012 г., 22:20
Потратил слишком много времени на это ... но это наконец (в основном) сделано. Опубликовано как ответ.
 31 мая 2012 г., 19:42
Это & APOS; smuch менее эффективный для обычных сеток, хотя. Не используйте его, если ваши данные находятся в регулярной сетке.
 31 мая 2012 г., 19:48
Если у вас есть пример со сглаженными прямоугольниками, не стесняйтесь опубликовать его! Это был бы лучший ответ, чем мой.
 31 мая 2012 г., 19:40
pcolor() тоже работает (Был бы мой пост первым, если бы я не нашел время, чтобы попытаться сгладить получающиеся прямоугольники ... ну, хорошо.)
 31 мая 2012 г., 19:45
Раньше вы могли сгладить прямоугольники, передаваяresolution ключевое слово аргумент полярным осям во время инициализации, но это теперь игнорируется, по-видимому ...

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

from matplotlib.pylab import *
ax = subplot(111, projection='polar')

# starts grid and colors
th = array([pi/6 * n for n in range(13)]) # so n = 0..12, allowing for full wrapping
r = array(range(9)) # r = 0..8
c = array([[random_integers(0, 10)/10 for y in range(th.size)] for x in range(r.size)])

# The smoothing
TH = cbook.simple_linear_interpolation(th, 10)

# Properly padding out C so the colors go with the right sectors (can't remember the proper word for such segments of wedges)
# A much more elegant version could probably be created using stuff from itertools or functools
C = zeros((r.size, TH.size))
oldfill = 0
TH_ = TH.tolist()

for i in range(th.size):
    fillto = TH_.index(th[i])

    for j, x in enumerate(c[:,i]):
        C[j, oldfill:fillto].fill(x)

    oldfill = fillto

# The plotting
th, r = meshgrid(TH, r)
ax.pcolormesh(th, r, C)
show()
 Manuel Ebert31 мая 2012 г., 22:36
Спасибо за прохождение лишней мили, я действительно ценю это!
 31 мая 2012 г., 22:42
@Nkosinathi: Добро пожаловать. И, к счастью для меня, хотя я не думал об этом, работая над вышеизложенным, я понял, что могу использовать его для задачи, которую я выполняю для работы.

Это может быть сделано довольно хорошо, если рассматривать его как столбчатую диаграмму:

import matplotlib.pyplot as plt
import numpy as np
from random import choice

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)

for i in xrange(12*8):
    color = choice(['navy','maroon','lightgreen'])
    ax.bar(i * 2 * np.pi / 12, 1, width=2 * np.pi / 12, bottom=i / 12,
           color=color, edgecolor = color)
plt.ylim(0,10)
ax.set_yticks([])
plt.show()

Производит:

enter image description here

 01 июн. 2012 г., 16:32
О, классно. Не могли бы вы также установитьedgecolor='None' вbar() позвонить, хотя?
 01 июн. 2012 г., 16:36
Ну, это интересно. К сожалению, я не могу проверить это самостоятельно, так как в настоящее время у меня нет доступа к компьютеру, оборудованному matplotlib.
 01 июн. 2012 г., 16:35
@JAB - Вы можете подумать, что это должно сработать, но это приводит к совершенно пустому сюжету! Должна быть ошибка (по крайней мере, в моей версии).
 Manuel Ebert01 июн. 2012 г., 15:40
Ха-ха, действительно хорошее решение! Просто нужно подобрать цвет по значению, а в остальном именно то, что мне нужно, и в кратчайшие сроки. Однако решения JAB's solut и Joe являются чуть более универсальными.

Ваш ответ на вопрос