diff --git a/galleries/examples/userdemo/annotate_explain.py b/galleries/examples/userdemo/annotate_explain.py deleted file mode 100644 index 8f20b5406bd7..000000000000 --- a/galleries/examples/userdemo/annotate_explain.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -================ -Annotate Explain -================ - -""" - -import matplotlib.pyplot as plt - -import matplotlib.patches as mpatches - -fig, axs = plt.subplots(2, 2) -x1, y1 = 0.3, 0.3 -x2, y2 = 0.7, 0.7 - -ax = axs.flat[0] -ax.plot([x1, x2], [y1, y2], ".") -el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2) -ax.add_artist(el) -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="-", - color="0.5", - patchB=None, - shrinkB=0, - connectionstyle="arc3,rad=0.3", - ), - ) -ax.text(.05, .95, "connect", transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[1] -ax.plot([x1, x2], [y1, y2], ".") -el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2) -ax.add_artist(el) -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="-", - color="0.5", - patchB=el, - shrinkB=0, - connectionstyle="arc3,rad=0.3", - ), - ) -ax.text(.05, .95, "clip", transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[2] -ax.plot([x1, x2], [y1, y2], ".") -el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2) -ax.add_artist(el) -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="-", - color="0.5", - patchB=el, - shrinkB=5, - connectionstyle="arc3,rad=0.3", - ), - ) -ax.text(.05, .95, "shrink", transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[3] -ax.plot([x1, x2], [y1, y2], ".") -el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2) -ax.add_artist(el) -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="fancy", - color="0.5", - patchB=el, - shrinkB=5, - connectionstyle="arc3,rad=0.3", - ), - ) -ax.text(.05, .95, "mutate", transform=ax.transAxes, ha="left", va="top") - -for ax in axs.flat: - ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1) - -plt.show() diff --git a/galleries/examples/userdemo/annotate_text_arrow.py b/galleries/examples/userdemo/annotate_text_arrow.py deleted file mode 100644 index 2495c7687bd7..000000000000 --- a/galleries/examples/userdemo/annotate_text_arrow.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -=================== -Annotate Text Arrow -=================== - -""" - -import matplotlib.pyplot as plt -import numpy as np - -# Fixing random state for reproducibility -np.random.seed(19680801) - -fig, ax = plt.subplots(figsize=(5, 5)) -ax.set_aspect(1) - -x1 = -1 + np.random.randn(100) -y1 = -1 + np.random.randn(100) -x2 = 1. + np.random.randn(100) -y2 = 1. + np.random.randn(100) - -ax.scatter(x1, y1, color="r") -ax.scatter(x2, y2, color="g") - -bbox_props = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9) -ax.text(-2, -2, "Sample A", ha="center", va="center", size=20, - bbox=bbox_props) -ax.text(2, 2, "Sample B", ha="center", va="center", size=20, - bbox=bbox_props) - - -bbox_props = dict(boxstyle="rarrow", fc=(0.8, 0.9, 0.9), ec="b", lw=2) -t = ax.text(0, 0, "Direction", ha="center", va="center", rotation=45, - size=15, - bbox=bbox_props) - -bb = t.get_bbox_patch() -bb.set_boxstyle("rarrow", pad=0.6) - -ax.set_xlim(-4, 4) -ax.set_ylim(-4, 4) - -plt.show() diff --git a/galleries/examples/userdemo/connectionstyle_demo.py b/galleries/examples/userdemo/connectionstyle_demo.py deleted file mode 100644 index e34c63a5708b..000000000000 --- a/galleries/examples/userdemo/connectionstyle_demo.py +++ /dev/null @@ -1,63 +0,0 @@ -""" -================================= -Connection styles for annotations -================================= - -When creating an annotation using `~.Axes.annotate`, the arrow shape can be -controlled via the *connectionstyle* parameter of *arrowprops*. For further -details see the description of `.FancyArrowPatch`. -""" - -import matplotlib.pyplot as plt - - -def demo_con_style(ax, connectionstyle): - x1, y1 = 0.3, 0.2 - x2, y2 = 0.8, 0.6 - - ax.plot([x1, x2], [y1, y2], ".") - ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="->", color="0.5", - shrinkA=5, shrinkB=5, - patchA=None, patchB=None, - connectionstyle=connectionstyle, - ), - ) - - ax.text(.05, .95, connectionstyle.replace(",", ",\n"), - transform=ax.transAxes, ha="left", va="top") - - -fig, axs = plt.subplots(3, 5, figsize=(7, 6.3), layout="constrained") -demo_con_style(axs[0, 0], "angle3,angleA=90,angleB=0") -demo_con_style(axs[1, 0], "angle3,angleA=0,angleB=90") -demo_con_style(axs[0, 1], "arc3,rad=0.") -demo_con_style(axs[1, 1], "arc3,rad=0.3") -demo_con_style(axs[2, 1], "arc3,rad=-0.3") -demo_con_style(axs[0, 2], "angle,angleA=-90,angleB=180,rad=0") -demo_con_style(axs[1, 2], "angle,angleA=-90,angleB=180,rad=5") -demo_con_style(axs[2, 2], "angle,angleA=-90,angleB=10,rad=5") -demo_con_style(axs[0, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=0") -demo_con_style(axs[1, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5") -demo_con_style(axs[2, 3], "arc,angleA=-90,angleB=0,armA=0,armB=40,rad=0") -demo_con_style(axs[0, 4], "bar,fraction=0.3") -demo_con_style(axs[1, 4], "bar,fraction=-0.3") -demo_con_style(axs[2, 4], "bar,angle=180,fraction=-0.2") - -for ax in axs.flat: - ax.set(xlim=(0, 1), ylim=(0, 1.25), xticks=[], yticks=[], aspect=1.25) -fig.get_layout_engine().set(wspace=0, hspace=0, w_pad=0, h_pad=0) - -plt.show() - -# %% -# -# .. admonition:: References -# -# The use of the following functions, methods, classes and modules is shown -# in this example: -# -# - `matplotlib.axes.Axes.annotate` -# - `matplotlib.patches.FancyArrowPatch` diff --git a/galleries/examples/userdemo/custom_boxstyle01.py b/galleries/examples/userdemo/custom_boxstyle01.py deleted file mode 100644 index 71668cc6cc31..000000000000 --- a/galleries/examples/userdemo/custom_boxstyle01.py +++ /dev/null @@ -1,128 +0,0 @@ -r""" -================= -Custom box styles -================= - -This example demonstrates the implementation of a custom `.BoxStyle`. -Custom `.ConnectionStyle`\s and `.ArrowStyle`\s can be similarly defined. -""" - -import matplotlib.pyplot as plt - -from matplotlib.patches import BoxStyle -from matplotlib.path import Path - -# %% -# Custom box styles can be implemented as a function that takes arguments -# specifying both a rectangular box and the amount of "mutation", and -# returns the "mutated" path. The specific signature is the one of -# ``custom_box_style`` below. -# -# Here, we return a new path which adds an "arrow" shape on the left of the -# box. -# -# The custom box style can then be used by passing -# ``bbox=dict(boxstyle=custom_box_style, ...)`` to `.Axes.text`. - - -def custom_box_style(x0, y0, width, height, mutation_size): - """ - Given the location and size of the box, return the path of the box around - it. - - Rotation is automatically taken care of. - - Parameters - ---------- - x0, y0, width, height : float - Box location and size. - mutation_size : float - Mutation reference scale, typically the text font size. - """ - # padding - mypad = 0.3 - pad = mutation_size * mypad - # width and height with padding added. - width = width + 2 * pad - height = height + 2 * pad - # boundary of the padded box - x0, y0 = x0 - pad, y0 - pad - x1, y1 = x0 + width, y0 + height - # return the new path - return Path([(x0, y0), - (x1, y0), (x1, y1), (x0, y1), - (x0-pad, (y0+y1)/2), (x0, y0), - (x0, y0)], - closed=True) - - -fig, ax = plt.subplots(figsize=(3, 3)) -ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30, - bbox=dict(boxstyle=custom_box_style, alpha=0.2)) - - -# %% -# Likewise, custom box styles can be implemented as classes that implement -# ``__call__``. -# -# The classes can then be registered into the ``BoxStyle._style_list`` dict, -# which allows specifying the box style as a string, -# ``bbox=dict(boxstyle="registered_name,param=value,...", ...)``. -# Note that this registration relies on internal APIs and is therefore not -# officially supported. - - -class MyStyle: - """A simple box.""" - - def __init__(self, pad=0.3): - """ - The arguments must be floats and have default values. - - Parameters - ---------- - pad : float - amount of padding - """ - self.pad = pad - super().__init__() - - def __call__(self, x0, y0, width, height, mutation_size): - """ - Given the location and size of the box, return the path of the box - around it. - - Rotation is automatically taken care of. - - Parameters - ---------- - x0, y0, width, height : float - Box location and size. - mutation_size : float - Reference scale for the mutation, typically the text font size. - """ - # padding - pad = mutation_size * self.pad - # width and height with padding added - width = width + 2.*pad - height = height + 2.*pad - # boundary of the padded box - x0, y0 = x0 - pad, y0 - pad - x1, y1 = x0 + width, y0 + height - # return the new path - return Path([(x0, y0), - (x1, y0), (x1, y1), (x0, y1), - (x0-pad, (y0+y1)/2.), (x0, y0), - (x0, y0)], - closed=True) - - -BoxStyle._style_list["angled"] = MyStyle # Register the custom style. - -fig, ax = plt.subplots(figsize=(3, 3)) -ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30, - bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2)) - -del BoxStyle._style_list["angled"] # Unregister it. - -plt.show() diff --git a/galleries/examples/userdemo/pgf_fonts.py b/galleries/examples/userdemo/pgf_fonts.py deleted file mode 100644 index 9d5f5594b81b..000000000000 --- a/galleries/examples/userdemo/pgf_fonts.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -========= -PGF fonts -========= -""" - -import matplotlib.pyplot as plt - -plt.rcParams.update({ - "font.family": "serif", - # Use LaTeX default serif font. - "font.serif": [], - # Use specific cursive fonts. - "font.cursive": ["Comic Neue", "Comic Sans MS"], -}) - -fig, ax = plt.subplots(figsize=(4.5, 2.5)) - -ax.plot(range(5)) - -ax.text(0.5, 3., "serif") -ax.text(0.5, 2., "monospace", family="monospace") -ax.text(2.5, 2., "sans-serif", family="DejaVu Sans") # Use specific sans font. -ax.text(2.5, 1., "comic", family="cursive") -ax.set_xlabel("µ is not $\\mu$") - -fig.tight_layout(pad=.5) - -fig.savefig("pgf_fonts.pdf") -fig.savefig("pgf_fonts.png") diff --git a/galleries/examples/userdemo/pgf_preamble_sgskip.py b/galleries/examples/userdemo/pgf_preamble_sgskip.py deleted file mode 100644 index b32fa972c31f..000000000000 --- a/galleries/examples/userdemo/pgf_preamble_sgskip.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -============ -PGF preamble -============ -""" - -import matplotlib as mpl - -mpl.use("pgf") -import matplotlib.pyplot as plt - -plt.rcParams.update({ - "font.family": "serif", # use serif/main font for text elements - "text.usetex": True, # use inline math for ticks - "pgf.rcfonts": False, # don't setup fonts from rc parameters - "pgf.preamble": "\n".join([ - r"\usepackage{url}", # load additional packages - r"\usepackage{unicode-math}", # unicode math setup - r"\setmainfont{DejaVu Serif}", # serif font via preamble - ]) -}) - -fig, ax = plt.subplots(figsize=(4.5, 2.5)) - -ax.plot(range(5)) - -ax.set_xlabel("unicode text: я, ψ, €, ü") -ax.set_ylabel(r"\url{https://matplotlib.org}") -ax.legend(["unicode math: $λ=∑_i^∞ μ_i^2$"]) - -fig.tight_layout(pad=.5) - -fig.savefig("pgf_preamble.pdf") -fig.savefig("pgf_preamble.png") diff --git a/galleries/examples/userdemo/pgf_texsystem.py b/galleries/examples/userdemo/pgf_texsystem.py deleted file mode 100644 index 0d8e326803ea..000000000000 --- a/galleries/examples/userdemo/pgf_texsystem.py +++ /dev/null @@ -1,30 +0,0 @@ -""" -============= -PGF texsystem -============= -""" - -import matplotlib.pyplot as plt - -plt.rcParams.update({ - "pgf.texsystem": "pdflatex", - "pgf.preamble": "\n".join([ - r"\usepackage[utf8x]{inputenc}", - r"\usepackage[T1]{fontenc}", - r"\usepackage{cmbright}", - ]), -}) - -fig, ax = plt.subplots(figsize=(4.5, 2.5)) - -ax.plot(range(5)) - -ax.text(0.5, 3., "serif", family="serif") -ax.text(0.5, 2., "monospace", family="monospace") -ax.text(2.5, 2., "sans-serif", family="sans-serif") -ax.set_xlabel(r"µ is not $\mu$") - -fig.tight_layout(pad=.5) - -fig.savefig("pgf_texsystem.pdf") -fig.savefig("pgf_texsystem.png") diff --git a/galleries/examples/userdemo/simple_annotate01.py b/galleries/examples/userdemo/simple_annotate01.py deleted file mode 100644 index cb3b6cb7e2c8..000000000000 --- a/galleries/examples/userdemo/simple_annotate01.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -================= -Simple Annotate01 -================= - -""" - -import matplotlib.pyplot as plt - -import matplotlib.patches as mpatches - -fig, axs = plt.subplots(2, 4) -x1, y1 = 0.3, 0.3 -x2, y2 = 0.7, 0.7 - -ax = axs.flat[0] -ax.plot([x1, x2], [y1, y2], "o") -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="->")) -ax.text(.05, .95, "A $->$ B", - transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[2] -ax.plot([x1, x2], [y1, y2], "o") -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.3", - shrinkB=5)) -ax.text(.05, .95, "shrinkB=5", - transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[3] -ax.plot([x1, x2], [y1, y2], "o") -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.3")) -ax.text(.05, .95, "connectionstyle=arc3", - transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[4] -ax.plot([x1, x2], [y1, y2], "o") -el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.5) -ax.add_artist(el) -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.2")) - -ax = axs.flat[5] -ax.plot([x1, x2], [y1, y2], "o") -el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.5) -ax.add_artist(el) -ax.annotate("", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.2", - patchB=el)) -ax.text(.05, .95, "patchB", - transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[6] -ax.plot([x1], [y1], "o") -ax.annotate("Test", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - ha="center", va="center", - bbox=dict(boxstyle="round", fc="w"), - arrowprops=dict(arrowstyle="->")) -ax.text(.05, .95, "annotate", - transform=ax.transAxes, ha="left", va="top") - -ax = axs.flat[7] -ax.plot([x1], [y1], "o") -ax.annotate("Test", - xy=(x1, y1), xycoords='data', - xytext=(x2, y2), textcoords='data', - ha="center", va="center", - bbox=dict(boxstyle="round", fc="w", ), - arrowprops=dict(arrowstyle="->", relpos=(0., 0.))) -ax.text(.05, .95, "relpos=(0, 0)", - transform=ax.transAxes, ha="left", va="top") - -for ax in axs.flat: - ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1) - -plt.show() diff --git a/galleries/users_explain/text/annotations.py b/galleries/users_explain/text/annotations.py index 89787c4a6336..5cfb16c12715 100644 --- a/galleries/users_explain/text/annotations.py +++ b/galleries/users_explain/text/annotations.py @@ -1,13 +1,16 @@ r""" +.. redirect-from:: /gallery/userdemo/anchored_box04 +.. redirect-from:: /gallery/userdemo/annotate_explain .. redirect-from:: /gallery/userdemo/annotate_simple01 .. redirect-from:: /gallery/userdemo/annotate_simple02 .. redirect-from:: /gallery/userdemo/annotate_simple03 .. redirect-from:: /gallery/userdemo/annotate_simple04 -.. redirect-from:: /gallery/userdemo/anchored_box04 .. redirect-from:: /gallery/userdemo/annotate_simple_coord01 .. redirect-from:: /gallery/userdemo/annotate_simple_coord02 .. redirect-from:: /gallery/userdemo/annotate_simple_coord03 +.. redirect-from:: /gallery/userdemo/annotate_text_arrow .. redirect-from:: /gallery/userdemo/connect_simple01 +.. redirect-from:: /gallery/userdemo/connectionstyle_demo .. redirect-from:: /tutorials/text/annotations .. _annotations: @@ -265,23 +268,30 @@ # Defining custom box styles # ^^^^^^^^^^^^^^^^^^^^^^^^^^ # -# You can use a custom box style. The value for the ``boxstyle`` can be a -# callable object in the following forms: +# Custom box styles can be implemented as a function that takes arguments specifying +# both a rectangular box and the amount of "mutation", and returns the "mutated" path. +# The specific signature is the one of ``custom_box_style`` below. +# +# Here, we return a new path which adds an "arrow" shape on the left of the box. +# +# The custom box style can then be used by passing +# ``bbox=dict(boxstyle=custom_box_style, ...)`` to `.Axes.text`. from matplotlib.path import Path def custom_box_style(x0, y0, width, height, mutation_size): """ - Given the location and size of the box, return the path of the box around - it. Rotation is automatically taken care of. + Given the location and size of the box, return the path of the box around it. + + Rotation is automatically taken care of. Parameters ---------- x0, y0, width, height : float Box location and size. mutation_size : float - Mutation reference scale, typically the text font size. + Mutation reference scale, typically the text font size. """ # padding mypad = 0.3 @@ -302,9 +312,71 @@ def custom_box_style(x0, y0, width, height, mutation_size): bbox=dict(boxstyle=custom_box_style, alpha=0.2)) # %% -# See also :doc:`/gallery/userdemo/custom_boxstyle01`. Similarly, you can define a -# custom `.ConnectionStyle` and a custom `.ArrowStyle`. View the source code at -# `.patches` to learn how each class is defined. +# Likewise, custom box styles can be implemented as classes that implement +# ``__call__``. +# +# The classes can then be registered into the ``BoxStyle._style_list`` dict, +# which allows specifying the box style as a string, +# ``bbox=dict(boxstyle="registered_name,param=value,...", ...)``. +# Note that this registration relies on internal APIs and is therefore not +# officially supported. + +from matplotlib.patches import BoxStyle + + +class MyStyle: + """A simple box.""" + + def __init__(self, pad=0.3): + """ + The arguments must be floats and have default values. + + Parameters + ---------- + pad : float + amount of padding + """ + self.pad = pad + super().__init__() + + def __call__(self, x0, y0, width, height, mutation_size): + """ + Given the location and size of the box, return the path of the box around it. + + Rotation is automatically taken care of. + + Parameters + ---------- + x0, y0, width, height : float + Box location and size. + mutation_size : float + Reference scale for the mutation, typically the text font size. + """ + # padding + pad = mutation_size * self.pad + # width and height with padding added + width = width + 2 * pad + height = height + 2 * pad + # boundary of the padded box + x0, y0 = x0 - pad, y0 - pad + x1, y1 = x0 + width, y0 + height + # return the new path + return Path([(x0, y0), (x1, y0), (x1, y1), (x0, y1), + (x0-pad, (y0+y1)/2), (x0, y0), (x0, y0)], + closed=True) + + +BoxStyle._style_list["angled"] = MyStyle # Register the custom style. + +fig, ax = plt.subplots(figsize=(3, 3)) +ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30, + bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2)) + +del BoxStyle._style_list["angled"] # Unregister it. + +# %% +# Similarly, you can define a custom `.ConnectionStyle` and a custom `.ArrowStyle`. View +# the source code at `.patches` to learn how each class is defined. # # .. _annotation_with_custom_arrow: # @@ -332,9 +404,40 @@ def custom_box_style(x0, y0, width, height, mutation_size): # 4. The path is transmuted to an arrow patch, as specified by the *arrowstyle* # parameter. # -# .. figure:: /gallery/userdemo/images/sphx_glr_annotate_explain_001.png -# :target: /gallery/userdemo/annotate_explain.html -# :align: center +# .. plot:: +# :show-source-link: False +# +# import matplotlib.patches as mpatches +# +# x1, y1 = 0.3, 0.3 +# x2, y2 = 0.7, 0.7 +# arrowprops = { +# "1. connect with connectionstyle": +# dict(arrowstyle="-", patchB=False, shrinkB=0), +# "2. clip against patchB": dict(arrowstyle="-", patchB=True, shrinkB=0), +# "3. shrink by shrinkB": dict(arrowstyle="-", patchB=True, shrinkB=5), +# "4. mutate with arrowstyle": dict(arrowstyle="fancy", patchB=True, shrinkB=5), +# } +# +# fig, axs = plt.subplots(2, 2, figsize=(6, 6), layout='compressed') +# for ax, (name, props) in zip(axs.flat, arrowprops.items()): +# ax.plot([x1, x2], [y1, y2], ".") +# +# el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2) +# ax.add_artist(el) +# +# props["patchB"] = el if props["patchB"] else None +# +# ax.annotate( +# "", +# xy=(x1, y1), xycoords='data', +# xytext=(x2, y2), textcoords='data', +# arrowprops={"color": "0.5", "connectionstyle": "arc3,rad=0.3", **props}) +# ax.text(.05, .95, name, transform=ax.transAxes, ha="left", va="top") +# +# ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1) +# +# fig.get_layout_engine().set(wspace=0, hspace=0, w_pad=0, h_pad=0) # # The creation of the connecting path between two points is controlled by # ``connectionstyle`` key and the following styles are available: @@ -358,9 +461,47 @@ def custom_box_style(x0, y0, width, height, mutation_size): # example below. (Warning: The behavior of the ``bar`` style is currently not # well-defined and may be changed in the future). # -# .. figure:: /gallery/userdemo/images/sphx_glr_connectionstyle_demo_001.png -# :target: /gallery/userdemo/connectionstyle_demo.html -# :align: center +# .. plot:: +# :caption: Connection styles for annotations +# +# def demo_con_style(ax, connectionstyle): +# x1, y1 = 0.3, 0.2 +# x2, y2 = 0.8, 0.6 +# +# ax.plot([x1, x2], [y1, y2], ".") +# ax.annotate("", +# xy=(x1, y1), xycoords='data', +# xytext=(x2, y2), textcoords='data', +# arrowprops=dict(arrowstyle="->", color="0.5", +# shrinkA=5, shrinkB=5, +# patchA=None, patchB=None, +# connectionstyle=connectionstyle, +# ), +# ) +# +# ax.text(.05, .95, connectionstyle.replace(",", ",\n"), +# transform=ax.transAxes, ha="left", va="top") +# +# ax.set(xlim=(0, 1), ylim=(0, 1.25), xticks=[], yticks=[], aspect=1.25) +# +# fig, axs = plt.subplots(3, 5, figsize=(7, 6.3), layout="compressed") +# demo_con_style(axs[0, 0], "angle3,angleA=90,angleB=0") +# demo_con_style(axs[1, 0], "angle3,angleA=0,angleB=90") +# demo_con_style(axs[0, 1], "arc3,rad=0.") +# demo_con_style(axs[1, 1], "arc3,rad=0.3") +# demo_con_style(axs[2, 1], "arc3,rad=-0.3") +# demo_con_style(axs[0, 2], "angle,angleA=-90,angleB=180,rad=0") +# demo_con_style(axs[1, 2], "angle,angleA=-90,angleB=180,rad=5") +# demo_con_style(axs[2, 2], "angle,angleA=-90,angleB=10,rad=5") +# demo_con_style(axs[0, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=0") +# demo_con_style(axs[1, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5") +# demo_con_style(axs[2, 3], "arc,angleA=-90,angleB=0,armA=0,armB=40,rad=0") +# demo_con_style(axs[0, 4], "bar,fraction=0.3") +# demo_con_style(axs[1, 4], "bar,fraction=-0.3") +# demo_con_style(axs[2, 4], "bar,angle=180,fraction=-0.2") +# +# axs[2, 0].remove() +# fig.get_layout_engine().set(wspace=0, hspace=0, w_pad=0, h_pad=0) # # The connecting path (after clipping and shrinking) is then mutated to # an arrow patch, according to the given ``arrowstyle``: diff --git a/galleries/users_explain/text/pgf.py b/galleries/users_explain/text/pgf.py index 8683101032b5..fd7693cf55e3 100644 --- a/galleries/users_explain/text/pgf.py +++ b/galleries/users_explain/text/pgf.py @@ -91,6 +91,8 @@ pdf.savefig(fig2) +.. redirect-from:: /gallery/userdemo/pgf_fonts + Font specification ================== @@ -107,9 +109,29 @@ When saving to ``.pgf``, the font configuration Matplotlib used for the layout of the figure is included in the header of the text file. -.. literalinclude:: /gallery/userdemo/pgf_fonts.py - :end-before: fig.savefig +.. code-block:: python + + import matplotlib.pyplot as plt + + plt.rcParams.update({ + "font.family": "serif", + # Use LaTeX default serif font. + "font.serif": [], + # Use specific cursive fonts. + "font.cursive": ["Comic Neue", "Comic Sans MS"], + }) + fig, ax = plt.subplots(figsize=(4.5, 2.5)) + + ax.plot(range(5)) + + ax.text(0.5, 3., "serif") + ax.text(0.5, 2., "monospace", family="monospace") + ax.text(2.5, 2., "sans-serif", family="DejaVu Sans") # Use specific sans font. + ax.text(2.5, 1., "comic", family="cursive") + ax.set_xlabel("µ is not $\\mu$") + +.. redirect-from:: /gallery/userdemo/pgf_preamble_sgskip .. _pgf-preamble: @@ -122,16 +144,33 @@ if you want to do the font configuration yourself instead of using the fonts specified in the rc parameters, make sure to disable :rc:`pgf.rcfonts`. -.. only:: html +.. code-block:: python - .. literalinclude:: /gallery/userdemo/pgf_preamble_sgskip.py - :end-before: fig.savefig + import matplotlib as mpl -.. only:: latex + mpl.use("pgf") + import matplotlib.pyplot as plt - .. literalinclude:: /gallery/userdemo/pgf_preamble_sgskip.py - :end-before: import matplotlib.pyplot as plt + plt.rcParams.update({ + "font.family": "serif", # use serif/main font for text elements + "text.usetex": True, # use inline math for ticks + "pgf.rcfonts": False, # don't setup fonts from rc parameters + "pgf.preamble": "\n".join([ + r"\usepackage{url}", # load additional packages + r"\usepackage{unicode-math}", # unicode math setup + r"\setmainfont{DejaVu Serif}", # serif font via preamble + ]) + }) + fig, ax = plt.subplots(figsize=(4.5, 2.5)) + + ax.plot(range(5)) + + ax.set_xlabel("unicode text: я, ψ, €, ü") + ax.set_ylabel(r"\url{https://matplotlib.org}") + ax.legend(["unicode math: $λ=∑_i^∞ μ_i^2$"]) + +.. redirect-from:: /gallery/userdemo/pgf_texsystem .. _pgf-texsystem: @@ -143,9 +182,27 @@ Please note that when selecting pdflatex, the fonts and Unicode handling must be configured in the preamble. -.. literalinclude:: /gallery/userdemo/pgf_texsystem.py - :end-before: fig.savefig +.. code-block:: python + + import matplotlib.pyplot as plt + + plt.rcParams.update({ + "pgf.texsystem": "pdflatex", + "pgf.preamble": "\n".join([ + r"\usepackage[utf8x]{inputenc}", + r"\usepackage[T1]{fontenc}", + r"\usepackage{cmbright}", + ]), + }) + + fig, ax = plt.subplots(figsize=(4.5, 2.5)) + + ax.plot(range(5)) + ax.text(0.5, 3., "serif", family="serif") + ax.text(0.5, 2., "monospace", family="monospace") + ax.text(2.5, 2., "sans-serif", family="sans-serif") + ax.set_xlabel(r"µ is not $\mu$") .. _pgf-troubleshooting: