Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text on path effect #81

Open
cphyc opened this issue Jan 10, 2022 · 0 comments · May be fixed by #131
Open

Text on path effect #81

cphyc opened this issue Jan 10, 2022 · 0 comments · May be fixed by #131

Comments

@cphyc
Copy link
Owner

cphyc commented Jan 10, 2022

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
image

What needs to be done:

  1. Support the features of matplotlib-label-lines (notably outlining)
  2. Wire-in properly with the package, for example using a switch follow_path=True|False in the labelLine[s] functions.
  3. 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
@cphyc cphyc linked a pull request Apr 12, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant