{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Marker reference\n\nMatplotlib supports multiple categories of markers which are selected using\nthe ``marker`` parameter of plot commands:\n\n- `Unfilled markers`_\n- `Filled markers`_\n- `Markers created from TeX symbols`_\n- `Markers created from Paths`_\n\nFor a list of all markers see also the `matplotlib.markers` documentation.\n\nFor example usages see\n:doc:`/gallery/lines_bars_and_markers/scatter_star_poly`.\n\n.. redirect-from:: /gallery/shapes_and_collections/marker_path\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n\nfrom matplotlib.lines import Line2D\nfrom matplotlib.markers import MarkerStyle\nfrom matplotlib.transforms import Affine2D\n\ntext_style = dict(horizontalalignment='right', verticalalignment='center',\n fontsize=12, fontfamily='monospace')\nmarker_style = dict(linestyle=':', color='0.8', markersize=10,\n markerfacecolor=\"tab:blue\", markeredgecolor=\"tab:blue\")\n\n\ndef format_axes(ax):\n ax.margins(0.2)\n ax.set_axis_off()\n ax.invert_yaxis()\n\n\ndef split_list(a_list):\n i_half = len(a_list) // 2\n return a_list[:i_half], a_list[i_half:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Unfilled markers\nUnfilled markers are single-colored.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(ncols=2)\nfig.suptitle('Un-filled markers', fontsize=14)\n\n# Filter out filled markers and marker settings that do nothing.\nunfilled_markers = [m for m, func in Line2D.markers.items()\n if func != 'nothing' and m not in Line2D.filled_markers]\n\nfor ax, markers in zip(axs, split_list(unfilled_markers)):\n for y, marker in enumerate(markers):\n ax.text(-0.5, y, repr(marker), **text_style)\n ax.plot([y] * 3, marker=marker, **marker_style)\n format_axes(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Filled markers\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, axs = plt.subplots(ncols=2)\nfig.suptitle('Filled markers', fontsize=14)\nfor ax, markers in zip(axs, split_list(Line2D.filled_markers)):\n for y, marker in enumerate(markers):\n ax.text(-0.5, y, repr(marker), **text_style)\n ax.plot([y] * 3, marker=marker, **marker_style)\n format_axes(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n### Marker fill styles\nThe edge color and fill color of filled markers can be specified separately.\nAdditionally, the ``fillstyle`` can be configured to be unfilled, fully\nfilled, or half-filled in various directions. The half-filled styles use\n``markerfacecoloralt`` as secondary fill color.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, ax = plt.subplots()\nfig.suptitle('Marker fillstyle', fontsize=14)\nfig.subplots_adjust(left=0.4)\n\nfilled_marker_style = dict(marker='o', linestyle=':', markersize=15,\n color='darkgrey',\n markerfacecolor='tab:blue',\n markerfacecoloralt='lightsteelblue',\n markeredgecolor='brown')\n\nfor y, fill_style in enumerate(Line2D.fillStyles):\n ax.text(-0.5, y, repr(fill_style), **text_style)\n ax.plot([y] * 3, fillstyle=fill_style, **filled_marker_style)\nformat_axes(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Markers created from TeX symbols\n\nUse `MathText `, to use custom marker symbols,\nlike e.g. ``\"$\\u266B$\"``. For an overview over the STIX font symbols refer\nto the [STIX font table](http://www.stixfonts.org/allGlyphs.html).\nAlso see the :doc:`/gallery/text_labels_and_annotations/stix_fonts_demo`.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, ax = plt.subplots()\nfig.suptitle('Mathtext markers', fontsize=14)\nfig.subplots_adjust(left=0.4)\n\nmarker_style.update(markeredgecolor=\"none\", markersize=15)\nmarkers = [\"$1$\", r\"$\\frac{1}{2}$\", \"$f$\", \"$\\u266B$\", r\"$\\mathcal{A}$\"]\n\nfor y, marker in enumerate(markers):\n # Escape dollars so that the text is written \"as is\", not as mathtext.\n ax.text(-0.5, y, repr(marker).replace(\"$\", r\"\\$\"), **text_style)\n ax.plot([y] * 3, marker=marker, **marker_style)\nformat_axes(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Markers created from Paths\n\nAny `~.path.Path` can be used as a marker. The following example shows two\nsimple paths *star* and *circle*, and a more elaborate path of a circle with\na cut-out star.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nimport matplotlib.path as mpath\n\nstar = mpath.Path.unit_regular_star(6)\ncircle = mpath.Path.unit_circle()\n# concatenate the circle with an internal cutout of the star\ncut_star = mpath.Path(\n vertices=np.concatenate([circle.vertices, star.vertices[::-1, ...]]),\n codes=np.concatenate([circle.codes, star.codes]))\n\nfig, ax = plt.subplots()\nfig.suptitle('Path markers', fontsize=14)\nfig.subplots_adjust(left=0.4)\n\nmarkers = {'star': star, 'circle': circle, 'cut_star': cut_star}\n\nfor y, (name, marker) in enumerate(markers.items()):\n ax.text(-0.5, y, name, **text_style)\n ax.plot([y] * 3, marker=marker, **marker_style)\nformat_axes(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Advanced marker modifications with transform\n\nMarkers can be modified by passing a transform to the MarkerStyle\nconstructor. Following example shows how a supplied rotation is applied to\nseveral marker shapes.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "common_style = {k: v for k, v in filled_marker_style.items() if k != 'marker'}\nangles = [0, 10, 20, 30, 45, 60, 90]\n\nfig, ax = plt.subplots()\nfig.suptitle('Rotated markers', fontsize=14)\n\nax.text(-0.5, 0, 'Filled marker', **text_style)\nfor x, theta in enumerate(angles):\n t = Affine2D().rotate_deg(theta)\n ax.plot(x, 0, marker=MarkerStyle('o', 'left', t), **common_style)\n\nax.text(-0.5, 1, 'Un-filled marker', **text_style)\nfor x, theta in enumerate(angles):\n t = Affine2D().rotate_deg(theta)\n ax.plot(x, 1, marker=MarkerStyle('1', 'left', t), **common_style)\n\nax.text(-0.5, 2, 'Equation marker', **text_style)\nfor x, theta in enumerate(angles):\n t = Affine2D().rotate_deg(theta)\n eq = r'$\\frac{1}{x}$'\n ax.plot(x, 2, marker=MarkerStyle(eq, 'left', t), **common_style)\n\nfor x, theta in enumerate(angles):\n ax.text(x, 2.5, f\"{theta}\u00b0\", horizontalalignment=\"center\")\nformat_axes(ax)\n\nfig.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting marker cap style and join style\n\nMarkers have default cap and join styles, but these can be\ncustomized when creating a MarkerStyle.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from matplotlib.markers import CapStyle, JoinStyle\n\nmarker_inner = dict(markersize=35,\n markerfacecolor='tab:blue',\n markerfacecoloralt='lightsteelblue',\n markeredgecolor='brown',\n markeredgewidth=8,\n )\n\nmarker_outer = dict(markersize=35,\n markerfacecolor='tab:blue',\n markerfacecoloralt='lightsteelblue',\n markeredgecolor='white',\n markeredgewidth=1,\n )\n\nfig, ax = plt.subplots()\nfig.suptitle('Marker CapStyle', fontsize=14)\nfig.subplots_adjust(left=0.1)\n\nfor y, cap_style in enumerate(CapStyle):\n ax.text(-0.5, y, cap_style.name, **text_style)\n for x, theta in enumerate(angles):\n t = Affine2D().rotate_deg(theta)\n m = MarkerStyle('1', transform=t, capstyle=cap_style)\n ax.plot(x, y, marker=m, **marker_inner)\n ax.plot(x, y, marker=m, **marker_outer)\n ax.text(x, len(CapStyle) - .5, f'{theta}\u00b0', ha='center')\nformat_axes(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Modifying the join style:\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fig, ax = plt.subplots()\nfig.suptitle('Marker JoinStyle', fontsize=14)\nfig.subplots_adjust(left=0.05)\n\nfor y, join_style in enumerate(JoinStyle):\n ax.text(-0.5, y, join_style.name, **text_style)\n for x, theta in enumerate(angles):\n t = Affine2D().rotate_deg(theta)\n m = MarkerStyle('*', transform=t, joinstyle=join_style)\n ax.plot(x, y, marker=m, **marker_inner)\n ax.text(x, len(JoinStyle) - .5, f'{theta}\u00b0', ha='center')\nformat_axes(ax)\n\nplt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. tags::\n\n component: marker\n purpose: reference\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 }