Skip to content

Commit 3a1aa32

Browse files
committed
Initial impementation of text
1 parent 8b1d326 commit 3a1aa32

File tree

4 files changed

+133
-10
lines changed

4 files changed

+133
-10
lines changed

data_prototype/artist.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,10 @@ def axes(self, ax):
277277
return
278278

279279
desc: Desc = Desc(("N",), coordinates="data")
280+
desc_scal: Desc = Desc((), coordinates="data")
280281
xy: dict[str, Desc] = {"x": desc, "y": desc}
282+
xy_scal: dict[str, Desc] = {"x": desc_scal, "y": desc_scal}
283+
281284
self._graph = Graph(
282285
[
283286
TransformEdge(
@@ -292,6 +295,18 @@ def axes(self, ax):
292295
desc_like(xy, coordinates="display"),
293296
transform=self._axes.transAxes,
294297
),
298+
TransformEdge(
299+
"data_scal",
300+
xy_scal,
301+
desc_like(xy_scal, coordinates="axes"),
302+
transform=self._axes.transData - self._axes.transAxes,
303+
),
304+
TransformEdge(
305+
"axes_scal",
306+
desc_like(xy_scal, coordinates="axes"),
307+
desc_like(xy_scal, coordinates="display"),
308+
transform=self._axes.transAxes,
309+
),
295310
FuncEdge.from_func(
296311
"xunits",
297312
lambda: self._axes.xaxis.units,

data_prototype/conversion_edge.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ def edges(self):
327327
import matplotlib.pyplot as plt
328328

329329
self.visualize(input)
330+
self.visualize()
330331
plt.show()
331332
raise NotImplementedError(
332333
"This may be possible, but is not a simple case already considered"
@@ -344,7 +345,7 @@ def edges(self):
344345
else:
345346
out_edges.append(SequenceEdge.from_edges("eval", edges, output_subset))
346347

347-
found_outputs = set()
348+
found_outputs = set(input)
348349
for out in out_edges:
349350
found_outputs |= set(out.output)
350351
if missing := set(output) - found_outputs:

data_prototype/text.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import numpy as np
2+
3+
4+
from .artist import Artist
5+
from .description import Desc
6+
from .conversion_edge import Graph, CoordinateEdge
7+
8+
9+
class Text(Artist):
10+
def __init__(self, container, edges=None, **kwargs):
11+
super().__init__(container, edges, **kwargs)
12+
13+
edges = [
14+
CoordinateEdge.from_coords(
15+
"xycoords", {"x": Desc((), "auto"), "y": Desc((), "auto")}, "data"
16+
),
17+
]
18+
19+
self._graph = self._graph + Graph(edges)
20+
21+
def draw(self, renderer, graph: Graph) -> None:
22+
if not self.get_visible():
23+
return
24+
g = graph + self._graph
25+
conv = g.evaluator(
26+
self._container.describe(),
27+
{
28+
"x": Desc((), "display"),
29+
"y": Desc((), "display"),
30+
"text": Desc((), "display"),
31+
"color": Desc((4,), "rgba"),
32+
"alpha": Desc((), "display"),
33+
"fontproperties": Desc((), "display"),
34+
"usetex": Desc((), "display"),
35+
# "parse_math": Desc((), "display"),
36+
# "wrap": Desc((), "display"),
37+
# "verticalalignment": Desc((), "display"),
38+
# "horizontalalignment": Desc((), "display"),
39+
"rotation": Desc((), "display"),
40+
# "linespacing": Desc((), "display"),
41+
# "rotation_mode": Desc((), "display"),
42+
"antialiased": Desc((), "display"),
43+
},
44+
)
45+
46+
query, _ = self._container.query(g)
47+
evald = conv.evaluate(query)
48+
49+
text = evald["text"]
50+
if text == "":
51+
return
52+
53+
x = evald["x"]
54+
y = evald["y"]
55+
56+
if not np.isfinite(x) or not np.isfinite(y):
57+
# TODO: log?
58+
return
59+
60+
# TODO bbox?
61+
# TODO implement wrapping/layout?
62+
# TODO implement math?
63+
# TODO implement path_effects?
64+
65+
# TODO gid?
66+
renderer.open_group("text", None)
67+
68+
gc = renderer.new_gc()
69+
gc.set_foreground(evald["color"])
70+
gc.set_alpha(evald["alpha"])
71+
# TODO url?
72+
gc.set_antialiased(evald["antialiased"])
73+
# TODO clipping?
74+
75+
if evald["usetex"]:
76+
renderer.draw_tex(
77+
gc, x, y, text, evald["fontproperties"], evald["rotation"]
78+
)
79+
else:
80+
renderer.draw_text(
81+
gc, x, y, text, evald["fontproperties"], evald["rotation"]
82+
)
83+
84+
gc.restore()
85+
renderer.close_group("text")

examples/animation.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616

1717
import matplotlib.pyplot as plt
1818
from matplotlib.animation import FuncAnimation
19+
from matplotlib.font_manager import FontProperties
1920

2021
from data_prototype.conversion_edge import Graph
2122
from data_prototype.description import Desc
2223

23-
from data_prototype.conversion_node import FunctionConversionNode
2424

25-
from data_prototype.wrappers import FormattedText
26-
from data_prototype.artist import CompatibilityArtist as CA
25+
from data_prototype.artist import CompatibilityAxes
2726
from data_prototype.line import Line
27+
from data_prototype.text import Text
28+
from data_prototype.conversion_edge import FuncEdge
2829

2930

3031
class SinOfTime:
@@ -38,6 +39,12 @@ def describe(self):
3839
"y": Desc((self.N,)),
3940
"phase": Desc(()),
4041
"time": Desc(()),
42+
"rotation": Desc((), "display"),
43+
"alpha": Desc((), "display"),
44+
"color": Desc((4,), "rgba"),
45+
"usetex": Desc((), "display"),
46+
"antialiased": Desc((), "display"),
47+
"fontproperties": Desc((), "display"),
4148
}
4249

4350
def query(
@@ -55,6 +62,12 @@ def query(
5562
"y": np.sin(th + phase),
5663
"phase": phase,
5764
"time": cur_time,
65+
"rotation": 0,
66+
"alpha": 1,
67+
"color": np.array([0, 0, 0, 1]),
68+
"usetex": False,
69+
"antialiased": True,
70+
"fontproperties": FontProperties(),
5871
}, hash(cur_time)
5972

6073

@@ -63,15 +76,24 @@ def update(frame, art):
6376

6477

6578
sot_c = SinOfTime()
66-
lw = CA(Line(sot_c, linewidth=5, color="green", label="sin(time)"))
67-
fc = FormattedText(
79+
lw = Line(sot_c, linewidth=5, color="green", label="sin(time)")
80+
fc = Text(
6881
sot_c,
69-
FunctionConversionNode.from_funcs(
70-
{"text": lambda phase: f"ϕ={phase:.2f}", "x": lambda: 2 * np.pi, "y": lambda: 1}
71-
),
82+
[
83+
FuncEdge.from_func(
84+
"text",
85+
lambda phase: f"ϕ={phase:.2f}",
86+
{"phase": Desc((), "auto")},
87+
{"text": Desc((), "display")},
88+
),
89+
],
90+
x=2 * np.pi,
91+
y=0,
7292
ha="right",
7393
)
74-
fig, ax = plt.subplots()
94+
fig, nax = plt.subplots()
95+
ax = CompatibilityAxes(nax)
96+
nax.add_artist(ax)
7597
ax.add_artist(lw)
7698
ax.add_artist(fc)
7799
ax.set_xlim(0, 2 * np.pi)

0 commit comments

Comments
 (0)