Skip to content
Next Next commit
POC for Text mark
  • Loading branch information
mwaskom committed Sep 30, 2022
commit 7da1bd0eb4ef02cb23d679bc69490030ba1f9d23
33 changes: 33 additions & 0 deletions seaborn/_core/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,15 @@ class Alpha(IntervalProperty):
# TODO validate / enforce that output is in [0, 1]


class FontSize(IntervalProperty):
"""Thickness of the edges on a patch mark, in points."""
@property
def default_range(self) -> tuple[float, float]:
"""Min and max values used by default for semantic mapping."""
base = mpl.rcParams["font.size"]
return base * .5, base * 2


# =================================================================================== #
# Properties defined by arbitrary objects with inherently nominal scaling
# =================================================================================== #
Expand Down Expand Up @@ -496,6 +505,26 @@ def _get_dash_pattern(style: str | DashPattern) -> DashPatternWithOffset:
return offset, dashes


class TextAlignment(ObjectProperty):
legend = False


class HorizontalAlignment(TextAlignment):
legend = False

def _default_values(self, n: int) -> list:
vals = itertools.cycle(["left", "right"])
return [next(vals) for _ in range(n)]


class VerticalAlignment(TextAlignment):
legend = False

def _default_values(self, n: int) -> list:
vals = itertools.cycle(["top", "bottom"])
return [next(vals) for _ in range(n)]


# =================================================================================== #
# Properties with RGB(A) color values
# =================================================================================== #
Expand Down Expand Up @@ -751,6 +780,10 @@ def mapping(x):
"edgestyle": LineStyle,
"edgecolor": Color,
"edgealpha": Alpha,
"text": Property,
"halign": HorizontalAlignment,
"valign": VerticalAlignment,
"fontsize": FontSize,
"xmin": Coordinate,
"xmax": Coordinate,
"ymin": Coordinate,
Expand Down
64 changes: 64 additions & 0 deletions seaborn/_marks/text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from __future__ import annotations
from collections import defaultdict
from dataclasses import dataclass
from typing import Any

import numpy as np
import matplotlib as mpl
from matplotlib.artist import Artist

from seaborn._marks.base import (
Mark,
Mappable,
MappableFloat,
MappableString,
MappableColor,
resolve_properties,
document_properties,
)
from seaborn._core.scales import Scale


@document_properties
@dataclass
class Text(Mark):
"""
TODO
"""

text: MappableString = Mappable("")
color: MappableColor = Mappable("k")
fontsize: MappableFloat = Mappable(rc="font.size")
halign: MappableString = Mappable("center")
valign: MappableString = Mappable("center_baseline")

def _plot(self, split_gen, scales, orient):

ax_data = defaultdict(list)

for keys, data, ax in split_gen():
vals = resolve_properties(self, keys, scales)

for row in data.to_dict("records"):
artist = mpl.text.Text(
x=row["x"],
y=row["y"],
text=str(row["text"]), # TODO format
color=vals["color"],
fontsize=vals["fontsize"],
horizontalalignment=vals["halign"],
verticalalignment=vals["valign"],
**self.artist_kws,
)
ax.add_artist(artist)
ax_data[ax].append([row["x"], row["y"]])

for ax, ax_vals in ax_data.items():
ax.update_datalim(np.array(ax_vals))

def _legend_artist(
self, variables: list[str], value: Any, scales=dict[str, Scale],
) -> Artist:

# TODO
return mpl.line.Line2D()
3 changes: 2 additions & 1 deletion seaborn/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
from seaborn._marks.base import Mark # noqa: F401
from seaborn._marks.area import Area, Band # noqa: F401
from seaborn._marks.bar import Bar, Bars # noqa: F401
from seaborn._marks.line import Line, Lines, Path, Paths, Range # noqa: F401
from seaborn._marks.dot import Dot, Dots # noqa: F401
from seaborn._marks.line import Line, Lines, Path, Paths, Range # noqa: F401
from seaborn._marks.text import Text # noqa: F401

from seaborn._stats.base import Stat # noqa: F401
from seaborn._stats.aggregation import Agg, Est # noqa: F401
Expand Down