55This module provides a clean interface for resolving aesthetic mappings
66and determining whether aesthetic values are column references or literal values.
77"""
8+ from __future__ import annotations
89
9- import pandas as pd
10- import plotly .express as px
1110from functools import lru_cache
12- from typing import Any , Dict , Optional , Union , Tuple
11+ from typing import Any
12+
13+ import pandas as pd
1314
14- from .constants import SHAPE_PALETTE , get_color_palette as _get_color_palette
15- from .exceptions import ColumnNotFoundError , InvalidColorError
15+ from .constants import SHAPE_PALETTE
16+ from .constants import get_color_palette as _get_color_palette
17+ from .exceptions import ColumnNotFoundError
1618
1719
1820# Module-level cache for color conversions (expensive Plotly operations)
@@ -103,8 +105,8 @@ class AestheticMapper:
103105 - Literal values (colors, sizes, etc. to be used directly)
104106 """
105107
106- def __init__ (self , data : pd .DataFrame , mapping : Dict [str , Any ], params : Dict [str , Any ], theme = None ,
107- global_color_map : Dict [Any , str ] = None , global_shape_map : Dict [Any , str ] = None ,
108+ def __init__ (self , data : pd .DataFrame , mapping : dict [str , Any ], params : dict [str , Any ], theme = None ,
109+ global_color_map : dict [Any , str ] = None , global_shape_map : dict [Any , str ] = None ,
108110 validate : bool = True ):
109111 """
110112 Initialize the aesthetic mapper.
@@ -171,8 +173,8 @@ def validate_column(self, column: str, aesthetic: str = None) -> None:
171173 """
172174 if column not in self ._column_set :
173175 raise ColumnNotFoundError (column , list (self .data .columns ), aesthetic )
174-
175- def resolve_aesthetic (self , aesthetic : str ) -> Tuple [Any , Optional [ pd .Series ], Optional [ Dict ] ]:
176+
177+ def resolve_aesthetic (self , aesthetic : str ) -> tuple [Any , pd .Series | None , dict | None ]:
176178 """
177179 Resolve an aesthetic from both mapping and params.
178180
@@ -202,7 +204,7 @@ def resolve_aesthetic(self, aesthetic: str) -> Tuple[Any, Optional[pd.Series], O
202204 else :
203205 # It's a literal value
204206 return value , None , None
205-
207+
206208 def _is_continuous (self , series : pd .Series ) -> bool :
207209 """
208210 Determine if a series should be treated as continuous (numeric) or categorical.
@@ -237,7 +239,7 @@ def _is_continuous(self, series: pd.Series) -> bool:
237239
238240 return False
239241
240- def _create_color_map (self , series : pd .Series ) -> Dict [Any , str ]:
242+ def _create_color_map (self , series : pd .Series ) -> dict [Any , str ]:
241243 """
242244 Create a mapping from unique values to colors.
243245
@@ -261,7 +263,7 @@ def _create_color_map(self, series: pd.Series) -> Dict[Any, str]:
261263
262264 return color_map
263265
264- def _create_shape_map (self , series : pd .Series ) -> Dict [Any , str ]:
266+ def _create_shape_map (self , series : pd .Series ) -> dict [Any , str ]:
265267 """
266268 Create a mapping from unique values to marker shapes.
267269
@@ -278,8 +280,8 @@ def _create_shape_map(self, series: pd.Series) -> Dict[Any, str]:
278280 shape_map [val ] = SHAPE_PALETTE [i % len (SHAPE_PALETTE )]
279281
280282 return shape_map
281-
282- def get_style_properties (self ) -> Dict [str , Any ]:
283+
284+ def get_style_properties (self ) -> dict [str , Any ]:
283285 """
284286 Extract all relevant style properties for a geom.
285287
@@ -368,8 +370,8 @@ def get_style_properties(self) -> Dict[str, Any]:
368370 # Cache the result for subsequent calls
369371 self ._style_props_cache = result
370372 return result
371-
372- def get_color_for_value (self , value_key : Any , style_props : Dict [str , Any ] = None ,
373+
374+ def get_color_for_value (self , value_key : Any , style_props : dict [str , Any ] = None ,
373375 prefer_fill : bool = False ) -> str :
374376 """
375377 Get the resolved color for a specific value/group.
@@ -411,7 +413,7 @@ def get_color_for_value(self, value_key: Any, style_props: Dict[str, Any] = None
411413
412414 return style_props ['default_color' ]
413415
414- def get_color_with_alpha (self , value_key : Any = None , style_props : Dict [str , Any ] = None ,
416+ def get_color_with_alpha (self , value_key : Any = None , style_props : dict [str , Any ] = None ,
415417 prefer_fill : bool = False , alpha_override : float = None ) -> str :
416418 """
417419 Get color with alpha channel as RGBA string.
@@ -457,7 +459,7 @@ def _color_to_rgba(self, color: str, alpha: float) -> str:
457459 return _cached_color_to_rgba (color , alpha )
458460
459461 def apply_style_to_trace (self , trace_kwargs : dict , style_props : dict ,
460- target_mapping : dict , value_key : Optional [ Any ] = None ) -> dict :
462+ target_mapping : dict , value_key : Any | None = None ) -> dict :
461463 """
462464 Apply style properties to a trace dictionary based on target mapping.
463465
@@ -496,17 +498,17 @@ def apply_style_to_trace(self, trace_kwargs: dict, style_props: dict,
496498 return trace_kwargs
497499
498500
499- def create_aesthetic_mapper (data : pd .DataFrame , mapping : Dict [str , Any ],
500- params : Dict [str , Any ], theme = None ) -> AestheticMapper :
501+ def create_aesthetic_mapper (data : pd .DataFrame , mapping : dict [str , Any ],
502+ params : dict [str , Any ], theme = None ) -> AestheticMapper :
501503 """
502504 Factory function to create an AestheticMapper instance.
503-
505+
504506 Parameters:
505507 data: The DataFrame containing the plot data
506508 mapping: Dictionary of aesthetic mappings from aes()
507509 params: Dictionary of parameters passed to the geom
508510 theme: Optional theme object
509-
511+
510512 Returns:
511513 AestheticMapper instance
512514 """
0 commit comments