Custom Grid and Polar Projection in Matplotlib

LabEx
4 min readSep 5, 2024

--

Cover

Introduction

MindMap

In this lab, we will learn how to use GridHelperCurveLinear to create custom grid and tick lines in Matplotlib. We will also learn how to create a polar projection in a rectangular box.

VM Tips

After the VM startup is done, click the top left corner to switch to the Notebook tab to access Jupyter Notebook for practice.

Sometimes, you may need to wait a few seconds for Jupyter Notebook to finish loading. The validation of operations cannot be automated because of limitations in Jupyter Notebook.

If you face issues during learning, feel free to ask Labby. Provide feedback after the session, and we will promptly resolve the problem for you.

Grid for Custom Transform

First, we will create a custom grid and tick lines using GridHelperCurveLinear. The custom transform will be applied to the grid and tick lines. The following code demonstrates this process:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
from mpl_toolkits.axisartist import Axes, HostAxes, angle_helper
from mpl_toolkits.axisartist.grid_helper_curvelinear import GridHelperCurveLinear

def curvelinear_test1(fig):
# Define custom transform
def tr(x, y):
return x, y - x
def inv_tr(x, y):
return x, y + x

# Create GridHelperCurveLinear object
grid_helper = GridHelperCurveLinear((tr, inv_tr))

# Create a subplot with the custom grid and tick lines
ax1 = fig.add_subplot(1, 2, 1, axes_class=Axes, grid_helper=grid_helper)

# Plot some points on the subplot
xx, yy = tr(np.array([3, 6]), np.array([5, 10]))
ax1.plot(xx, yy)

# Set the aspect ratio and limits of the subplot
ax1.set_aspect(1)
ax1.set_xlim(0, 10)
ax1.set_ylim(0, 10)

# Add floating axes and grid lines
ax1.axis["t"] = ax1.new_floating_axis(0, 3)
ax1.axis["t2"] = ax1.new_floating_axis(1, 7)
ax1.grid(True, zorder=0)

fig = plt.figure(figsize=(7, 4))
curvelinear_test1(fig)
plt.show()

Polar Projection in a Rectangular Box

Next, we will create a polar projection in a rectangular box using GridHelperCurveLinear. We will use an Affine2D transform to scale the degree coordinates to radians, and PolarAxes.PolarTransform to create the polar projection. We will also use angle_helper.ExtremeFinderCycle to find the extremes of the polar projection, and angle_helper.LocatorDMS and angle_helper.FormatterDMS to format the tick labels. The following code demonstrates this process:

def curvelinear_test2(fig):
# Define the custom transform
tr = Affine2D().scale(np.pi/180, 1) + PolarAxes.PolarTransform()

# Define the extreme finder, grid locator, and tick formatter
extreme_finder = angle_helper.ExtremeFinderCycle(
nx=20, ny=20,
lon_cycle=360, lat_cycle=None,
lon_minmax=None, lat_minmax=(0, np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
tick_formatter1 = angle_helper.FormatterDMS()

# Create GridHelperCurveLinear object
grid_helper = GridHelperCurveLinear(
tr, extreme_finder=extreme_finder,
grid_locator1=grid_locator1, tick_formatter1=tick_formatter1)
ax1 = fig.add_subplot(
1, 2, 2, axes_class=HostAxes, grid_helper=grid_helper)

# Make ticklabels of right and top axis visible
ax1.axis["right"].major_ticklabels.set_visible(True)
ax1.axis["top"].major_ticklabels.set_visible(True)

# Let right axis show ticklabels for 1st coordinate (angle)
ax1.axis["right"].get_helper().nth_coord_ticks = 0

# Let bottom axis show ticklabels for 2nd coordinate (radius)
ax1.axis["bottom"].get_helper().nth_coord_ticks = 1

# Set the aspect ratio and limits of the subplot
ax1.set_aspect(1)
ax1.set_xlim(-5, 12)
ax1.set_ylim(-5, 10)

# Add grid lines to the subplot
ax1.grid(True, zorder=0)

# Create a parasite axes with the given transform
ax2 = ax1.get_aux_axes(tr)

# Anything you draw in ax2 will match the ticks and grids of ax1.
ax2.plot(np.linspace(0, 30, 51), np.linspace(10, 10, 51), linewidth=2)

ax2.pcolor(np.linspace(0, 90, 4), np.linspace(0, 10, 4),
np.arange(9).reshape((3, 3)))
ax2.contour(np.linspace(0, 90, 4), np.linspace(0, 10, 4),
np.arange(16).reshape((4, 4)), colors="k")

fig = plt.figure(figsize=(7, 4))
curvelinear_test2(fig)
plt.show()

Final Code

The final code combines the code from Step 1 and Step 2:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
from mpl_toolkits.axisartist import Axes, HostAxes, angle_helper
from mpl_toolkits.axisartist.grid_helper_curvelinear import GridHelperCurveLinear

def curvelinear_test1(fig):
# Define custom transform
def tr(x, y):
return x, y - x
def inv_tr(x, y):
return x, y + x

# Create GridHelperCurveLinear object
grid_helper = GridHelperCurveLinear((tr, inv_tr))

# Create a subplot with the custom grid and tick lines
ax1 = fig.add_subplot(1, 2, 1, axes_class=Axes, grid_helper=grid_helper)

# Plot some points on the subplot
xx, yy = tr(np.array([3, 6]), np.array([5, 10]))
ax1.plot(xx, yy)

# Set the aspect ratio and limits of the subplot
ax1.set_aspect(1)
ax1.set_xlim(0, 10)
ax1.set_ylim(0, 10)

# Add floating axes and grid lines
ax1.axis["t"] = ax1.new_floating_axis(0, 3)
ax1.axis["t2"] = ax1.new_floating_axis(1, 7)
ax1.grid(True, zorder=0)

def curvelinear_test2(fig):
# Define the custom transform
tr = Affine2D().scale(np.pi/180, 1) + PolarAxes.PolarTransform()

# Define the extreme finder, grid locator, and tick formatter
extreme_finder = angle_helper.ExtremeFinderCycle(
nx=20, ny=20,
lon_cycle=360, lat_cycle=None,
lon_minmax=None, lat_minmax=(0, np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
tick_formatter1 = angle_helper.FormatterDMS()

# Create GridHelperCurveLinear object
grid_helper = GridHelperCurveLinear(
tr, extreme_finder=extreme_finder,
grid_locator1=grid_locator1, tick_formatter1=tick_formatter1)
ax1 = fig.add_subplot(
1, 2, 2, axes_class=HostAxes, grid_helper=grid_helper)

# Make ticklabels of right and top axis visible
ax1.axis["right"].major_ticklabels.set_visible(True)
ax1.axis["top"].major_ticklabels.set_visible(True)

# Let right axis show ticklabels for 1st coordinate (angle)
ax1.axis["right"].get_helper().nth_coord_ticks = 0

# Let bottom axis show ticklabels for 2nd coordinate (radius)
ax1.axis["bottom"].get_helper().nth_coord_ticks = 1

# Set the aspect ratio and limits of the subplot
ax1.set_aspect(1)
ax1.set_xlim(-5, 12)
ax1.set_ylim(-5, 10)

# Add grid lines to the subplot
ax1.grid(True, zorder=0)

# Create a parasite axes with the given transform
ax2 = ax1.get_aux_axes(tr)

# Anything you draw in ax2 will match the ticks and grids of ax1.
ax2.plot(np.linspace(0, 30, 51), np.linspace(10, 10, 51), linewidth=2)

ax2.pcolor(np.linspace(0, 90, 4), np.linspace(0, 10, 4),
np.arange(9).reshape((3, 3)))
ax2.contour(np.linspace(0, 90, 4), np.linspace(0, 10, 4),
np.arange(16).reshape((4, 4)), colors="k")

fig = plt.figure(figsize=(7, 4))
curvelinear_test1(fig)
curvelinear_test2(fig)
plt.show()

Summary

In this lab, we learned how to create custom grid and tick lines using GridHelperCurveLinear. We also learned how to create a polar projection in a rectangular box using Affine2D, PolarAxes.PolarTransform, and GridHelperCurveLinear.

🚀 Practice Now: Matplotlib Curvilinear Grid

Want to Learn More?

--

--

LabEx
LabEx

Written by LabEx

LabEx is an AI-assisted, hands-on learning platform for tech enthusiasts, covering Programming, Data Science, Linux and other areas.

No responses yet