- 
                Notifications
    You must be signed in to change notification settings 
- Fork 29
Description
Following a discussion on Twitter (https://twitter.com/matplotlib/status/1480027041315667971) it would be great to implement a “text-on-path” effect.
This would notably be made possible by reusing the following snippet https://stackoverflow.com/questions/19353576/curved-text-rendering-in-matplotlib (after asking for the OP permission), which implements a CurvedText artist as a replacement for the Text artist.
This would perfectly fit in after #74 is merged in (thanks @HPLegion!!).
State
Using the StackOverflow snippet above and the tokenizer below (see the diff.txt), I was able to achieve the following

What needs to be done:
- Support the features of matplotlib-label-lines (notably outlining)
- Wire-in properly with the package, for example using a switch follow_path=True|Falsein thelabelLine[s]functions.
- Come up with a clever solution for math (see below)?
Further thoughts on math text
One of the difficulties in handling this would be math texts. Indeed, the “natural” approach to adding text on a line is by splitting it character-wise and adding each character in sequence on the line. Unfortunately, this doesn't work for math text,s as how a character will be displayed depends on the current context:
$a^2$          % will display: a², so the ^should be ignored and the 2 be a superscript
$\mathrm{abc}$ % will display abc in roman (not italic) so should we expand it to \mathrm{a}\mathrm{b}\mathrm{c} ?!
$\dfrac{1}{2}$ % will display 1/2 (in a fraction), so it should not be expanded at all and just put on the line as is.Note that one easy workaround would simply be to consider a math string as a single character and do not do any expansion whatsoever. The text could then be placed token by token, where each token would either be a character or a math expression ($…$). Here is an example of a tokenizer (to be tested thoroughly):
import re
from typing import List
def tokenize_string(text: str) -> List[str]:
    # Make sure the string has only valid math (i.e. there is an even number of `$`)
    valid_math = len(re.findall(r"(?<!\\)\$", text)) % 2 == 0
    if not valid_math:
        return [c for c in text]
    math_mode = False
    tokens = []
    i = 0
    prev_c = None
    for i, c in enumerate(text):
        if c == "$" and prev_c != "\\":
            if math_mode:
                tokens.append("$" + current_token + "$")
                math_mode = False
            else:
                math_mode = True
                current_token = ""
        elif math_mode:
            current_token += c
        else:
            tokens.append(c)
        prev_c = c
    return tokens