Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complex polar plot in matplotlib

I would like to create a polar plot similar the following:

plot

I can't find an example of how to add two different functions over different ranges of angles. I don't need the radial offset in the middle, but might be nice. Any pointers, known examples would be super!

like image 534
tdodwell Avatar asked Mar 06 '20 11:03

tdodwell


People also ask

Can Python plot complex numbers?

Complex number in Python : An complex number is represented by “ x + yi “. Python converts the real numbers x and y into complex using the function complex(x,y). The real part can be accessed using the function real() and imaginary part can be represented by imag().


3 Answers

It appears to be just like other plotting with matplotlib, i.e. if you want to plot two curves, you call plt.polar multiple times.

Here is an example:

import numpy as np
import matplotlib.pyplot as plt

blue_thetas = np.linspace(np.pi/3, 2*np.pi/3, 100)
red_thetas = np.linspace(4*np.pi/3, 6*np.pi/3, 100)

blue_rs = np.random.uniform(4, 6, len(blue_thetas))
red_rs = np.random.uniform(3, 5, len(red_thetas))

red_curve = plt.polar(red_thetas, red_rs, c='r', label="calculated")
blue_curve = plt.polar(blue_thetas, blue_rs, c='b', label="measured")
plt.legend(loc=10)

plt.xticks(np.concatenate((red_thetas[::20], blue_thetas[::30])))

plt.title("test polar image")
plt.show()

source: https://matplotlib.org/3.1.1/gallery/misc/transoffset.html#sphx-glr-gallery-misc-transoffset-py

Another stackoverflow post that might be useful for you is this: floating radial axis

polar plot example

like image 68
Alek Westover Avatar answered Nov 14 '22 23:11

Alek Westover


figure

import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import resample

# Generate random example data
theta_calculated = np.linspace(np.deg2rad(240), np.deg2rad(360), 100)
theta_measured = np.linspace(np.deg2rad(60), np.deg2rad(150), 100)
r_calculated = resample(np.random.uniform(2.5, 3.5, 10), len(theta_calculated))
r_measured = resample(np.random.uniform(3.5, 5.5, 10), len(theta_measured))

# Plot curves
plt.polar(theta_calculated, r_calculated, color="red", label="calculated")
plt.polar(theta_measured, r_measured, color="blue", label="measured")

# Add legend
plt.legend(loc="center")

# Adjust ticks to data, taking different step sizes into account
plt.xticks([
    *np.arange(min(theta_measured), max(theta_measured) + np.deg2rad(1), np.deg2rad(30)),
    *np.arange(min(theta_calculated), max(theta_calculated) + np.deg2rad(1), np.deg2rad(15)),
])
plt.yticks(np.arange(2, 6 + 1))

plt.show()
like image 34
finefoot Avatar answered Nov 15 '22 01:11

finefoot


enter image description hereNeed some more minor tweaks -

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,
                               AutoMinorLocator)
#Define Angle Range
measured_thetas = np.linspace(np.pi/3, 5*np.pi/6, 10)
calculated_thetas = np.linspace(4*np.pi/3, 6*np.pi/3, 10)

#Genarate radial data 
measured_rs = np.random.uniform(3, 5, len(measured_thetas))
calculated_rs = np.random.uniform(2, 4, len(calculated_thetas))

ax = plt.subplot(111, projection='polar')
# offset Radial Axis works with Matplotlib > 2.2.3
ax.set_rorigin(0)
ax.set_ylim(2, 6)

# Plot series data and Legend
ax.plot(measured_thetas, measured_rs, c='b', label="Calculated")
ax.plot(calculated_thetas, calculated_rs, c='r', label="Measured")
ax.legend(loc="center",frameon=False,fontsize =  'x-small')

#Set Radial Axes labels
ax.set_rlabel_position(np.rad2deg((min(measured_thetas))))

# Set Radial Axis Titles
label_position=ax.get_rlabel_position()
ax.text(np.math.radians(label_position-10),(ax.get_rmax()+2)/2.,'Measured',
        rotation= 60,ha='center',va='center')
ax.text(np.math.radians(np.rad2deg((min(calculated_thetas)))-10),(ax.get_rmax()+2)/2.,"Calculated",
        rotation= 60,ha='center',va='center')

# Set Gridlines
ax.set_rticks([*np.arange(2,7,1)], minor=False)  # Less radial ticks

# Adjust ticks to data, taking different step sizes into account
ax.set_xticks([
    *np.arange(min(measured_thetas), max(measured_thetas) + np.deg2rad(1), np.deg2rad(30)),
    *np.arange(min(calculated_thetas), max(calculated_thetas) + np.deg2rad(1), np.deg2rad(15)),
], minor = False)

# Turn on the minor TICKS, which are required for the minor GRID
ax.minorticks_on()
# For the minor ticks, use no labels; default NullFormatter.
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
ax.yaxis.set_minor_locator(AutoMinorLocator(2))
# Customize the major grid
ax.grid(which='major', linestyle='-', linewidth='0.25', color='black')
# Customize the minor grid
ax.grid(which='minor', linestyle='--', linewidth='0.15', color='black')

 # to control how far the scale is from the plot (axes coordinates)
def add_scale(ax, X_OFF, Y_OFF):
    # add extra axes for the scale
    X_OFFSET = X_OFF
    Y_OFFSET = Y_OFF
    rect = ax.get_position()
    rect = (rect.xmin-X_OFFSET, rect.ymin+rect.height/2-Y_OFFSET, # x, y
            rect.width, rect.height/2) # width, height
    scale_ax = ax.figure.add_axes(rect)
   # if (X_OFFSET >= 0):
        # hide most elements of the new axes
    for loc in ['right', 'top', 'bottom']:
        scale_ax.spines[loc].set_visible(False)
#    else:
#        for loc in ['right', 'top', 'bottom']:
#            scale_ax.spines[loc].set_visible(False)
    scale_ax.tick_params(bottom=False, labelbottom=False)
    scale_ax.patch.set_visible(False) # hide white background
    # adjust the scale
    scale_ax.spines['left'].set_bounds(*ax.get_ylim())
    # scale_ax.spines['left'].set_bounds(0, ax.get_rmax()) # mpl < 2.2.3
    scale_ax.set_yticks(ax.get_yticks())
    scale_ax.set_ylim(ax.get_rorigin(), ax.get_rmax())
    # scale_ax.set_ylim(ax.get_ylim()) # Matplotlib < 2.2.3


#Dummy Chart to hide unused gridlines 
padding_degree = 5    
dummy_thetas1 = np.linspace(0 + np.deg2rad(padding_degree), min(measured_thetas) - np.deg2rad(padding_degree), 100)
dummy_thetas2 = np.linspace(max(measured_thetas)+ np.deg2rad(padding_degree), min(calculated_thetas)- np.deg2rad(padding_degree), 100)

#Genrate Values 
dummy_r =  np.ones(len(dummy_thetas1))*float(max(ax.get_ylim())+0.1)

ax.plot(dummy_thetas1, dummy_r, c='y',  alpha = 1 ,linewidth = 30, ls = 'solid')
ax.plot(dummy_thetas2, dummy_r, c='y',alpha = 1,linewidth = 30, ls = 'solid') 





add_scale(ax,0.1,0.5)
add_scale(ax,-0.6,0)

plt.show()
like image 29
lostin Avatar answered Nov 15 '22 00:11

lostin