Draw text along an arbitrary curve in matplotlib, with arc-length positioning and a perpendicular offset.
Project description
curved-text
Draw text that follows an arbitrary curve in matplotlib.
Label curves along their own paths instead of in a legend, so the eye never leaves the data to decode a colour key.
Each character is placed in display coordinates and rotated to the chord across its own advance, which follows the curve's local tangent while staying smooth even when the curve is coarsely sampled. The layout is recomputed on every draw, so the label keeps following the curve through layout, resizing, and interactive panning or zooming. Placement is controlled by three independent parameters:
pos-- where the label is anchored along the curve, as a fraction of arc length (0.0= first point,1.0= last).anchor-- which part of the label lands atpos:"start","center", or"end".offset-- a perpendicular shift off the curve, in typographic points, along the normal of the label's chord (positive is above a left-to-right curve).
A label that overruns either end of the curve is not clipped: the curve is extended along its end tangent and the overrunning glyphs sit on that straight extension.
If you know LaTeX, this is matplotlib's analogue of TikZ's text along path
decoration (from decorations.text): pos/anchor play the role of text align and the indents, offset plays the role of raise, and overrunning
text rides the tangent extension instead of being truncated at the path's end.
Install
pip install curved-text
Or, from a clone, an editable install:
pip install -e .
Usage
import numpy as np
import matplotlib.pyplot as plt
from curved_text import curved_text
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
curved_text(ax, x, y, "text that follows the curve",
pos=0.5, anchor="center", offset=6.0, color="C3")
plt.show()
More worked examples -- the three placement controls, overrun behaviour, and integration with seaborn and pandas -- are in examples/.
The object-oriented form is also available:
from curved_text import CurvedText
CurvedText(x, y, "along the curve", ax, pos=0.2, anchor="start", offset=4.0)
Note the axes argument position: the CurvedText class takes it after x, y, text (matching matplotlib.text.Text), while the curved_text function takes it
first (matching matplotlib's axes-first helper functions).
Any extra keyword arguments (color, fontsize, alpha, fontfamily, ...) are
passed through to each character's matplotlib.text.Text.
Works with seaborn, pandas, and other matplotlib-backed libraries
curved_text needs a matplotlib.axes.Axes, so it works with any library that
draws on matplotlib. seaborn's axes-level functions return an Axes, its
figure-level functions expose one through .axes, and pandas DataFrame.plot
returns an Axes as well. Pass that axes in directly:
import seaborn as sns
ax = sns.lineplot(data=df, x="x", y="y")
curved_text(ax, df["x"], df["y"], "along the curve",
pos=0.5, anchor="center", offset=6.0)
Notes
- The curve
(x, y)should be ordered along the curve (monotonic in arc length) and have at least two points. - Arc length and the offset are computed in display space, so spacing and the offset are correct at any DPI and figure size.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file curved_text-0.1.1.tar.gz.
File metadata
- Download URL: curved_text-0.1.1.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa10eb0bf9c2a27117da5d266fddb84ac5ade6e0418285ad02d0c0032f78c3a2
|
|
| MD5 |
517f013754f7c67211432e5ef1aec55f
|
|
| BLAKE2b-256 |
e8a0187e8bf5aa6339d0ce38fb530a8cbef764abf56ca574e1c039c7bae1ea6a
|
Provenance
The following attestation bundles were made for curved_text-0.1.1.tar.gz:
Publisher:
publish.yml on thiebes/curved-text
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
curved_text-0.1.1.tar.gz -
Subject digest:
aa10eb0bf9c2a27117da5d266fddb84ac5ade6e0418285ad02d0c0032f78c3a2 - Sigstore transparency entry: 1806537304
- Sigstore integration time:
-
Permalink:
thiebes/curved-text@0aa8fa39ccea62f76cae53f788cfbcf98751f174 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/thiebes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0aa8fa39ccea62f76cae53f788cfbcf98751f174 -
Trigger Event:
push
-
Statement type:
File details
Details for the file curved_text-0.1.1-py3-none-any.whl.
File metadata
- Download URL: curved_text-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
721b39253ddbdd8fed093384b8dff25e9c3b90f0d20b58194d19706b804c9867
|
|
| MD5 |
fd18c18dc326852b81129d0626ddf52b
|
|
| BLAKE2b-256 |
c4dbc5cc900007964f1ac4937b7b897f722e2283bd367bfcc9b61ec012e89f8d
|
Provenance
The following attestation bundles were made for curved_text-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on thiebes/curved-text
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
curved_text-0.1.1-py3-none-any.whl -
Subject digest:
721b39253ddbdd8fed093384b8dff25e9c3b90f0d20b58194d19706b804c9867 - Sigstore transparency entry: 1806537344
- Sigstore integration time:
-
Permalink:
thiebes/curved-text@0aa8fa39ccea62f76cae53f788cfbcf98751f174 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/thiebes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0aa8fa39ccea62f76cae53f788cfbcf98751f174 -
Trigger Event:
push
-
Statement type: