Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a polar mesh profile in Python

I would like to create a diagram like the figure below.


The picture above is from a paper Zhou K.-J. et al. 2014 about ion up-flow of ionosphere.
When I try something like:

import matplotlib.pyplot as plt
import numpy as np

thetabin=36
rbin=0.5
rmin=6
rmax=12
rmin=rmin+rbin
r_arr=linspace(rmin,rmax,(rmax-rmin)/rbin+1)
theta_arr=linspace(0,360,thetabin+1)
C = rand(len(r_arr), len(theta_arr))

plt.pcolor(r_arr,theta_arr,C.T)
xlabel(r'r')
ylabel(r'theta')
plt.show()

I only get this rectangle picture:

enter image description here

how can I turn it into a 'pie-chart-style' picture?

like image 459
sam Avatar asked Aug 31 '25 21:08

sam


2 Answers

So your code is nearly there but there are three things missing:

  1. You need to use a 'polar' projection. This tells pyplot that you are using polar co-ordinates, so it will create a circular plot like in the image you have linked.
  2. Your theta array needs to be in radians, not degrees.
  3. Your arrays containing values for r and theta need to be 2D, not 1D.

I have created a working version of your code and included it below:

    import matplotlib.pyplot as plt
    import numpy as np

    # number of bins in r and theta dimensions
    N_bins_theta = 36
    N_bins_r = 10

    # limits in r dimension
    rmin = 6
    rmax = 12

    # setting up 1D arrays in r and theta
    r = np.linspace(rmin, rmax, N_bins_r)
    theta = np.linspace(0, 2*np.pi, N_bins_theta)  # N.B. radians not degrees

    # 'gridding' the 1D arrays into 2D arrays so they can be used by pcolor
    theta, r = np.meshgrid(theta, r)

    # generating random data; note shape of array
    C = np.random.rand(N_bins_r, N_bins_theta)

    # setting up 'polar' projection and plotting
    ax = plt.subplot(111, projection='polar')
    plt.pcolor(theta, r, C)
    plt.show()

Here is the image output:

A working polar plot

like image 87
Aniche Avatar answered Sep 03 '25 11:09

Aniche


Unsatisfied with the aesthetics of the projection='polar' solution, I wrote another one. It utilizes a custom routine to draw annular sectors.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

COLORMAP = 'jet'        # choose colors here

def polar_annular_sector(r1, r2, theta1, theta2, **kargs):
    # draw annular sector in polar coordinates
    theta = np.arange(theta1, theta2+1, 1)/180.*np.pi
    cr1 = np.full_like(theta, r1)
    cr2 = np.full_like(theta, r2)
    plt.fill_between(theta, cr1, cr2, **kargs)

r_min=0
r_max=40
r_step = 5
r_arr = np.linspace(r_min,r_max-r_step,(r_max-r_min)/r_step)

theta_step = 15
theta_arr = np.linspace(0,360-theta_step,360/theta_step)

# generate random data
C = np.random.rand(len(r_arr), len(theta_arr))

# load colormap
space = np.linspace(0.0, 1.0, 100)
rgb = cm.get_cmap(COLORMAP)(space)[np.newaxis, :, :3]

# draw custom (slow) polar mesh profile
plt.polar()
for ri, r in enumerate(r_arr):
    print (ri, r)
    for ti, th in enumerate(theta_arr):
        color = rgb[0, int(C[ri, ti]*len(space))]
        polar_annular_sector(r, r+r_step, th, th+theta_step, color=color)
plt.show()

Sample result:

Color mesh in a circle

Another one (12 by 36):

Color mesh in a doughnut

like image 27
Andriy Makukha Avatar answered Sep 03 '25 09:09

Andriy Makukha