Skip to content

Commit fad1ed8

Browse files
committed
ENH: Add font* aesthestics to geom_text
closes #790
1 parent 6ba2f40 commit fad1ed8

File tree

6 files changed

+85
-22
lines changed

6 files changed

+85
-22
lines changed

doc/changelog.qmd

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
---
22
title: Changelog
33
---
4+
## v0.14.0
5+
6+
(not-yet-released)
7+
8+
### Enhancements
9+
10+
- The `family`, `fontstyle` and `fontweight` parameters of
11+
[](:class:`~plotnine.geom_text`) are now aesthetics ({{< issue 790 >}}).
12+
13+
### New Features
14+
15+
- [](:class:`~plotnine.geom_text`) has gained new aesthetics
16+
`fontvariant` and `fontstretch`.
17+
18+
419
## v0.13.6
520
(2024-05-09)
621

plotnine/geoms/geom_text.py

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ class geom_text(geom):
4242
parse : bool, default=False
4343
If `True`{.py}, the labels will be rendered with
4444
[latex](http://matplotlib.org/users/usetex.html).
45-
family : str, default=None
46-
Font family.
47-
fontweight : int | str, default="normal"
48-
Font weight.
49-
fontstyle : Literal["normal", "italic", "oblique"], default="normal"
50-
Font style.
5145
nudge_x : float, default=0
5246
Horizontal adjustment to apply to the text
5347
nudge_y : float, default=0
@@ -87,13 +81,64 @@ class geom_text(geom):
8781
8882
**Aesthetics Descriptions**
8983
84+
`size`
85+
86+
: Float or one of:
87+
88+
```python
89+
{
90+
"xx-small", "x-small", "small", "medium", "large",
91+
"x-large", "xx-large"
92+
}
93+
```
94+
9095
`ha`
9196
92-
: Horizontal alignment. One of *left*, *center* or *right.*
97+
: Horizontal alignment. One of `{"left", "center", "right"}`{.py}.
9398
9499
`va`
95100
96-
: Vertical alignment. One of *top*, *center*, *bottom*, *baseline*.
101+
: Vertical alignment. One of
102+
`{"top", "center", "bottom", "baseline", "center_baseline"}`{.py}.
103+
104+
`family`
105+
106+
: Font family. Can be a font name
107+
e.g. "Arial", "Helvetica", "Times", ... or a family that is one of
108+
`{"serif", "sans-serif", "cursive", "fantasy", "monospace"}}`{.py}
109+
110+
`fontweight`
111+
112+
: Font weight. A numeric value in range 0-1000 or a string that is
113+
one of:
114+
115+
```python
116+
{
117+
"ultralight", "light", "normal", "regular", "book", "medium",
118+
"roman", "semibold", "demibold", "demi", "bold", "heavy",
119+
"extra bold", "black"
120+
}
121+
```
122+
123+
`fontstyle`
124+
125+
: Font style. One of `{"normal", "italic", "oblique"}`{.py}.
126+
127+
`fontvariant`
128+
129+
: Font variant. One of `{"normal", "small-caps"}`{.py}.
130+
131+
`fontstretch`
132+
133+
: Font Stretch. A numeric value in range 0-1000, or one of:
134+
135+
```python
136+
{
137+
"ultra-condensed", "extra-condensed", "condensed",
138+
"semi-condensed", "normal", "semi-expanded", "expanded",
139+
"extra-expanded", "ultra-expanded"
140+
}
141+
```
97142
"""
98143
DEFAULT_AES = {
99144
"alpha": 1,
@@ -103,16 +148,18 @@ class geom_text(geom):
103148
"lineheight": 1.2,
104149
"ha": "center",
105150
"va": "center",
151+
"family": None,
152+
"fontweight": "normal",
153+
"fontstyle": "normal",
154+
"fontvariant": None,
155+
"fontstretch": None,
106156
}
107157
REQUIRED_AES = {"label", "x", "y"}
108158
DEFAULT_PARAMS = {
109159
"stat": "identity",
110160
"position": "identity",
111161
"na_rm": False,
112162
"parse": False,
113-
"family": None,
114-
"fontweight": "normal",
115-
"fontstyle": "normal",
116163
"nudge_x": 0,
117164
"nudge_y": 0,
118165
"adjust_text": None,
@@ -198,14 +245,18 @@ def draw_group(
198245

199246
# Create a dataframe for the plotting data required
200247
# by ax.text
201-
plot_data = data[["x", "y", "size", "ha", "va"]].copy()
202-
plot_data["s"] = data["label"]
203-
plot_data["rotation"] = data["angle"]
204-
plot_data["linespacing"] = data["lineheight"]
248+
ae_names = list(set(geom_text.DEFAULT_AES) | geom_text.REQUIRED_AES)
249+
plot_data = data[ae_names]
250+
plot_data.rename(
251+
{
252+
"label": "s",
253+
"angle": "rotation",
254+
"lineheight": "linespacing",
255+
},
256+
axis=1,
257+
inplace=True,
258+
)
205259
plot_data["color"] = color
206-
plot_data["family"] = params["family"]
207-
plot_data["fontweight"] = params["fontweight"]
208-
plot_data["fontstyle"] = params["fontstyle"]
209260
plot_data["zorder"] = params["zorder"]
210261
plot_data["rasterized"] = params["raster"]
211262
plot_data["clip_on"] = True
@@ -299,7 +350,7 @@ def draw_legend(
299350
y=0.5 * da.height,
300351
text="a",
301352
size=data["size"],
302-
family=lyr.geom.params["family"],
353+
family=data["family"],
303354
color=color,
304355
rotation=data["angle"],
305356
horizontalalignment="center",
Loading
Loading
Loading

tests/test_geom_text_label.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def test_label_aesthetics():
8888
assert p == "label_aesthetics"
8989

9090

91-
@pytest.mark.skipif(is_CI, reason="Sudden small difference on GHA")
9291
def test_adjust_text():
9392
p = (
9493
ggplot(mtcars.tail(2), aes("mpg", "disp", label="name"))
@@ -98,7 +97,6 @@ def test_adjust_text():
9897
assert p == "adjust_text"
9998

10099

101-
@pytest.mark.skipif(is_CI, reason="Sudden small difference on GHA")
102100
def test_adjust_label():
103101
p = (
104102
ggplot(mtcars.tail(2), aes("mpg", "disp", label="name"))
@@ -108,7 +106,6 @@ def test_adjust_label():
108106
assert p == "adjust_label"
109107

110108

111-
@pytest.mark.skipif(is_CI, reason="Sudden small difference on GHA")
112109
def test_adjust_text_default_color():
113110
adjust_text2 = adjust_text.copy()
114111
del adjust_text2["arrowprops"]["color"]

0 commit comments

Comments
 (0)