dungmai's picture
Upload folder using huggingface_hub
8a6cf24 verified
"""Customizing chart configuration defaults."""
from __future__ import annotations
from functools import wraps as _wraps
from typing import TYPE_CHECKING, Any
from typing import overload as _overload
from altair.vegalite.v5.schema._config import (
AreaConfigKwds,
AutoSizeParamsKwds,
AxisConfigKwds,
AxisResolveMapKwds,
BarConfigKwds,
BindCheckboxKwds,
BindDirectKwds,
BindInputKwds,
BindRadioSelectKwds,
BindRangeKwds,
BoxPlotConfigKwds,
BrushConfigKwds,
CompositionConfigKwds,
ConfigKwds,
DateTimeKwds,
DerivedStreamKwds,
ErrorBandConfigKwds,
ErrorBarConfigKwds,
FeatureGeometryGeoJsonPropertiesKwds,
FormatConfigKwds,
GeoJsonFeatureCollectionKwds,
GeoJsonFeatureKwds,
GeometryCollectionKwds,
GradientStopKwds,
HeaderConfigKwds,
IntervalSelectionConfigKwds,
IntervalSelectionConfigWithoutTypeKwds,
LegendConfigKwds,
LegendResolveMapKwds,
LegendStreamBindingKwds,
LinearGradientKwds,
LineConfigKwds,
LineStringKwds,
LocaleKwds,
MarkConfigKwds,
MergedStreamKwds,
MultiLineStringKwds,
MultiPointKwds,
MultiPolygonKwds,
NumberLocaleKwds,
OverlayMarkDefKwds,
PaddingKwds,
PointKwds,
PointSelectionConfigKwds,
PointSelectionConfigWithoutTypeKwds,
PolygonKwds,
ProjectionConfigKwds,
ProjectionKwds,
RadialGradientKwds,
RangeConfigKwds,
RectConfigKwds,
ResolveKwds,
RowColKwds,
ScaleConfigKwds,
ScaleInvalidDataConfigKwds,
ScaleResolveMapKwds,
SelectionConfigKwds,
StepKwds,
StyleConfigIndexKwds,
ThemeConfig,
TickConfigKwds,
TimeIntervalStepKwds,
TimeLocaleKwds,
TitleConfigKwds,
TitleParamsKwds,
TooltipContentKwds,
TopLevelSelectionParameterKwds,
VariableParameterKwds,
ViewBackgroundKwds,
ViewConfigKwds,
)
from altair.vegalite.v5.theme import themes as _themes
if TYPE_CHECKING:
import sys
from typing import Any, Callable, Literal
if sys.version_info >= (3, 11):
from typing import LiteralString
else:
from typing_extensions import LiteralString
if sys.version_info >= (3, 10):
from typing import ParamSpec
else:
from typing_extensions import ParamSpec
from altair.utils.plugin_registry import Plugin
P = ParamSpec("P")
__all__ = [
"AreaConfigKwds",
"AutoSizeParamsKwds",
"AxisConfigKwds",
"AxisResolveMapKwds",
"BarConfigKwds",
"BindCheckboxKwds",
"BindDirectKwds",
"BindInputKwds",
"BindRadioSelectKwds",
"BindRangeKwds",
"BoxPlotConfigKwds",
"BrushConfigKwds",
"CompositionConfigKwds",
"ConfigKwds",
"DateTimeKwds",
"DerivedStreamKwds",
"ErrorBandConfigKwds",
"ErrorBarConfigKwds",
"FeatureGeometryGeoJsonPropertiesKwds",
"FormatConfigKwds",
"GeoJsonFeatureCollectionKwds",
"GeoJsonFeatureKwds",
"GeometryCollectionKwds",
"GradientStopKwds",
"HeaderConfigKwds",
"IntervalSelectionConfigKwds",
"IntervalSelectionConfigWithoutTypeKwds",
"LegendConfigKwds",
"LegendResolveMapKwds",
"LegendStreamBindingKwds",
"LineConfigKwds",
"LineStringKwds",
"LinearGradientKwds",
"LocaleKwds",
"MarkConfigKwds",
"MergedStreamKwds",
"MultiLineStringKwds",
"MultiPointKwds",
"MultiPolygonKwds",
"NumberLocaleKwds",
"OverlayMarkDefKwds",
"PaddingKwds",
"PointKwds",
"PointSelectionConfigKwds",
"PointSelectionConfigWithoutTypeKwds",
"PolygonKwds",
"ProjectionConfigKwds",
"ProjectionKwds",
"RadialGradientKwds",
"RangeConfigKwds",
"RectConfigKwds",
"ResolveKwds",
"RowColKwds",
"ScaleConfigKwds",
"ScaleInvalidDataConfigKwds",
"ScaleResolveMapKwds",
"SelectionConfigKwds",
"StepKwds",
"StyleConfigIndexKwds",
"ThemeConfig",
"TickConfigKwds",
"TimeIntervalStepKwds",
"TimeLocaleKwds",
"TitleConfigKwds",
"TitleParamsKwds",
"TooltipContentKwds",
"TopLevelSelectionParameterKwds",
"VariableParameterKwds",
"ViewBackgroundKwds",
"ViewConfigKwds",
"active",
"enable",
"get",
"names",
"options",
"register",
"unregister",
]
def register(
name: LiteralString, *, enable: bool
) -> Callable[[Plugin[ThemeConfig]], Plugin[ThemeConfig]]:
"""
Decorator for registering a theme function.
Parameters
----------
name
Unique name assigned in registry.
enable
Auto-enable the wrapped theme.
Examples
--------
Register and enable a theme::
import altair as alt
from altair import theme
@theme.register("param_font_size", enable=True)
def custom_theme() -> theme.ThemeConfig:
sizes = 12, 14, 16, 18, 20
return {
"autosize": {"contains": "content", "resize": True},
"background": "#F3F2F1",
"config": {
"axisX": {"labelFontSize": sizes[1], "titleFontSize": sizes[1]},
"axisY": {"labelFontSize": sizes[1], "titleFontSize": sizes[1]},
"font": "'Lato', 'Segoe UI', Tahoma, Verdana, sans-serif",
"headerColumn": {"labelFontSize": sizes[1]},
"headerFacet": {"labelFontSize": sizes[1]},
"headerRow": {"labelFontSize": sizes[1]},
"legend": {"labelFontSize": sizes[0], "titleFontSize": sizes[1]},
"text": {"fontSize": sizes[0]},
"title": {"fontSize": sizes[-1]},
},
"height": {"step": 28},
"width": 350,
}
We can then see the ``name`` parameter displayed when checking::
theme.active
"param_font_size"
Until another theme has been enabled, all charts will use defaults set in ``custom_theme()``::
from vega_datasets import data
source = data.stocks()
lines = (
alt.Chart(source, title=alt.Title("Stocks"))
.mark_line()
.encode(x="date:T", y="price:Q", color="symbol:N")
)
lines.interactive(bind_y=False)
"""
# HACK: See for `LiteralString` requirement in `name`
# https://github.com/vega/altair/pull/3526#discussion_r1743350127
def decorate(func: Plugin[ThemeConfig], /) -> Plugin[ThemeConfig]:
_register(name, func)
if enable:
_themes.enable(name)
@_wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> ThemeConfig:
return func(*args, **kwargs)
return wrapper
return decorate
def unregister(name: LiteralString) -> Plugin[ThemeConfig]:
"""
Remove and return a previously registered theme.
Parameters
----------
name
Unique name assigned during ``alt.theme.register``.
Raises
------
TypeError
When ``name`` has not been registered.
"""
plugin = _register(name, None)
if plugin is None:
msg = (
f"Found no theme named {name!r} in registry.\n"
f"Registered themes:\n"
f"{names()!r}"
)
raise TypeError(msg)
else:
return plugin
enable = _themes.enable
get = _themes.get
names = _themes.names
active: str
"""Return the name of the currently active theme."""
options: dict[str, Any]
"""Return the current themes options dictionary."""
def __dir__() -> list[str]:
return __all__
@_overload
def __getattr__(name: Literal["active"]) -> str: ... # type: ignore[misc]
@_overload
def __getattr__(name: Literal["options"]) -> dict[str, Any]: ... # type: ignore[misc]
def __getattr__(name: str) -> Any:
if name == "active":
return _themes.active
elif name == "options":
return _themes.options
else:
msg = f"module {__name__!r} has no attribute {name!r}"
raise AttributeError(msg)
def _register(
name: LiteralString, fn: Plugin[ThemeConfig] | None, /
) -> Plugin[ThemeConfig] | None:
if fn is None:
return _themes._plugins.pop(name, None)
elif _themes.plugin_type(fn):
_themes._plugins[name] = fn
return fn
else:
msg = f"{type(fn).__name__!r} is not a callable theme\n\n{fn!r}"
raise TypeError(msg)