MatplotLibAPI 3.2.21__py3-none-any.whl → 4.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. MatplotLibAPI/__init__.py +4 -86
  2. MatplotLibAPI/accessor.py +519 -196
  3. MatplotLibAPI/area.py +177 -0
  4. MatplotLibAPI/bar.py +185 -0
  5. MatplotLibAPI/base_plot.py +88 -0
  6. MatplotLibAPI/box_violin.py +180 -0
  7. MatplotLibAPI/bubble.py +568 -0
  8. MatplotLibAPI/{Composite.py → composite.py} +127 -106
  9. MatplotLibAPI/heatmap.py +223 -0
  10. MatplotLibAPI/histogram.py +170 -0
  11. MatplotLibAPI/mcp/__init__.py +17 -0
  12. MatplotLibAPI/mcp/metadata.py +90 -0
  13. MatplotLibAPI/mcp/renderers.py +45 -0
  14. MatplotLibAPI/mcp_server.py +626 -0
  15. MatplotLibAPI/network/__init__.py +28 -0
  16. MatplotLibAPI/network/constants.py +22 -0
  17. MatplotLibAPI/network/core.py +1360 -0
  18. MatplotLibAPI/network/plot.py +597 -0
  19. MatplotLibAPI/network/scaling.py +56 -0
  20. MatplotLibAPI/pie.py +154 -0
  21. MatplotLibAPI/pivot.py +274 -0
  22. MatplotLibAPI/sankey.py +99 -0
  23. MatplotLibAPI/{StyleTemplate.py → style_template.py} +27 -22
  24. MatplotLibAPI/sunburst.py +139 -0
  25. MatplotLibAPI/{Table.py → table.py} +112 -87
  26. MatplotLibAPI/{Timeserie.py → timeserie.py} +98 -42
  27. MatplotLibAPI/{Treemap.py → treemap.py} +43 -55
  28. MatplotLibAPI/typing.py +12 -0
  29. MatplotLibAPI/{_visualization_utils.py → utils.py} +7 -13
  30. MatplotLibAPI/waffle.py +173 -0
  31. MatplotLibAPI/word_cloud.py +489 -0
  32. {matplotlibapi-3.2.21.dist-info → matplotlibapi-4.0.0.dist-info}/METADATA +98 -9
  33. matplotlibapi-4.0.0.dist-info/RECORD +36 -0
  34. {matplotlibapi-3.2.21.dist-info → matplotlibapi-4.0.0.dist-info}/WHEEL +1 -1
  35. matplotlibapi-4.0.0.dist-info/entry_points.txt +2 -0
  36. MatplotLibAPI/Area.py +0 -80
  37. MatplotLibAPI/Bar.py +0 -83
  38. MatplotLibAPI/BoxViolin.py +0 -75
  39. MatplotLibAPI/Bubble.py +0 -458
  40. MatplotLibAPI/Heatmap.py +0 -121
  41. MatplotLibAPI/Histogram.py +0 -73
  42. MatplotLibAPI/Network.py +0 -989
  43. MatplotLibAPI/Pie.py +0 -70
  44. MatplotLibAPI/Pivot.py +0 -134
  45. MatplotLibAPI/Sankey.py +0 -46
  46. MatplotLibAPI/Sunburst.py +0 -89
  47. MatplotLibAPI/Waffle.py +0 -86
  48. MatplotLibAPI/Wordcloud.py +0 -373
  49. MatplotLibAPI/_typing.py +0 -17
  50. matplotlibapi-3.2.21.dist-info/RECORD +0 -26
  51. {matplotlibapi-3.2.21.dist-info → matplotlibapi-4.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,18 +1,18 @@
1
1
  """Treemap plotting utilities."""
2
2
 
3
- from typing import Any, Dict, Optional
3
+ from typing import Any, Dict, Optional, cast
4
4
 
5
5
  import pandas as pd
6
6
  import plotly.graph_objects as go
7
7
  from pandas import BooleanDtype, CategoricalDtype
8
8
 
9
- from .StyleTemplate import (
10
- TREEMAP_STYLE_TEMPLATE,
11
- StyleTemplate,
12
- percent_formatter,
13
- string_formatter,
14
- validate_dataframe,
15
- )
9
+ from .style_template import TREEMAP_STYLE_TEMPLATE, StyleTemplate, validate_dataframe
10
+
11
+ __all__ = [
12
+ "TREEMAP_STYLE_TEMPLATE",
13
+ "aplot_treemap",
14
+ "fplot_treemap",
15
+ ]
16
16
 
17
17
 
18
18
  def aplot_treemap(
@@ -25,43 +25,44 @@ def aplot_treemap(
25
25
  sort_by: Optional[str] = None,
26
26
  ascending: bool = False,
27
27
  max_values: int = 100,
28
- ) -> go.Trace:
29
- """Create a treemap trace from the data frame.
28
+ **kwargs: Any,
29
+ ) -> go.Treemap:
30
+ """Create a treemap trace from the provided dataframe.
30
31
 
31
32
  Parameters
32
33
  ----------
33
34
  pd_df : pd.DataFrame
34
35
  DataFrame containing the data to plot.
35
36
  path : str
36
- Column representing hierarchical path.
37
+ Column representing the hierarchical path.
37
38
  values : str
38
39
  Column containing values for each treemap block.
39
40
  style : StyleTemplate, optional
40
41
  Style configuration. The default is `TREEMAP_STYLE_TEMPLATE`.
41
42
  title : str, optional
42
- Plot title.
43
+ Plot title. The default is None.
43
44
  color : str, optional
44
- Column used for coloring.
45
+ Column used for coloring. The default is None.
45
46
  sort_by : str, optional
46
- Column used to sort data.
47
+ Column used to sort data. The default is None.
47
48
  ascending : bool, optional
48
- Sort order for the data. The default is `False`.
49
+ Sort order for the data. The default is False.
49
50
  max_values : int, optional
50
51
  Maximum number of rows to plot. The default is 100.
51
52
 
52
53
  Returns
53
54
  -------
54
- go.Trace
55
+ go.Treemap
55
56
  Plotly treemap trace.
56
57
  """
57
58
  cols = [path, values]
58
59
  if color:
59
60
  cols.append(color)
60
61
  validate_dataframe(pd_df, cols=cols, sort_by=sort_by)
61
- if not sort_by:
62
- sort_by = values
63
- df = pd_df.sort_values(by=sort_by, ascending=ascending)[cols].head(max_values)
64
- data = {
62
+
63
+ sort_col = sort_by or values
64
+ df = pd_df.sort_values(by=sort_col, ascending=ascending)[cols].head(max_values)
65
+ data: Dict[str, Any] = {
65
66
  "labels": df[path],
66
67
  "parents": [""] * len(df),
67
68
  "values": df[values],
@@ -74,22 +75,17 @@ def aplot_treemap(
74
75
  },
75
76
  }
76
77
 
77
- if color and color in pd_df.columns:
78
- color_data = pd_df[color]
78
+ if color and color in df.columns:
79
+ color_data = cast(pd.Series, df[color])
79
80
  if isinstance(
80
81
  color_data.dtype, CategoricalDtype
81
82
  ) or pd.api.types.is_object_dtype(color_data.dtype):
82
83
  color_data = color_data.astype("category").cat.codes
83
84
  elif isinstance(color_data.dtype, BooleanDtype):
84
85
  color_data = color_data.astype(int)
85
- data["marker"] = dict(colorscale="Viridis", colors=color_data.to_list())
86
-
87
- g = go.Treemap(
88
- data,
89
- root_color=style.background_color,
90
- )
86
+ data["marker"] = dict(colorscale="Viridis", colors=color_data.tolist())
91
87
 
92
- return g # type: ignore
88
+ return go.Treemap(data, root_color=style.background_color)
93
89
 
94
90
 
95
91
  def fplot_treemap(
@@ -103,40 +99,42 @@ def fplot_treemap(
103
99
  ascending: bool = False,
104
100
  max_values: int = 100,
105
101
  fig: Optional[go.Figure] = None,
106
- save_path: Optional[str] = None,
107
- savefig_kwargs: Optional[Dict[str, Any]] = None,
108
102
  ) -> go.Figure:
109
- """Return a figure containing the treemap plot.
103
+ """Return a figure containing a treemap plot.
110
104
 
111
105
  Parameters
112
106
  ----------
113
107
  pd_df : pd.DataFrame
114
108
  DataFrame containing the data to plot.
115
109
  path : str
116
- Column representing hierarchical path.
110
+ Column representing the hierarchical path.
117
111
  values : str
118
112
  Column containing values for each treemap block.
119
113
  style : StyleTemplate, optional
120
114
  Style configuration. The default is `TREEMAP_STYLE_TEMPLATE`.
121
115
  title : str, optional
122
- Plot title.
116
+ Plot title. The default is None.
123
117
  color : str, optional
124
- Column used for coloring.
118
+ Column used for coloring. The default is None.
125
119
  sort_by : str, optional
126
- Column used to sort data.
120
+ Column used to sort data. The default is None.
127
121
  ascending : bool, optional
128
- Sort order for the data. The default is `False`.
122
+ Sort order for the data. The default is False.
129
123
  max_values : int, optional
130
124
  Maximum number of rows to plot. The default is 100.
131
125
  fig : go.Figure, optional
132
- Existing figure to add the treemap to.
126
+ Existing figure to add the treemap to. If None, create a new figure.
127
+ save_path : str, optional
128
+ Path to save the figure as HTML or static image. The default is None.
129
+ savefig_kwargs : dict[str, Any], optional
130
+ Extra keyword arguments passed to Plotly save methods.
133
131
 
134
132
  Returns
135
133
  -------
136
134
  go.Figure
137
135
  Figure containing the treemap plot.
138
136
  """
139
- g = aplot_treemap(
137
+ treemap_trace = aplot_treemap(
140
138
  pd_df=pd_df,
141
139
  path=path,
142
140
  values=values,
@@ -148,25 +146,15 @@ def fplot_treemap(
148
146
  max_values=max_values,
149
147
  )
150
148
 
151
- if not fig:
152
- fig = go.Figure(g)
153
- else:
154
- fig.add_trace(g)
149
+ figure = go.Figure(treemap_trace) if fig is None else fig
150
+ if fig is not None:
151
+ figure.add_trace(treemap_trace)
155
152
 
156
- fig.update_layout(
153
+ figure.update_layout(
157
154
  title=title,
158
155
  plot_bgcolor=style.background_color,
159
156
  paper_bgcolor=style.background_color,
160
157
  font=dict(family=style.font_name, size=style.font_size, color=style.font_color),
161
- showlegend=style.legend if style else True,
158
+ showlegend=style.legend,
162
159
  )
163
-
164
- # Apply color scale
165
- fig.update_traces(marker=dict(colorscale=style.palette))
166
-
167
- if save_path:
168
- if save_path.lower().endswith((".html", ".htm")):
169
- fig.write_html(save_path, **(savefig_kwargs or {}))
170
- else:
171
- fig.write_image(save_path, **(savefig_kwargs or {}))
172
- return fig
160
+ return figure
@@ -0,0 +1,12 @@
1
+ """Internal type aliases used across MatplotLibAPI."""
2
+
3
+ from typing import Callable, Literal, Sequence, Union
4
+
5
+ from typing_extensions import TypeAlias
6
+
7
+ # ``DataFrame.corr`` supports the three built-in correlation methods or a callable
8
+ # that operates on two array-like inputs and returns a float.
9
+ CorrelationMethod: TypeAlias = Union[
10
+ Literal["pearson", "kendall", "spearman"],
11
+ Callable[[Sequence[float], Sequence[float]], float],
12
+ ]
@@ -8,6 +8,8 @@ from matplotlib.axes import Axes
8
8
  from matplotlib.figure import Figure
9
9
  from typing_extensions import Protocol
10
10
 
11
+ from .style_template import StyleTemplate
12
+
11
13
 
12
14
  class _AplotFunc(Protocol):
13
15
  def __call__(self, *, pd_df: Any, ax: Axes, **kwargs: Any) -> Axes: ...
@@ -22,9 +24,8 @@ def _wrap_aplot(
22
24
  plot_func: _AplotFunc,
23
25
  pd_df: Any,
24
26
  figsize: Tuple[float, float],
27
+ style: StyleTemplate,
25
28
  ax_args: Optional[Dict[str, Any]] = None,
26
- save_path: Optional[str] = None,
27
- savefig_kwargs: Optional[Dict[str, Any]] = None,
28
29
  **kwargs: Any,
29
30
  ) -> Figure:
30
31
  """Create a new figure and delegate plotting to an axis-level function.
@@ -39,30 +40,23 @@ def _wrap_aplot(
39
40
  Size of the created figure.
40
41
  ax_args : dict, optional
41
42
  Additional keyword arguments forwarded to ``plt.subplots``.
42
- save_path : str, optional
43
- File path where the figure should be saved. The default is ``None``
44
- and no file is written.
45
- savefig_kwargs : dict, optional
46
- Extra keyword arguments forwarded to ``Figure.savefig`` when
47
- ``save_path`` is provided. Defaults to ``None``.
48
43
  **kwargs : Any
49
44
  Additional arguments forwarded to ``plot_func``.
50
45
 
51
46
  Returns
52
47
  -------
53
48
  Figure
54
- Figure containing the rendered plot. If ``save_path`` is supplied the
55
- figure is saved before being returned.
49
+ Figure containing the rendered plot.
56
50
  """
57
51
  ax_args = ax_args or {}
58
52
  fig, axes_obj = plt.subplots(figsize=figsize, **ax_args)
53
+ fig_obj: Figure = cast(Figure, fig)
54
+ fig_obj.patch.set_facecolor(style.background_color)
59
55
  ax: Axes
60
56
  if isinstance(axes_obj, Axes):
61
57
  ax = axes_obj
62
58
  else:
63
59
  ax = cast(Axes, axes_obj.flat[0] if isinstance(axes_obj, ndarray) else axes_obj)
64
60
  plot_func(pd_df=pd_df, ax=ax, **kwargs)
65
- fig_obj: Figure = cast(Figure, fig)
66
- if save_path:
67
- fig_obj.savefig(save_path, **(savefig_kwargs or {}))
61
+
68
62
  return fig_obj
@@ -0,0 +1,173 @@
1
+ """Waffle chart helpers."""
2
+
3
+ from typing import Any, Optional, Tuple, cast
4
+
5
+ import pandas as pd
6
+ import seaborn as sns
7
+ import matplotlib.pyplot as plt
8
+ from matplotlib.axes import Axes
9
+ from matplotlib.figure import Figure
10
+ from matplotlib.patches import Rectangle
11
+
12
+ from .base_plot import BasePlot
13
+
14
+ from .style_template import PIE_STYLE_TEMPLATE, StyleTemplate, validate_dataframe
15
+ from .utils import _get_axis
16
+
17
+
18
+ class WaffleChart(BasePlot):
19
+ """Plot waffle charts from categorical proportions.
20
+
21
+ Methods
22
+ -------
23
+ aplot
24
+ Plot a waffle chart on an existing Matplotlib axes.
25
+ fplot
26
+ Plot a waffle chart on a new Matplotlib figure.
27
+ """
28
+
29
+ def __init__(self, pd_df: pd.DataFrame, category: str, value: str):
30
+ validate_dataframe(pd_df, cols=[category, value])
31
+ super().__init__(pd_df=pd_df)
32
+ self.category = category
33
+ self.value = value
34
+
35
+ def aplot(
36
+ self,
37
+ rows: int = 10,
38
+ title: Optional[str] = None,
39
+ style: StyleTemplate = PIE_STYLE_TEMPLATE,
40
+ ax: Optional[Axes] = None,
41
+ **kwargs: Any,
42
+ ) -> Axes:
43
+ """Plot a waffle chart on the provided axis.
44
+
45
+ Parameters
46
+ ----------
47
+ rows : int, optional
48
+ Number of rows and columns in the waffle grid. The default is 10.
49
+ title : str, optional
50
+ Title for the plot. The default is None.
51
+ style : StyleTemplate, optional
52
+ Style template for the plot. The default is PIE_STYLE_TEMPLATE.
53
+ ax : Axes, optional
54
+ Matplotlib axes to plot on. If None, use the current axes.
55
+ **kwargs : Any
56
+ Additional keyword arguments reserved for compatibility.
57
+
58
+ Returns
59
+ -------
60
+ Axes
61
+ The Matplotlib axes containing the waffle chart.
62
+ """
63
+ value_series = cast(pd.Series, self._obj[self.value])
64
+ category_series = cast(pd.Series, self._obj[self.category])
65
+ total = float(value_series.sum())
66
+ squares = rows * rows
67
+ colors = sns.color_palette(style.palette, n_colors=len(self._obj))
68
+ plot_ax = _get_axis(ax)
69
+ plot_ax.set_aspect("equal")
70
+
71
+ start = 0
72
+ for idx, (label, val) in enumerate(zip(category_series, value_series)):
73
+ count = int(round((val / total) * squares))
74
+ for square in range(start, min(start + count, squares)):
75
+ row = square // rows
76
+ col = square % rows
77
+ plot_ax.add_patch(
78
+ Rectangle(
79
+ (col, rows - row),
80
+ 1,
81
+ 1,
82
+ facecolor=colors[idx],
83
+ edgecolor=style.background_color,
84
+ )
85
+ )
86
+ start += count
87
+
88
+ plot_ax.set_xlim(0, rows)
89
+ plot_ax.set_ylim(0, rows + 1)
90
+ plot_ax.axis("off")
91
+ if title:
92
+ plot_ax.set_title(title)
93
+ legend_handles = [Rectangle((0, 0), 1, 1, color=color) for color in colors]
94
+ plot_ax.legend(
95
+ legend_handles, category_series, loc="upper center", ncol=3, frameon=False
96
+ )
97
+ return plot_ax
98
+
99
+ def fplot(
100
+ self,
101
+ rows: int = 10,
102
+ title: Optional[str] = None,
103
+ style: StyleTemplate = PIE_STYLE_TEMPLATE,
104
+ figsize: Tuple[float, float] = (8, 8),
105
+ ) -> Figure:
106
+ """Plot a waffle chart on a new figure.
107
+
108
+ Parameters
109
+ ----------
110
+ rows : int, optional
111
+ Number of rows and columns in the waffle grid. The default is 10.
112
+ title : str, optional
113
+ Title for the plot. The default is None.
114
+ style : StyleTemplate, optional
115
+ Style template for the plot. The default is PIE_STYLE_TEMPLATE.
116
+ figsize : tuple[float, float], optional
117
+ Figure size. The default is (8, 8).
118
+
119
+ Returns
120
+ -------
121
+ Figure
122
+ The Matplotlib figure containing the waffle chart.
123
+ """
124
+ fig = Figure(
125
+ figsize=figsize,
126
+ facecolor=style.background_color,
127
+ edgecolor=style.background_color,
128
+ )
129
+ ax = Axes(fig=fig, facecolor=style.background_color)
130
+ self.aplot(
131
+ title=title,
132
+ style=style,
133
+ rows=rows,
134
+ ax=ax,
135
+ )
136
+ return fig
137
+
138
+
139
+ def aplot_waffle(
140
+ pd_df: pd.DataFrame,
141
+ category: str,
142
+ value: str,
143
+ rows: int = 10,
144
+ title: Optional[str] = None,
145
+ style: StyleTemplate = PIE_STYLE_TEMPLATE,
146
+ ax: Optional[Axes] = None,
147
+ **kwargs: Any,
148
+ ) -> Axes:
149
+ """Plot a waffle chart on the provided axis."""
150
+ return WaffleChart(pd_df=pd_df, category=category, value=value).aplot(
151
+ title=title,
152
+ style=style,
153
+ rows=rows,
154
+ ax=ax,
155
+ )
156
+
157
+
158
+ def fplot_waffle(
159
+ pd_df: pd.DataFrame,
160
+ category: str,
161
+ value: str,
162
+ rows: int = 10,
163
+ title: Optional[str] = None,
164
+ style: StyleTemplate = PIE_STYLE_TEMPLATE,
165
+ figsize: Tuple[float, float] = (8, 8),
166
+ ) -> Figure:
167
+ """Plot waffle charts on a new figure."""
168
+ return WaffleChart(pd_df=pd_df, category=category, value=value).fplot(
169
+ title=title,
170
+ style=style,
171
+ rows=rows,
172
+ figsize=figsize,
173
+ )