{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Evans test\n\nA mockup \"Foo\" units class which supports conversion and different tick\nformatting depending on the \"unit\".  Here the \"unit\" is just a scalar\nconversion factor, but this example shows that Matplotlib is entirely agnostic\nto what kind of units client packages use.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nimport matplotlib.ticker as ticker\nimport matplotlib.units as units\n\n\nclass Foo:\n    def __init__(self, val, unit=1.0):\n        self.unit = unit\n        self._val = val * unit\n\n    def value(self, unit):\n        if unit is None:\n            unit = self.unit\n        return self._val / unit\n\n\nclass FooConverter(units.ConversionInterface):\n    @staticmethod\n    def axisinfo(unit, axis):\n        \"\"\"Return the Foo AxisInfo.\"\"\"\n        if unit == 1.0 or unit == 2.0:\n            return units.AxisInfo(\n                majloc=ticker.IndexLocator(8, 0),\n                majfmt=ticker.FormatStrFormatter(\"VAL: %s\"),\n                label='foo',\n                )\n\n        else:\n            return None\n\n    @staticmethod\n    def convert(obj, unit, axis):\n        \"\"\"\n        Convert *obj* using *unit*.\n\n        If *obj* is a sequence, return the converted sequence.\n        \"\"\"\n        if np.iterable(obj):\n            return [o.value(unit) for o in obj]\n        else:\n            return obj.value(unit)\n\n    @staticmethod\n    def default_units(x, axis):\n        \"\"\"Return the default unit for *x* or None.\"\"\"\n        if np.iterable(x):\n            for thisx in x:\n                return thisx.unit\n        else:\n            return x.unit\n\n\nunits.registry[Foo] = FooConverter()\n\n# create some Foos\nx = [Foo(val, 1.0) for val in range(0, 50, 2)]\n# and some arbitrary y data\ny = [i for i in range(len(x))]\n\nfig, (ax1, ax2) = plt.subplots(1, 2)\nfig.suptitle(\"Custom units\")\nfig.subplots_adjust(bottom=0.2)\n\n# plot specifying units\nax2.plot(x, y, 'o', xunits=2.0)\nax2.set_title(\"xunits = 2.0\")\nax2.tick_params(axis='x', rotation=30, rotation_mode='xtick')\n\n# plot without specifying units; will use the None branch for axisinfo\nax1.plot(x, y)  # uses default units\nax1.set_title('default units')\nax1.tick_params(axis='x', rotation=30, rotation_mode='xtick')\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.14.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}