3

I'm trying to make a polar plot with Python, of which I've been somewhat successful so far

polar scatter plot example

I did have a few questions for which I was hoping to get some ideas/suggestions:

  1. is it possible set the color of the circles to a specific value (e.g.: "n" in the sample code below)? If so, can I set specific color ranges? E.g: 0-30: red color, 31-40: yellow; 41-60: green

Note: following the examples from Plot with conditional colors based on values in R, I tried ax.scatter(ra,dec,c = ifelse(n < 30,’red','green'), pch = 19 ) without success =(

  1. how can I make the data circles a little bit bigger?

  2. can I move the "90" label so that the graph title does not overlap? I tried: x.set_rlabel_position(-22.5) but I get an error ("AttributeError: 'PolarAxes' object has no attribute 'set_rlabel_position'")

  3. Is it possible to only show the 0,30, and 60 elevation labels? Can these be oriented horizontally (e.g.: along the 0 azimuth line)?

Thank you so much! Looking forward to hearing your suggestions =)

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()
Community
  • 1
  • 1
luke
  • 61
  • 2
  • 7

2 Answers2

3

1. colorize points
Using the c argument of scatter allows to colorize the points. In thei caase you may supply the n array to it and let the color be chosen accoring to a colormap. The colormap would consist of the different colors (31 times red, 10 times yellow, 20 times green). The advantage of using a colormap is that it allows to easily use a colorbar.

2. making circles bigger can be done using the s argument.

3. adding space between label and title This would best be done by moving the title a bit upwards, using the y argument to set_title. In order for the title not to go outside the figure, we can use the subplots_adjust method and make top a little smaller. (Note that this works only if the axes are created via subplots.)

4. Only show certain ticks can be accomplished by setting the ticks as ax.set_yticks([0,30,60]) and orienting ylabels along a horizontal line is done by ax.set_rlabel_position(0). (Note that set_rlabel_position is available from version 1.4 on, if you have an earlier version, consider updating).

enter image description here

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()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thank you so much for the incredibly detailed explanation! This is s-u-p-e-r helpful =) – luke Mar 31 '17 at 00:54
  • I realized as I was going through the code that I read the values of the "circles" incorrectly. In reality, these values should be the other way around (e.g.: the center should be 90, and the outermost circle should be 0) since they represent the elevation angle (when the observer is located at the center of the chart). Hmmm... Is there a way to correct this? – luke Mar 31 '17 at 00:58
  • Just a quick updated: I learned how to change the orientation of the graph so that "0" is pointing straight up (i.e.: North). I just added: ax.set_theta_zero_location('N') ax.set_theta_direction(-1) and it did the trick =) – luke Mar 31 '17 at 01:16
  • Got it!!! =) The solution was: 1. change the order of the ylim: ax.set_ylim(90,0) 2. subtract 90 to each of the dec values: dec[:] = [90 - x for x in dec] Worked like a charm =) Thank you SO much to everyone again for all your help!! – luke Mar 31 '17 at 01:33
1

for color you can use c=[list of colors for each element], for size s= like here:

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

for the title and axis I would recommend changing the position of the title:

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

you may have to adjust the size of the figure to show the title correctly:

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

for visibility of ticks you can use:

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

overall:

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()
Martyna
  • 212
  • 1
  • 7