4

I would like to use curly brackets '}' in my plot all having different heights, but the same width. So far when scaling the text, the width scales proportionally:

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.text(0.2, 0.2, '}', fontsize=20)
ax.text(0.4, 0.2, '}', fontsize=40)
plt.show()

The only idea that comes to my mind is overlaying images of braces with the matplotlib image, e.g. using svgutils like in Importing an svg file a matplotlib figure, but this is cumbersome.

A solution with vector graphics as output would be ideal.

gizzmole
  • 1,437
  • 18
  • 26
  • I did think that using `LaTeX` text rendering, and a `\scalebox` would do the job here, but it appears that [doesn't work](https://github.com/matplotlib/matplotlib/issues/7480). – tmdavison Apr 26 '18 at 10:32

1 Answers1

7

To get a letter in scaled only in one dimension, e.g. height but keeping the other dimension constant, you may create the curly bracket as TextPath. This can be provided as input for a PathPatch. And the PathPatch may be scaled arbitrarily using matplotlib.transforms.

import matplotlib.transforms as mtrans
from matplotlib.text import TextPath
from matplotlib.patches import PathPatch

import matplotlib.pyplot as plt
fig, ax = plt.subplots()

def curly(x,y, scale, ax=None):
    if not ax: ax=plt.gca()
    tp = TextPath((0, 0), "}", size=1)
    trans = mtrans.Affine2D().scale(1, scale) + \
        mtrans.Affine2D().translate(x,y) + ax.transData
    pp = PathPatch(tp, lw=0, fc="k", transform=trans)
    ax.add_artist(pp)

X = [0,1,2,3,4]
Y = [1,1,2,2,3]
S = [1,2,3,4,1]

for x,y,s in zip(X,Y,S):
    curly(x,y,s, ax=ax)

ax.axis([0,5,0,7])
plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • is it possible to adapt this function to plot a bracket outside of the figure? For instance, to the right? – jonboy Apr 03 '20 at 01:10
  • 3
    @jonboy Sure, you would just need to set the `clip_path` off. – ImportanceOfBeingErnest Apr 04 '20 at 20:54
  • Cheers. Thanks @ImportanceOfBeingErnest – jonboy Apr 05 '20 at 06:29
  • 1
    Just in case somebody stumbles on this today, as I did, there is a really nice package by Dr. Gao, SiYu published after this question was answered. It is way more modular than reshaping a string of text, see the examples in the documentations / repo. https://github.com/iruletheworld/matplotlib-curly-brace documentation : https://matplotlib-curly-brace.readthedocs.io/en/latest/index.html I hope it helps others as it did for me! – DouglasCoenen Aug 12 '22 at 08:43