{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Figure subfigures\n\nSometimes it is desirable to have a figure with two different layouts in it.\nThis can be achieved with\n:doc:`nested gridspecs`,\nbut having a virtual figure with its own artists is helpful, so\nMatplotlib also has \"subfigures\", accessed by calling\n`matplotlib.figure.Figure.add_subfigure` in a way that is analogous to\n`matplotlib.figure.Figure.add_subplot`, or\n`matplotlib.figure.Figure.subfigures` to make an array of subfigures. Note\nthat subfigures can also have their own child subfigures.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef example_plot(ax, fontsize=12, hide_labels=False):\n pc = ax.pcolormesh(np.random.randn(30, 30), vmin=-2.5, vmax=2.5)\n if not hide_labels:\n ax.set_xlabel('x-label', fontsize=fontsize)\n ax.set_ylabel('y-label', fontsize=fontsize)\n ax.set_title('Title', fontsize=fontsize)\n return pc\n\nnp.random.seed(19680808)\n# gridspec inside gridspec\nfig = plt.figure(layout='constrained', figsize=(10, 4))\nsubfigs = fig.subfigures(1, 2, wspace=0.07)\n\naxsLeft = subfigs[0].subplots(1, 2, sharey=True)\nsubfigs[0].set_facecolor('0.75')\nfor ax in axsLeft:\n pc = example_plot(ax)\nsubfigs[0].suptitle('Left plots', fontsize='x-large')\nsubfigs[0].colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')\n\naxsRight = subfigs[1].subplots(3, 1, sharex=True)\nfor nn, ax in enumerate(axsRight):\n pc = example_plot(ax, hide_labels=True)\n if nn == 2:\n ax.set_xlabel('xlabel')\n if nn == 1:\n ax.set_ylabel('ylabel')\n\nsubfigs[1].set_facecolor('0.85')\nsubfigs[1].colorbar(pc, shrink=0.6, ax=axsRight)\nsubfigs[1].suptitle('Right plots', fontsize='x-large')\n\nfig.suptitle('Figure suptitle', fontsize='xx-large')\n\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to mix subplots and subfigures using\n`matplotlib.figure.Figure.add_subfigure`. This requires getting\nthe gridspec that the subplots are laid out on.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(2, 3, layout='constrained', figsize=(10, 4))\ngridspec = axs[0, 0].get_subplotspec().get_gridspec()\n\n# clear the left column for the subfigure:\nfor a in axs[:, 0]:\n a.remove()\n\n# plot data in remaining Axes:\nfor a in axs[:, 1:].flat:\n a.plot(np.arange(10))\n\n# make the subfigure in the empty gridspec slots:\nsubfig = fig.add_subfigure(gridspec[:, 0])\n\naxsLeft = subfig.subplots(1, 2, sharey=True)\nsubfig.set_facecolor('0.75')\nfor ax in axsLeft:\n pc = example_plot(ax)\nsubfig.suptitle('Left plots', fontsize='x-large')\nsubfig.colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')\n\nfig.suptitle('Figure suptitle', fontsize='xx-large')\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Subfigures can have different widths and heights. This is exactly the\nsame example as the first example, but *width_ratios* has been changed:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig = plt.figure(layout='constrained', figsize=(10, 4))\nsubfigs = fig.subfigures(1, 2, wspace=0.07, width_ratios=[2, 1])\n\naxsLeft = subfigs[0].subplots(1, 2, sharey=True)\nsubfigs[0].set_facecolor('0.75')\nfor ax in axsLeft:\n pc = example_plot(ax)\nsubfigs[0].suptitle('Left plots', fontsize='x-large')\nsubfigs[0].colorbar(pc, shrink=0.6, ax=axsLeft, location='bottom')\n\naxsRight = subfigs[1].subplots(3, 1, sharex=True)\nfor nn, ax in enumerate(axsRight):\n pc = example_plot(ax, hide_labels=True)\n if nn == 2:\n ax.set_xlabel('xlabel')\n if nn == 1:\n ax.set_ylabel('ylabel')\n\nsubfigs[1].set_facecolor('0.85')\nsubfigs[1].colorbar(pc, shrink=0.6, ax=axsRight)\nsubfigs[1].suptitle('Right plots', fontsize='x-large')\n\nfig.suptitle('Figure suptitle', fontsize='xx-large')\n\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Subfigures can be also be nested:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig = plt.figure(layout='constrained', figsize=(10, 8))\n\nfig.suptitle('fig')\n\nsubfigs = fig.subfigures(1, 2, wspace=0.07)\n\nsubfigs[0].set_facecolor('coral')\nsubfigs[0].suptitle('subfigs[0]')\n\nsubfigs[1].set_facecolor('coral')\nsubfigs[1].suptitle('subfigs[1]')\n\nsubfigsnest = subfigs[0].subfigures(2, 1, height_ratios=[1, 1.4])\nsubfigsnest[0].suptitle('subfigsnest[0]')\nsubfigsnest[0].set_facecolor('r')\naxsnest0 = subfigsnest[0].subplots(1, 2, sharey=True)\nfor nn, ax in enumerate(axsnest0):\n pc = example_plot(ax, hide_labels=True)\nsubfigsnest[0].colorbar(pc, ax=axsnest0)\n\nsubfigsnest[1].suptitle('subfigsnest[1]')\nsubfigsnest[1].set_facecolor('g')\naxsnest1 = subfigsnest[1].subplots(3, 1, sharex=True)\n\naxsRight = subfigs[1].subplots(2, 2)\n\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. tags::\n\n component: figure\n plot-type: pcolormesh\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.13.2" } }, "nbformat": 4, "nbformat_minor": 0 }