Polar Plots

This Notebook demonstrates how to create polar plots in VCS

© The CDAT software was developed by LLNL. This tutorial was written by Charles Doutriaux. This work was performed under the auspices of the U.S. Department of Energy by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.

Download the Jupyter notebook

Prepare modules and function to visualize

Back To Top

In [1]:
import vcs
import vcsaddons
import numpy

# class to visualize canvas
import tempfile
import base64
class VCSAddonsNotebook(object):
    def __init__(self, x):
        self.x = x
    def _repr_png_(self):
        fnm = tempfile.mktemp()+".png"
        x.png(fnm)
        encoded = base64.b64encode(open(fnm, "rb").read())
        return encoded
    def __call__(self):
        return self
    
def show(canvas):
    return VCSAddonsNotebook(canvas)()

Prepare data and vcs objects

Back to Top

Here we define some dataset for later use in the notebook, feel free to set r to any of these to see the changes.

In [2]:
# Angles
nPoints = 75
theta0 = .001
e = numpy.exp(1.)
pi = numpy.pi
thetaN =  2.*pi
delta = (thetaN-theta0)/(nPoints-1)
theta = numpy.arange(theta0,thetaN,delta)

# Archimede's spiral
r_archimede = theta
# Rose Curves
nPetals = 6
r_rose = 4.*numpy.cos(nPetals*theta)
# simple
r_simple = 5. * numpy.sin(theta)
# Another simple one
r_simple_2 = 4. - 4.*numpy.cos(theta)
# Leaf
r_leaf = (1 + 0.9*numpy.cos(8*theta))*(1 + 0.1*numpy.cos(24*theta))*(0.9 + 0.05*numpy.cos(200*theta))*(1 +numpy.sin(theta))
# Love
r_love = 2*pi/numpy.sqrt(theta) + pi/4. -2.*numpy.sin(theta)+numpy.sin(theta)*numpy.sqrt(numpy.abs(numpy.cos(theta)))/(numpy.sin(theta)+1.4)

# set which curve to vizualize
r = r_archimede

# Initialize vcs canvas
x=vcs.init(bg=True, geometry=(600,600))

Basic (default) Plot

Let's plot this with a very basic plot.

Back To Top

In [3]:
# Create polar graphic method
polar = vcsaddons.createpolar()
# Associate vcs canvas with it
polar.x = x
# Plot
show(polar.plot(r,theta))
Out[3]:

Controlling the markers

Back To Top

In [4]:
polar.markersizes = [2.]
polar.markercolors = ["red"]
polar.markertypes = ["square"]
x.clear()
show(polar.plot(r,theta))
Out[4]:

Plotting Multiple Sets (groups) At Once

We can plot 3 different sets/groups at once, each with their own set of color/markers.

Back To Top

In [5]:
r2 = numpy.array([r,r_simple,r_simple_2])
polar.markercolors = ["red","green","blue"]
polar.markertypes = ["square","dot","diamond"]
polar.markersizes = [2.,5.,2.]
x.clear()
show(polar.plot(r2,theta))
Out[5]:

Clockwise Plots

Sometimes it can be useful to have $\theta$ rotating clockwise.

Back To Top

In [6]:
polar.markercolors = ["red"]
polar.markersizes= [1]
polar.markertypes = ["square"]
import EzTemplate
M = EzTemplate.Multi(columns=2,rows=1)
x.clear()
polar.plot(r,theta,template=M.get(row=0,column=0))
polar.clockwise = True
show(polar.plot(r,theta,template=M.get(row=0,column=1)))
Out[6]:

Connecting The Markers

We can also connect markers.

Back To Top

In [7]:
polar.clockwise = False
polar.linepriority=1
polar.linetypes=["dot"]
polar.linecolors = ["blue"]
polar.linewidths = [3.]
x.clear()
show(polar.plot(r,theta))
Out[7]:
In [8]:
polar.theta_tick_count = 3
x.clear()
show(polar.plot(r,theta))
Out[8]:

Controlling Magnitude (Radial) Labels/Ticks

We can control the value of the magnitude labels. Using vcs templates and text orientation objects we can control these labels angle.

Back To Top

In [9]:
ticks = {}
for a in range(45,361,45):
    ticks[float(a)/180.*numpy.pi] = r"$%i^o$" % a
polar.xticlabels1 = ticks
#polar.yticlabels1 = {1.:"one",3.:"three"}
polar.datawc_y1 = 0
polar.datawc_y2= 7
polar.yticlabels1 = {1.:"one",3.:"three",5:"five"}
polar.magnitude_tick_angle = pi/4.
#polar.yticlabels1 = None
x.clear()
to = vcs.createtextorientation()
to.angle = -45
tmpl = vcs.createtemplate()
tmpl.ylabel1.textorientation = to
show(polar.plot(r,theta, template=tmpl))
Out[9]:

Angular ($\theta$) Offset

Sometimes we need $\theta$ to start at some other values than 0 radians.

Back To Top

In [10]:
polar.theta_offset = pi/4.
to.angle = -90
x.clear()
show(polar.plot(r,theta, template=tmpl))
Out[10]:

Magnitude Sub ticks

We can add sub ticks on the magnitude (radial) circles Using vcs template and line objects we can control the appearance of these subticks.

Back To Top

In [11]:
# reset a few things
polar.theta_offset = 0.
polar.magnitude_tick_angle = 0
to.angle = 0

dot = vcs.createline()
dot.type="dot"
dot.color = ["grey"]
tmpl.ymintic1.line = dot
tmpl.ymintic1.priority = 1
polar.magnitude_mintics = [.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5]
x.clear()
show(polar.plot(r,theta, template=tmpl))
Out[11]:

Non Linear Magnitude (Radial) Scales

Sometimes it can be useful to have a non linear scale for the radius.

Back To Top

In [12]:
polar.magnitude_ticks = [1,1.1,2,7]
polar.datawc_y1 = 1.e20
polar.datawc_y2 = 1.e20
x.clear()
show(polar.plot(r,theta, template=tmpl))
Out[12]:

Using Amplitude To Control Markers Colors

It can be useful to link the markers color to the magnitude.

Back To Top

In [13]:
x.clear()
polar = vcsaddons.createpolar()
polar.x=x
polar.markercolors = [16, 66, 116, 143, 162, 181, 200, 219]
polar.markercolorsource = "magnitude"
tmpl = vcs.createtemplate()
tmpl.legend.x1=.9
tmpl.legend.x2=.99
tmpl.legend.y1 = .2
tmpl.legend.y2=.8
x.clear()
show(polar.plot(r,theta,template=tmpl))
Out[13]:

Using $\theta$ To Control Markers Colors

It can be useful to link the markers color to $\theta$.

Back To Top

In [14]:
x.clear()
polar = vcsaddons.createpolar()
polar.x=x
polar.markercolors = [16, 66, 116, 143, 162, 181, 200, 219]
polar.markercolorsource = "theta"
tmpl = vcs.createtemplate()
tmpl.legend.priority=0
x.clear()
show(polar.plot(r,theta,template=tmpl))
Out[14]: