Skip to content

Commit

Permalink
Add helpers for common artist edges
Browse files Browse the repository at this point in the history
  • Loading branch information
ksunden committed Aug 2, 2024
1 parent 0ebbbfd commit f0fabc1
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 26 deletions.
26 changes: 26 additions & 0 deletions data_prototype/axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@


import matplotlib as mpl
from data_prototype.artist import CompatibilityAxes
from matplotlib.axes._axes import Axes as MPLAxes, _preprocess_data
from matplotlib.axes._base import _process_plot_var_args
import matplotlib.collections as mcoll
import matplotlib.cbook as cbook
import matplotlib.lines as mlines
import matplotlib.markers as mmarkers
import matplotlib.projections as mprojections

Expand All @@ -14,13 +17,20 @@
FunctionConversionNode,
RenameConversionNode,
)
from .line import Line
from .wrappers import PathCollectionWrapper


class Axes(MPLAxes):
# Name for registering as a projection so we can experiment with it
name = "data-prototype"

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._ca = CompatibilityAxes(self)
self._get_lines_mirror = _process_plot_var_args("mirror")
self.add_artist(self._ca)

@_preprocess_data(
replace_names=[
"x",
Expand Down Expand Up @@ -142,6 +152,22 @@ def scatter(
self._request_autoscale_view()
return pcw

def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs):
kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
line_args = [*self._get_lines_mirror(self, *args, data=data, **kwargs)]
print(line_args)
lines = []
for coord, kws in line_args:
cont = ArrayContainer(**{"x": coord[0], "y": coord[1]})
line = Line(cont, **kws)
lines.append(line)
self._ca.add_artist(line)
if scalex:
self._request_autoscale_view("x")
if scaley:
self._request_autoscale_view("y")
return lines


# This is a handy trick to allow e.g. plt.subplots(subplot_kw={'projection': 'data-prototype'})
mprojections.register_projection(Axes)
35 changes: 34 additions & 1 deletion data_prototype/conversion_edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any
import numpy as np

from data_prototype.description import Desc, desc_like
from data_prototype.description import Desc, desc_like, ShapeSpec

from matplotlib.transforms import Transform

Expand Down Expand Up @@ -112,6 +112,17 @@ def from_default_value(
) -> "DefaultEdge":
return cls(name, {}, {key: output}, weight, invertable=False, value=value)

@classmethod
def from_rc(
cls, rc_name: str, key: str | None = None, coordinates: str = "display"
):
from matplotlib import rcParams

if key is None:
key = rc_name.split(".")[-1]
scalar = Desc((), coordinates)
return cls.from_default_value(f"{rc_name}_rc", key, scalar, rcParams[rc_name])

def evaluate(self, input: dict[str, Any]) -> dict[str, Any]:
return {k: self.value for k in self.output}

Expand Down Expand Up @@ -419,3 +430,25 @@ def __add__(self, other: Graph) -> Graph:
aother = {k: v for k, v in other._aliases}
aliases = tuple((aself | aother).items())
return Graph(self._edges + other._edges, aliases)


def coord_and_default(
key: str,
shape: ShapeSpec = (),
coordinates: str = "display",
default_value: Any = None,
default_rc: str | None = None,
):
if default_rc is not None:
if default_value is not None:
raise ValueError(
"Only one of 'default_value' and 'default_rc' may be specified"
)
def_edge = DefaultEdge.from_rc(default_rc, key, coordinates)
else:
scalar = Desc((), coordinates)
def_edge = DefaultEdge.from_default_value(
f"{key}_def", key, scalar, default_value
)
coord_edge = CoordinateEdge.from_coords(key, {key: Desc(shape)}, coordinates)
return coord_edge, def_edge
33 changes: 8 additions & 25 deletions data_prototype/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,24 @@

from .artist import Artist
from .description import Desc
from .conversion_edge import Graph, CoordinateEdge, DefaultEdge
from .conversion_edge import Graph, CoordinateEdge, coord_and_default


class Text(Artist):
def __init__(self, container, edges=None, **kwargs):
super().__init__(container, edges, **kwargs)

scalar = Desc((), "display")

edges = [
CoordinateEdge.from_coords(
"xycoords", {"x": Desc((), "auto"), "y": Desc((), "auto")}, "data"
),
CoordinateEdge.from_coords("text", {"text": Desc(())}, "display"),
CoordinateEdge.from_coords("color", {"color": Desc(())}, "display"),
CoordinateEdge.from_coords("alpha", {"alpha": Desc(())}, "display"),
CoordinateEdge.from_coords(
"fontproperties", {"fontproperties": Desc(())}, "display"
),
CoordinateEdge.from_coords("usetex", {"usetex": Desc(())}, "display"),
CoordinateEdge.from_coords("rotation", {"rotation": Desc(())}, "display"),
CoordinateEdge.from_coords(
"antialiased", {"antialiased": Desc(())}, "display"
),
DefaultEdge.from_default_value("text_def", "text", scalar, ""),
DefaultEdge.from_default_value("color_def", "color", scalar, "k"),
DefaultEdge.from_default_value("alpha_def", "alpha", scalar, 1),
DefaultEdge.from_default_value(
"fontproperties_def", "fontproperties", scalar, FontProperties()
),
DefaultEdge.from_default_value("usetex_def", "usetex", scalar, False),
DefaultEdge.from_default_value("rotation_def", "rotation", scalar, 0),
DefaultEdge.from_default_value(
"antialiased_def", "antialiased", scalar, False
),
*coord_and_default("text", default_value=""),
*coord_and_default("color", default_rc="text.color"),
*coord_and_default("alpha", default_value=1),
*coord_and_default("fontproperties", default_value=FontProperties()),
*coord_and_default("usetex", default_rc="text.usetex"),
*coord_and_default("rotation", default_value=0),
*coord_and_default("antialiased", default_rc="text.antialiased"),
]

self._graph = self._graph + Graph(edges)
Expand Down

0 comments on commit f0fabc1

Please sign in to comment.