Добавление цвета к точкам данных графика Polar Scatter

Я пытаюсь сделать полярный сюжет с Python, в чем я до сих пор несколько преуспел.

Пример графика полярного рассеяния

У меня было несколько вопросов, по которым я надеялся получить некоторые идеи/предложения:

  1. возможно ли установить цвет кругов на определенное значение (например: «n» в приведенном ниже примере кода)? Если да, могу ли я установить определенные цветовые диапазоны? Например: 0-30: красный цвет, 31-40: желтый; 41-60: зеленый

Примечание. Следуя примерам из Plot с условными цветами на основе значений в R, я безуспешно пробовал ax.scatter(ra,dec,c = ifelse(n < 30,’red','green'), pch = 19 ) =(

  1. как я могу сделать круги данных немного больше?

  2. можно ли переместить метку "90", чтобы заголовок графика не перекрывался? Я пробовал: x.set_rlabel_position(-22.5), но получаю сообщение об ошибке ("AttributeError: у объекта "PolarAxes" нет атрибута "set_rlabel_position"")

  3. Можно ли отображать только метки высот 0,30 и 60? Могут ли они быть ориентированы горизонтально (например, вдоль азимутальной линии 0)?

Большое спасибо! Ждем ваших предложений =)

import numpy
import matplotlib.pyplot as pyplot

dec = [10,20,30,40,50,60,70,80,90,80,70,60,50,40,30,20,10]
ra = [225,225,225,225,225,225,225,225,225,45,45,45,45,45,45,45,45]
n = [20,23,36,43,47,48,49,50,51,50,48,46,44,36,30,24,21]

ra = [x/180.0*3.141593 for x in ra]
fig = pyplot.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax.set_ylim(0,90)
ax.set_yticks(numpy.arange(0,90,10))
ax.scatter(ra,dec,c ='r')
ax.set_title("Graph Title here", va='bottom')
pyplot.show()

person luke    schedule 30.03.2017    source источник


Ответы (2)


<сильный>1. раскрашивать точки
Использование аргумента c для scatter позволяет раскрашивать точки. В этом случае вы можете предоставить ему массив n и позволить выбрать цвет в соответствии с цветовой картой. Цветовая карта будет состоять из разных цветов (31 раз красный, 10 раз желтый, 20 раз зеленый). Преимущество использования цветовой карты заключается в том, что она позволяет легко использовать цветовую шкалу.

<сильный>2. увеличить круги можно с помощью аргумента s.

<сильный>3. добавление пробела между меткой и заголовком Это лучше всего сделать, переместив заголовок немного вверх, используя аргумент y для set_title. Чтобы заголовок не выходил за пределы рисунка, мы можем использовать метод subplots_adjust и сделать top немного меньше. (Обратите внимание, что это работает, только если оси созданы через подграфики.)

<сильный>4. Показывать только определенные метки можно, установив галочки как ax.set_yticks([0,30,60]), а ориентация ylabels вдоль горизонтальной линии выполняется с помощью ax.set_rlabel_position(0). (Обратите внимание, что set_rlabel_position доступно, начиная с версии 1.4, если у вас более ранняя версия, подумайте об обновлении).

введите здесь описание изображения

import numpy as np
import matplotlib.pyplot as plt # don't use pylab
import matplotlib.colors
import matplotlib.cm

dec = [10,20,30,40,50,60,70,80,90,80,70,60,50,40,30,20,10]
ra = [225,225,225,225,225,225,225,225,225,45,45,45,45,45,45,45,45]
n = [20,23,36,43,47,48,49,50,51,50,48,46,44,36,30,24,21]

ra = [x/180.0*np.pi for x in ra]
fig = plt.figure()
ax = fig.add_subplot(111,polar=True)
ax.set_ylim(0,90)

# 4. only show 0,30, 60 ticks
ax.set_yticks([0,30,60])
# 4. orient ylabels along horizontal line
ax.set_rlabel_position(0)

# 1. prepare cmap and norm
colors= ["red"] * 31 + ["gold"] * 10 + ["limegreen"] * 20
cmap=matplotlib.colors.ListedColormap(colors)
norm = matplotlib.colors.Normalize(vmin=0, vmax=60)   
# 2. make circles bigger, using `s` argument
# 1. set different colors according to `n`
sc = ax.scatter(ra,dec,c =n, s=49, cmap=cmap, norm=norm, zorder=2)

# 1. make colorbar
cax = fig.add_axes([0.8,0.1,0.01,0.2])
fig.colorbar(sc, cax=cax, label="n", ticks=[0,30,40,60])
# 3. move title upwards, then adjust top spacing
ax.set_title("Graph Title here", va='bottom', y=1.1)
plt.subplots_adjust(top=0.8)

plt.show()
person ImportanceOfBeingErnest    schedule 30.03.2017
comment
Большое спасибо за невероятно подробное объяснение! Это о-о-о-очень полезно =) - person luke; 31.03.2017
comment
Я понял, когда просматривал код, что неправильно прочитал значения кругов. На самом деле эти значения должны быть обратными (например, центр должен быть равен 90°, а крайний круг должен быть равен 0), поскольку они представляют собой угол возвышения (когда наблюдатель находится в центре диаграммы). Хм... Есть ли способ исправить это? - person luke; 31.03.2017
comment
Просто быстрое обновление: я узнал, как изменить ориентацию графика, чтобы 0 указывал прямо вверх (т.е. на север). Я только что добавил: ax.set_theta_zero_location('N') ax.set_theta_direction(-1) и это помогло =) - person luke; 31.03.2017
comment
Понятно!!! =) Решение было таким: 1. изменить порядок ylim: ax.set_ylim(90,0) 2. вычесть 90 из каждого значения dec: dec[:] = [90 - x вместо x в dec] Работало как прелесть =) Еще раз ОГРОМНОЕ спасибо всем за вашу помощь!! - person luke; 31.03.2017

для цвета вы можете использовать c=[список цветов для каждого элемента], для размера s= как здесь:

ax.scatter(ra,dec,c =['r' if a < 31 else 'yellow' if a < 41 else 'green' for a in n], s =40)

для заголовка и оси я бы рекомендовал изменить положение заголовка:

ax.set_title("Graph Title here", va='bottom', y=1.08)

возможно, вам придется отрегулировать размер рисунка, чтобы заголовок отображался правильно:

fig = pyplot.figure(figsize=(7,8))

для видимости тиков вы можете использовать:

for label in ax.yaxis.get_ticklabels():
    label.set_visible(False)
for label in ax.yaxis.get_ticklabels()[::3]:
    label.set_visible(True)

в общем и целом:

import numpy
import matplotlib.pyplot as pyplot

dec = [10,20,30,40,50,60,70,80,90,80,70,60,50,40,30,20,10]
ra = [225,225,225,225,225,225,225,225,225,45,45,45,45,45,45,45,45]
n = [20,23,36,43,47,48,49,50,51,50,48,46,44,36,30,24,21]

ra = [x/180.0*3.141593 for x in ra]
fig = pyplot.figure(figsize=(7,8))
ax = fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax.set_ylim(0,90)
ax.set_yticks(numpy.arange(0,90,10))

ax.scatter(ra,dec,c =['r' if a < 31 else 'yellow' if a < 41 else 'green' for a in n], s =40)
ax.set_title("Graph Title here", va='bottom', y=1.08)
for label in ax.yaxis.get_ticklabels():
    label.set_visible(False)
for label in ax.yaxis.get_ticklabels()[::3]:
    label.set_visible(True)
pyplot.show()
person Martyna    schedule 30.03.2017