{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Create a colormap from a list of colors\n\nFor more detail on creating and manipulating colormaps see\n`colormap-manipulation`.\n\nCreating a `colormap <colormaps>` from a list of colors\ncan be done with the `.LinearSegmentedColormap.from_list` method.  You must\npass a list of RGB tuples that define the mixture of colors from 0 to 1.\n\n\n## Creating custom colormaps\nIt is also possible to create a custom mapping for a colormap. This is\naccomplished by creating dictionary that specifies how the RGB channels\nchange from one end of the cmap to the other.\n\nExample: suppose you want red to increase from 0 to 1 over the bottom\nhalf, green to do the same over the middle half, and blue over the top\nhalf.  Then you would use::\n\n    cdict = {\n        'red': (\n            (0.0,  0.0, 0.0),\n            (0.5,  1.0, 1.0),\n            (1.0,  1.0, 1.0),\n        ),\n        'green': (\n            (0.0,  0.0, 0.0),\n            (0.25, 0.0, 0.0),\n            (0.75, 1.0, 1.0),\n            (1.0,  1.0, 1.0),\n        ),\n        'blue': (\n            (0.0,  0.0, 0.0),\n            (0.5,  0.0, 0.0),\n            (1.0,  1.0, 1.0),\n        )\n    }\n\nIf, as in this example, there are no discontinuities in the r, g, and b\ncomponents, then it is quite simple: the second and third element of\neach tuple, above, is the same -- call it \"``y``\".  The first element (\"``x``\")\ndefines interpolation intervals over the full range of 0 to 1, and it\nmust span that whole range.  In other words, the values of ``x`` divide the\n0-to-1 range into a set of segments, and ``y`` gives the end-point color\nvalues for each segment.\n\nNow consider the green, ``cdict['green']`` is saying that for:\n\n- 0 <= ``x`` <= 0.25, ``y`` is zero; no green.\n- 0.25 < ``x`` <= 0.75, ``y`` varies linearly from 0 to 1.\n- 0.75 < ``x`` <= 1, ``y`` remains at 1, full green.\n\nIf there are discontinuities, then it is a little more complicated. Label the 3\nelements in each row in the ``cdict`` entry for a given color as ``(x, y0,\ny1)``. Then for values of ``x`` between ``x[i]`` and ``x[i+1]`` the color value\nis interpolated between ``y1[i]`` and ``y0[i+1]``.\n\nGoing back to a cookbook example::\n\n    cdict = {\n        'red': (\n            (0.0,  0.0, 0.0),\n            (0.5,  1.0, 0.7),\n            (1.0,  1.0, 1.0),\n        ),\n        'green': (\n            (0.0,  0.0, 0.0),\n            (0.5,  1.0, 0.0),\n            (1.0,  1.0, 1.0),\n        ),\n        'blue': (\n            (0.0,  0.0, 0.0),\n            (0.5,  0.0, 0.0),\n            (1.0,  1.0, 1.0),\n        )\n    }\n\nand look at ``cdict['red'][1]``; because ``y0 != y1``, it is saying that for\n``x`` from 0 to 0.5, red increases from 0 to 1, but then it jumps down, so that\nfor ``x`` from 0.5 to 1, red increases from 0.7 to 1.  Green ramps from 0 to 1\nas ``x`` goes from 0 to 0.5, then jumps back to 0, and ramps back to 1 as ``x``\ngoes from 0.5 to 1. ::\n\n  row i:   x  y0  y1\n                 /\n                /\n  row i+1: x  y0  y1\n\nAbove is an attempt to show that for ``x`` in the range ``x[i]`` to ``x[i+1]``,\nthe interpolation is between ``y1[i]`` and ``y0[i+1]``.  So, ``y0[0]`` and\n``y1[-1]`` are never used.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nimport matplotlib as mpl\nfrom matplotlib.colors import LinearSegmentedColormap\n\n# Make some illustrative fake data:\n\nx = np.arange(0, np.pi, 0.1)\ny = np.arange(0, 2 * np.pi, 0.1)\nX, Y = np.meshgrid(x, y)\nZ = np.cos(X) * np.sin(Y) * 10"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Colormaps from a list\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)]  # R -> G -> B\nn_bins = [3, 6, 10, 100]  # Discretizes the interpolation into bins\ncmap_name = 'my_list'\nfig, axs = plt.subplots(2, 2, figsize=(6, 9))\nfig.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05)\nfor n_bin, ax in zip(n_bins, axs.flat):\n    # Create the colormap\n    cmap = LinearSegmentedColormap.from_list(cmap_name, colors, N=n_bin)\n    # Fewer bins will result in \"coarser\" colomap interpolation\n    im = ax.imshow(Z, origin='lower', cmap=cmap)\n    ax.set_title(\"N bins: %s\" % n_bin)\n    fig.colorbar(im, ax=ax)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Custom colormaps\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cdict1 = {\n    'red': (\n        (0.0, 0.0, 0.0),\n        (0.5, 0.0, 0.1),\n        (1.0, 1.0, 1.0),\n    ),\n    'green': (\n        (0.0, 0.0, 0.0),\n        (1.0, 0.0, 0.0),\n    ),\n    'blue': (\n        (0.0, 0.0, 1.0),\n        (0.5, 0.1, 0.0),\n        (1.0, 0.0, 0.0),\n    )\n}\n\ncdict2 = {\n    'red': (\n        (0.0, 0.0, 0.0),\n        (0.5, 0.0, 1.0),\n        (1.0, 0.1, 1.0),\n    ),\n    'green': (\n        (0.0, 0.0, 0.0),\n        (1.0, 0.0, 0.0),\n    ),\n    'blue': (\n        (0.0, 0.0, 0.1),\n        (0.5, 1.0, 0.0),\n        (1.0, 0.0, 0.0),\n    )\n}\n\ncdict3 = {\n    'red': (\n        (0.0, 0.0, 0.0),\n        (0.25, 0.0, 0.0),\n        (0.5, 0.8, 1.0),\n        (0.75, 1.0, 1.0),\n        (1.0, 0.4, 1.0),\n    ),\n    'green': (\n        (0.0, 0.0, 0.0),\n        (0.25, 0.0, 0.0),\n        (0.5, 0.9, 0.9),\n        (0.75, 0.0, 0.0),\n        (1.0, 0.0, 0.0),\n    ),\n    'blue': (\n        (0.0, 0.0, 0.4),\n        (0.25, 1.0, 1.0),\n        (0.5, 1.0, 0.8),\n        (0.75, 0.0, 0.0),\n        (1.0, 0.0, 0.0),\n    )\n}\n\n# Make a modified version of cdict3 with some transparency\n# in the middle of the range.\ncdict4 = {\n    **cdict3,\n    'alpha': (\n        (0.0, 1.0, 1.0),\n        # (0.25, 1.0, 1.0),\n        (0.5, 0.3, 0.3),\n        # (0.75, 1.0, 1.0),\n        (1.0, 1.0, 1.0),\n    ),\n}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now we will use this example to illustrate 2 ways of\nhandling custom colormaps.\nFirst, the most direct and explicit:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "blue_red1 = LinearSegmentedColormap('BlueRed1', cdict1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Second, create the map explicitly and register it.\nLike the first method, this method works with any kind\nof Colormap, not just\na LinearSegmentedColormap:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mpl.colormaps.register(LinearSegmentedColormap('BlueRed2', cdict2))\nmpl.colormaps.register(LinearSegmentedColormap('BlueRed3', cdict3))\nmpl.colormaps.register(LinearSegmentedColormap('BlueRedAlpha', cdict4))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Make the figure, with 4 subplots:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig, axs = plt.subplots(2, 2, figsize=(6, 9))\nfig.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05)\n\nim1 = axs[0, 0].imshow(Z, cmap=blue_red1)\nfig.colorbar(im1, ax=axs[0, 0])\n\nim2 = axs[1, 0].imshow(Z, cmap='BlueRed2')\nfig.colorbar(im2, ax=axs[1, 0])\n\n# Now we will set the third cmap as the default.  One would\n# not normally do this in the middle of a script like this;\n# it is done here just to illustrate the method.\n\nplt.rcParams['image.cmap'] = 'BlueRed3'\n\nim3 = axs[0, 1].imshow(Z)\nfig.colorbar(im3, ax=axs[0, 1])\naxs[0, 1].set_title(\"Alpha = 1\")\n\n# Or as yet another variation, we can replace the rcParams\n# specification *before* the imshow with the following *after*\n# imshow.\n# This sets the new default *and* sets the colormap of the last\n# image-like item plotted via pyplot, if any.\n#\n\n# Draw a line with low zorder so it will be behind the image.\naxs[1, 1].plot([0, 10 * np.pi], [0, 20 * np.pi], color='c', lw=20, zorder=-1)\n\nim4 = axs[1, 1].imshow(Z)\nfig.colorbar(im4, ax=axs[1, 1])\n\n# Here it is: changing the colormap for the current image and its\n# colorbar after they have been plotted.\nim4.set_cmap('BlueRedAlpha')\naxs[1, 1].set_title(\"Varying alpha\")\n\nfig.suptitle('Custom Blue-Red colormaps', fontsize=16)\nfig.subplots_adjust(top=0.9)\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. admonition:: References\n\n   The use of the following functions, methods, classes and modules is shown\n   in this example:\n\n   - `matplotlib.axes.Axes.imshow` / `matplotlib.pyplot.imshow`\n   - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`\n   - `matplotlib.colors`\n   - `matplotlib.colors.LinearSegmentedColormap`\n   - `matplotlib.colors.LinearSegmentedColormap.from_list`\n   - `matplotlib.cm`\n   - `matplotlib.cm.ScalarMappable.set_cmap`\n   - `matplotlib.cm.ColormapRegistry.register`\n\n.. tags::\n\n   styling: colormap\n   plot-type: imshow\n   level: intermediate\n\n"
      ]
    }
  ],
  "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
}