Matplotlib Custom Units

PythonPythonBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

Matplotlib is a plotting library for the Python programming language. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits like Tkinter, wxPython, Qt, or GTK. Matplotlib allows developers to create a wide range of static, animated, and interactive visualizations in Python.

In this lab, we will learn how to create custom units in Matplotlib and plot data using these custom units.

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.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("`Python`")) -.-> python/BasicConceptsGroup(["`Basic Concepts`"]) matplotlib(("`Matplotlib`")) -.-> matplotlib/BasicConceptsGroup(["`Basic Concepts`"]) matplotlib(("`Matplotlib`")) -.-> matplotlib/PlottingDataGroup(["`Plotting Data`"]) matplotlib(("`Matplotlib`")) -.-> matplotlib/PlotCustomizationGroup(["`Plot Customization`"]) python(("`Python`")) -.-> python/ControlFlowGroup(["`Control Flow`"]) python(("`Python`")) -.-> python/DataStructuresGroup(["`Data Structures`"]) python(("`Python`")) -.-> python/FunctionsGroup(["`Functions`"]) python(("`Python`")) -.-> python/ModulesandPackagesGroup(["`Modules and Packages`"]) python(("`Python`")) -.-> python/ObjectOrientedProgrammingGroup(["`Object-Oriented Programming`"]) python(("`Python`")) -.-> python/DataScienceandMachineLearningGroup(["`Data Science and Machine Learning`"]) python/BasicConceptsGroup -.-> python/comments("`Comments`") matplotlib/BasicConceptsGroup -.-> matplotlib/importing_matplotlib("`Importing Matplotlib`") matplotlib/BasicConceptsGroup -.-> matplotlib/figures_axes("`Understanding Figures and Axes`") matplotlib/PlottingDataGroup -.-> matplotlib/line_plots("`Line Plots`") matplotlib/PlotCustomizationGroup -.-> matplotlib/line_styles_colors("`Customizing Line Styles and Colors`") python/ControlFlowGroup -.-> python/conditional_statements("`Conditional Statements`") python/ControlFlowGroup -.-> python/for_loops("`For Loops`") python/ControlFlowGroup -.-> python/list_comprehensions("`List Comprehensions`") python/DataStructuresGroup -.-> python/lists("`Lists`") python/DataStructuresGroup -.-> python/tuples("`Tuples`") python/FunctionsGroup -.-> python/function_definition("`Function Definition`") python/FunctionsGroup -.-> python/default_arguments("`Default Arguments`") python/ModulesandPackagesGroup -.-> python/importing_modules("`Importing Modules`") python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("`Classes and Objects`") python/ObjectOrientedProgrammingGroup -.-> python/constructor("`Constructor`") python/ObjectOrientedProgrammingGroup -.-> python/polymorphism("`Polymorphism`") python/ObjectOrientedProgrammingGroup -.-> python/encapsulation("`Encapsulation`") python/DataScienceandMachineLearningGroup -.-> python/numerical_computing("`Numerical Computing`") python/DataScienceandMachineLearningGroup -.-> python/data_visualization("`Data Visualization`") python/FunctionsGroup -.-> python/build_in_functions("`Build-in Functions`") subgraph Lab Skills python/comments -.-> lab-48719{{"`Matplotlib Custom Units`"}} matplotlib/importing_matplotlib -.-> lab-48719{{"`Matplotlib Custom Units`"}} matplotlib/figures_axes -.-> lab-48719{{"`Matplotlib Custom Units`"}} matplotlib/line_plots -.-> lab-48719{{"`Matplotlib Custom Units`"}} matplotlib/line_styles_colors -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/conditional_statements -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/for_loops -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/list_comprehensions -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/lists -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/tuples -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/function_definition -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/default_arguments -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/importing_modules -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/classes_objects -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/constructor -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/polymorphism -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/encapsulation -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/numerical_computing -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/data_visualization -.-> lab-48719{{"`Matplotlib Custom Units`"}} python/build_in_functions -.-> lab-48719{{"`Matplotlib Custom Units`"}} end

Import Libraries

In the first step, we need to import the required libraries - matplotlib.pyplot, numpy, matplotlib.ticker, and matplotlib.units.

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.units as units

Create a Custom Unit Class

In this step, we will create a custom unit class - Foo. This class will support conversion and different tick formatting depending on the "unit". Here, the "unit" is just a scalar conversion factor.

class Foo:
    def __init__(self, val, unit=1.0):
        self.unit = unit
        self._val = val * unit

    def value(self, unit):
        if unit is None:
            unit = self.unit
        return self._val / unit

Create a Converter Class

In this step, we will create a converter class - FooConverter. This class will define three static methods - axisinfo, convert, and default_units.

class FooConverter(units.ConversionInterface):
    @staticmethod
    def axisinfo(unit, axis):
        """Return the Foo AxisInfo."""
        if unit == 1.0 or unit == 2.0:
            return units.AxisInfo(
                majloc=ticker.IndexLocator(8, 0),
                majfmt=ticker.FormatStrFormatter("VAL: %s"),
                label='foo',
                )

        else:
            return None

    @staticmethod
    def convert(obj, unit, axis):
        """
        Convert *obj* using *unit*.

        If *obj* is a sequence, return the converted sequence.
        """
        if np.iterable(obj):
            return [o.value(unit) for o in obj]
        else:
            return obj.value(unit)

    @staticmethod
    def default_units(x, axis):
        """Return the default unit for *x* or None."""
        if np.iterable(x):
            for thisx in x:
                return thisx.unit
        else:
            return x.unit

Register the Custom Unit Class

In this step, we will register the custom unit class - Foo - with the converter class - FooConverter.

units.registry[Foo] = FooConverter()

Create Data Points

In this step, we will create some data points using the custom unit class - Foo.

## create some Foos
x = [Foo(val, 1.0) for val in range(0, 50, 2)]
## and some arbitrary y data
y = [i for i in range(len(x))]

Create Plots

In this step, we will create two plots - one using custom units and the other using default units.

fig, (ax1, ax2) = plt.subplots(1, 2)
fig.suptitle("Custom units")
fig.subplots_adjust(bottom=0.2)

## plot specifying units
ax2.plot(x, y, 'o', xunits=2.0)
ax2.set_title("xunits = 2.0")
plt.setp(ax2.get_xticklabels(), rotation=30, ha='right')

## plot without specifying units; will use the None branch for axisinfo
ax1.plot(x, y)  ## uses default units
ax1.set_title('default units')
plt.setp(ax1.get_xticklabels(), rotation=30, ha='right')

plt.show()

Run the Code

In the final step, run the code to create the custom unit plots.

Summary

In this lab, we learned how to create custom units in Matplotlib using a custom unit class and a converter class. We then created two plots - one using custom units and the other using default units - to demonstrate the usage of these custom units. Custom units can be useful when dealing with complex data that requires custom scaling or tick formatting.

Other Python Tutorials you may like