MatplotLibAPI 3.3.0__py3-none-any.whl → 4.0.1__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.
- MatplotLibAPI/__init__.py +4 -86
- MatplotLibAPI/accessor.py +288 -191
- MatplotLibAPI/area.py +235 -0
- MatplotLibAPI/bar.py +193 -0
- MatplotLibAPI/base_plot.py +88 -0
- MatplotLibAPI/box_violin.py +186 -0
- MatplotLibAPI/bubble.py +569 -0
- MatplotLibAPI/{Composite.py → composite.py} +70 -83
- MatplotLibAPI/heatmap.py +246 -0
- MatplotLibAPI/histogram.py +172 -0
- MatplotLibAPI/mcp/__init__.py +17 -0
- MatplotLibAPI/mcp/metadata.py +90 -0
- MatplotLibAPI/mcp/renderers.py +45 -0
- MatplotLibAPI/mcp_server.py +626 -0
- MatplotLibAPI/network/__init__.py +28 -0
- MatplotLibAPI/network/constants.py +22 -0
- MatplotLibAPI/{Network.py → network/core.py} +347 -809
- MatplotLibAPI/network/plot.py +597 -0
- MatplotLibAPI/network/scaling.py +56 -0
- MatplotLibAPI/pie.py +155 -0
- MatplotLibAPI/pivot.py +282 -0
- MatplotLibAPI/sankey.py +99 -0
- MatplotLibAPI/{StyleTemplate.py → style_template.py} +8 -4
- MatplotLibAPI/sunburst.py +139 -0
- MatplotLibAPI/{Table.py → table.py} +109 -93
- MatplotLibAPI/{Timeserie.py → timeserie.py} +99 -42
- MatplotLibAPI/{Treemap.py → treemap.py} +43 -55
- MatplotLibAPI/typing.py +12 -0
- MatplotLibAPI/{_visualization_utils.py → utils.py} +30 -13
- MatplotLibAPI/waffle.py +174 -0
- MatplotLibAPI/{Wordcloud.py → word_cloud.py} +188 -88
- {matplotlibapi-3.3.0.dist-info → matplotlibapi-4.0.1.dist-info}/METADATA +98 -9
- matplotlibapi-4.0.1.dist-info/RECORD +36 -0
- {matplotlibapi-3.3.0.dist-info → matplotlibapi-4.0.1.dist-info}/WHEEL +1 -1
- matplotlibapi-4.0.1.dist-info/entry_points.txt +2 -0
- MatplotLibAPI/Area.py +0 -80
- MatplotLibAPI/Bar.py +0 -83
- MatplotLibAPI/BoxViolin.py +0 -75
- MatplotLibAPI/Bubble.py +0 -460
- MatplotLibAPI/Heatmap.py +0 -121
- MatplotLibAPI/Histogram.py +0 -73
- MatplotLibAPI/Pie.py +0 -70
- MatplotLibAPI/Pivot.py +0 -134
- MatplotLibAPI/Sankey.py +0 -46
- MatplotLibAPI/Sunburst.py +0 -89
- MatplotLibAPI/Waffle.py +0 -86
- MatplotLibAPI/_typing.py +0 -17
- matplotlibapi-3.3.0.dist-info/RECORD +0 -26
- {matplotlibapi-3.3.0.dist-info → matplotlibapi-4.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -10,17 +10,19 @@ from matplotlib.figure import Figure
|
|
|
10
10
|
from matplotlib.gridspec import GridSpec
|
|
11
11
|
from plotly.subplots import make_subplots
|
|
12
12
|
|
|
13
|
-
from .
|
|
14
|
-
|
|
15
|
-
from .
|
|
13
|
+
from .base_plot import BasePlot
|
|
14
|
+
|
|
15
|
+
from .bubble import BUBBLE_STYLE_TEMPLATE, FIG_SIZE, Bubble
|
|
16
|
+
from .network import aplot_network, NetworkGraph
|
|
17
|
+
from .style_template import (
|
|
16
18
|
MAX_RESULTS,
|
|
17
19
|
TITLE_SCALE_FACTOR,
|
|
18
20
|
StyleTemplate,
|
|
19
21
|
validate_dataframe,
|
|
20
22
|
)
|
|
21
|
-
from .
|
|
22
|
-
from .
|
|
23
|
-
from .
|
|
23
|
+
from .table import aplot_table
|
|
24
|
+
from .treemap import TREEMAP_STYLE_TEMPLATE, aplot_treemap
|
|
25
|
+
from .word_cloud import WORDCLOUD_STYLE_TEMPLATE, aplot_wordcloud, WordCloud
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
def plot_composite_bubble(
|
|
@@ -79,36 +81,29 @@ def plot_composite_bubble(
|
|
|
79
81
|
"""
|
|
80
82
|
validate_dataframe(pd_df, cols=[label, x, y, z], sort_by=sort_by)
|
|
81
83
|
|
|
82
|
-
if not sort_by:
|
|
83
|
-
sort_by = z
|
|
84
|
-
if not filter_by:
|
|
85
|
-
filter_by = z
|
|
86
|
-
plot_df = pd_df.sort_values(by=filter_by, ascending=ascending)[
|
|
87
|
-
[label, x, y, z]
|
|
88
|
-
].head(max_values)
|
|
89
|
-
|
|
90
84
|
fig = cast(Figure, plt.figure(figsize=figsize))
|
|
91
|
-
fig.
|
|
85
|
+
fig.set_facecolor(style.background_color)
|
|
92
86
|
grid = GridSpec(2, 2, height_ratios=[2, 1], width_ratios=[1, 1])
|
|
93
87
|
ax = fig.add_subplot(grid[0, 0:])
|
|
94
|
-
ax =
|
|
95
|
-
pd_df=
|
|
88
|
+
ax = Bubble(
|
|
89
|
+
pd_df=pd_df,
|
|
96
90
|
label=label,
|
|
97
91
|
x=x,
|
|
98
92
|
y=y,
|
|
99
93
|
z=z,
|
|
100
|
-
title=title,
|
|
101
|
-
style=style,
|
|
102
94
|
max_values=max_values,
|
|
103
95
|
center_to_mean=center_to_mean,
|
|
104
96
|
sort_by=sort_by,
|
|
105
97
|
ascending=ascending,
|
|
98
|
+
).aplot(
|
|
99
|
+
title=title,
|
|
100
|
+
style=style,
|
|
106
101
|
ax=ax,
|
|
107
102
|
)
|
|
108
103
|
|
|
109
104
|
ax2 = fig.add_subplot(grid[1, 0])
|
|
110
105
|
ax2 = aplot_table(
|
|
111
|
-
pd_df=
|
|
106
|
+
pd_df=pd_df,
|
|
112
107
|
cols=[label, z, y, x],
|
|
113
108
|
title=f"Top {table_rows}",
|
|
114
109
|
ax=ax2,
|
|
@@ -119,7 +114,7 @@ def plot_composite_bubble(
|
|
|
119
114
|
)
|
|
120
115
|
ax3 = fig.add_subplot(grid[1, 1])
|
|
121
116
|
ax3 = aplot_table(
|
|
122
|
-
pd_df=
|
|
117
|
+
pd_df=pd_df,
|
|
123
118
|
cols=[label, z, y, x],
|
|
124
119
|
title=f"Last {table_rows}",
|
|
125
120
|
ax=ax3,
|
|
@@ -171,46 +166,39 @@ def plot_composite_treemap(
|
|
|
171
166
|
go.Figure, optional
|
|
172
167
|
Composite treemap figure, or None if no data frames are provided.
|
|
173
168
|
"""
|
|
169
|
+
go_fig = go.Figure()
|
|
174
170
|
num_dimensions = len(pd_dfs)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
subplot_titles=subplot_titles,
|
|
188
|
-
vertical_spacing=0.2,
|
|
189
|
-
)
|
|
171
|
+
subplot_titles = [
|
|
172
|
+
f"{title}::{dim.title()}" if title is not None else dim.title()
|
|
173
|
+
for dim in pd_dfs
|
|
174
|
+
]
|
|
175
|
+
fig = make_subplots(
|
|
176
|
+
rows=num_dimensions,
|
|
177
|
+
cols=1,
|
|
178
|
+
specs=[[{"type": "treemap"} for _ in range(1)] for _ in range(num_dimensions)],
|
|
179
|
+
subplot_titles=subplot_titles,
|
|
180
|
+
vertical_spacing=0.2,
|
|
181
|
+
figure=go_fig,
|
|
182
|
+
)
|
|
190
183
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
current_row += 1
|
|
205
|
-
return fig
|
|
206
|
-
return None
|
|
184
|
+
for current_row, (path, df) in enumerate(pd_dfs.items(), start=1):
|
|
185
|
+
trm = aplot_treemap(
|
|
186
|
+
pd_df=df,
|
|
187
|
+
path=path,
|
|
188
|
+
values=values,
|
|
189
|
+
style=style,
|
|
190
|
+
color=color,
|
|
191
|
+
sort_by=sort_by,
|
|
192
|
+
ascending=ascending,
|
|
193
|
+
max_values=max_values,
|
|
194
|
+
)
|
|
195
|
+
fig.add_trace(trm, row=current_row, col=1)
|
|
196
|
+
return fig
|
|
207
197
|
|
|
208
198
|
|
|
209
|
-
def
|
|
210
|
-
|
|
199
|
+
def fplot_wordcloud_network(
|
|
200
|
+
node_df: pd.DataFrame,
|
|
211
201
|
edges_df: pd.DataFrame,
|
|
212
|
-
node_col: str = "node",
|
|
213
|
-
node_weight_col: str = "weight",
|
|
214
202
|
edge_source_col: str = "source",
|
|
215
203
|
edge_target_col: str = "target",
|
|
216
204
|
edge_weight_col: str = "weight",
|
|
@@ -226,15 +214,8 @@ def plot_wordcloud_network(
|
|
|
226
214
|
|
|
227
215
|
Parameters
|
|
228
216
|
----------
|
|
229
|
-
nodes_df : pd.DataFrame
|
|
230
|
-
DataFrame containing node labels and optional weights for the word cloud.
|
|
231
217
|
edges_df : pd.DataFrame
|
|
232
218
|
DataFrame containing edge connections for the network plot.
|
|
233
|
-
node_col : str, optional
|
|
234
|
-
Column in ``nodes_df`` containing the node labels. The default is ``"node"``.
|
|
235
|
-
node_weight_col : str, optional
|
|
236
|
-
Column in ``nodes_df`` containing weights for sizing words. The default is
|
|
237
|
-
``"weight"``.
|
|
238
219
|
edge_source_col : str, optional
|
|
239
220
|
Column in ``edges_df`` containing source nodes. The default is ``"source"``.
|
|
240
221
|
edge_target_col : str, optional
|
|
@@ -265,11 +246,6 @@ def plot_wordcloud_network(
|
|
|
265
246
|
Figure
|
|
266
247
|
Matplotlib figure containing the word cloud on top and network below.
|
|
267
248
|
"""
|
|
268
|
-
validate_dataframe(nodes_df, cols=[node_col], sort_by=node_weight_col)
|
|
269
|
-
validate_dataframe(
|
|
270
|
-
edges_df, cols=[edge_source_col, edge_target_col, edge_weight_col], sort_by=None
|
|
271
|
-
)
|
|
272
|
-
|
|
273
249
|
fig_raw, axes_raw = plt.subplots(
|
|
274
250
|
2,
|
|
275
251
|
1,
|
|
@@ -282,7 +258,7 @@ def plot_wordcloud_network(
|
|
|
282
258
|
wordcloud_style = wordcloud_style or style
|
|
283
259
|
network_style = network_style or style
|
|
284
260
|
|
|
285
|
-
fig.
|
|
261
|
+
fig.set_facecolor(style.background_color)
|
|
286
262
|
if title:
|
|
287
263
|
fig.suptitle(
|
|
288
264
|
title,
|
|
@@ -291,30 +267,41 @@ def plot_wordcloud_network(
|
|
|
291
267
|
fontname=style.font_name,
|
|
292
268
|
)
|
|
293
269
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
stopwords=stopwords,
|
|
302
|
-
ax=wordcloud_ax,
|
|
270
|
+
validate_dataframe(
|
|
271
|
+
node_df,
|
|
272
|
+
cols=["node", "weight"],
|
|
273
|
+
)
|
|
274
|
+
validate_dataframe(
|
|
275
|
+
edges_df,
|
|
276
|
+
cols=[edge_source_col, edge_target_col, edge_weight_col],
|
|
303
277
|
)
|
|
304
278
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
node_col=
|
|
309
|
-
node_weight_col=
|
|
279
|
+
network = NetworkGraph.from_pandas(
|
|
280
|
+
node_df,
|
|
281
|
+
edges_df,
|
|
282
|
+
node_col="node",
|
|
283
|
+
node_weight_col="weight",
|
|
310
284
|
edge_source_col=edge_source_col,
|
|
311
285
|
edge_target_col=edge_target_col,
|
|
312
286
|
edge_weight_col=edge_weight_col,
|
|
287
|
+
)
|
|
288
|
+
network.aplot(
|
|
313
289
|
title=None,
|
|
314
290
|
style=network_style,
|
|
315
291
|
ax=network_ax,
|
|
316
292
|
)
|
|
317
293
|
|
|
294
|
+
aplot_wordcloud(
|
|
295
|
+
pd_df=network.node_view.to_dataframe(),
|
|
296
|
+
text_column="node",
|
|
297
|
+
weight_column=edge_weight_col,
|
|
298
|
+
title=None,
|
|
299
|
+
style=wordcloud_style,
|
|
300
|
+
max_words=max_words,
|
|
301
|
+
stopwords=stopwords,
|
|
302
|
+
ax=wordcloud_ax,
|
|
303
|
+
)
|
|
304
|
+
|
|
318
305
|
if title:
|
|
319
306
|
fig.tight_layout(rect=(0, 0, 1, 0.95))
|
|
320
307
|
else:
|
MatplotLibAPI/heatmap.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"""Heatmap and correlation matrix helpers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional, Sequence, Tuple, cast
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import seaborn as sns
|
|
7
|
+
from matplotlib.axes import Axes
|
|
8
|
+
from matplotlib.figure import Figure
|
|
9
|
+
from pandas.api.extensions import register_dataframe_accessor
|
|
10
|
+
|
|
11
|
+
from .base_plot import BasePlot
|
|
12
|
+
from .style_template import (
|
|
13
|
+
HEATMAP_STYLE_TEMPLATE,
|
|
14
|
+
StyleTemplate,
|
|
15
|
+
string_formatter,
|
|
16
|
+
validate_dataframe,
|
|
17
|
+
)
|
|
18
|
+
from .typing import CorrelationMethod
|
|
19
|
+
from .utils import _get_axis, _merge_kwargs
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"HEATMAP_STYLE_TEMPLATE",
|
|
23
|
+
"aplot_heatmap",
|
|
24
|
+
"aplot_correlation_matrix",
|
|
25
|
+
"fplot_heatmap",
|
|
26
|
+
"fplot_correlation_matrix",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@register_dataframe_accessor("heatmap")
|
|
31
|
+
class Heatmap(BasePlot):
|
|
32
|
+
"""Class for plotting heatmaps and correlation matrices."""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
pd_df: pd.DataFrame,
|
|
37
|
+
x: str,
|
|
38
|
+
y: str,
|
|
39
|
+
value: str,
|
|
40
|
+
):
|
|
41
|
+
self._obj = _prepare_data(pd_df, x, y, value)
|
|
42
|
+
self.x = x
|
|
43
|
+
self.y = y
|
|
44
|
+
self.value = value
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def correlation_matrix(self) -> pd.DataFrame:
|
|
48
|
+
"""Compute the correlation matrix for the underlying DataFrame."""
|
|
49
|
+
return self._obj.corr()
|
|
50
|
+
|
|
51
|
+
def aplot(
|
|
52
|
+
self,
|
|
53
|
+
title: Optional[str] = None,
|
|
54
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
55
|
+
ax: Optional[Axes] = None,
|
|
56
|
+
**kwargs: Any,
|
|
57
|
+
) -> Axes:
|
|
58
|
+
"""Plot a heatmap on an existing Matplotlib axes."""
|
|
59
|
+
plot_ax = _get_axis(ax)
|
|
60
|
+
heatmap_kwargs: dict[str, Any] = {
|
|
61
|
+
"data": self._obj,
|
|
62
|
+
"cmap": style.palette,
|
|
63
|
+
"ax": plot_ax,
|
|
64
|
+
}
|
|
65
|
+
sns.heatmap(**_merge_kwargs(heatmap_kwargs, kwargs))
|
|
66
|
+
|
|
67
|
+
plot_ax.set_xlabel(string_formatter(self.x))
|
|
68
|
+
plot_ax.set_ylabel(string_formatter(self.y))
|
|
69
|
+
if title:
|
|
70
|
+
plot_ax.set_title(title)
|
|
71
|
+
return plot_ax
|
|
72
|
+
|
|
73
|
+
def fplot(
|
|
74
|
+
self,
|
|
75
|
+
title: Optional[str] = None,
|
|
76
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
77
|
+
figsize: Tuple[float, float] = (10, 6),
|
|
78
|
+
) -> Figure:
|
|
79
|
+
"""Plot a heatmap on a new Matplotlib figure."""
|
|
80
|
+
fig = Figure(
|
|
81
|
+
figsize=figsize,
|
|
82
|
+
facecolor=style.background_color,
|
|
83
|
+
edgecolor=style.background_color,
|
|
84
|
+
)
|
|
85
|
+
ax = fig.add_subplot(111)
|
|
86
|
+
ax.set_facecolor(style.background_color)
|
|
87
|
+
self.aplot(title=title, style=style, ax=ax)
|
|
88
|
+
return fig
|
|
89
|
+
|
|
90
|
+
def aplot_correlation_matrix(
|
|
91
|
+
self,
|
|
92
|
+
title: Optional[str] = None,
|
|
93
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
94
|
+
ax: Optional[Axes] = None,
|
|
95
|
+
**kwargs: Any,
|
|
96
|
+
) -> Axes:
|
|
97
|
+
"""Plot a correlation matrix heatmap on existing axes."""
|
|
98
|
+
plot_ax = _get_axis(ax)
|
|
99
|
+
heatmap_kwargs: dict[str, Any] = {
|
|
100
|
+
"data": self.correlation_matrix,
|
|
101
|
+
"cmap": style.palette,
|
|
102
|
+
"annot": True,
|
|
103
|
+
"fmt": ".2f",
|
|
104
|
+
"ax": plot_ax,
|
|
105
|
+
}
|
|
106
|
+
sns.heatmap(**_merge_kwargs(heatmap_kwargs, kwargs))
|
|
107
|
+
if title:
|
|
108
|
+
plot_ax.set_title(title)
|
|
109
|
+
return plot_ax
|
|
110
|
+
|
|
111
|
+
def fplot_correlation_matrix(
|
|
112
|
+
self,
|
|
113
|
+
title: Optional[str] = None,
|
|
114
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
115
|
+
figsize: Tuple[float, float] = (10, 6),
|
|
116
|
+
) -> Figure:
|
|
117
|
+
"""Plot a correlation matrix heatmap on a new figure."""
|
|
118
|
+
fig = Figure(
|
|
119
|
+
figsize=figsize,
|
|
120
|
+
facecolor=style.background_color,
|
|
121
|
+
edgecolor=style.background_color,
|
|
122
|
+
)
|
|
123
|
+
ax = fig.add_subplot(111)
|
|
124
|
+
ax.set_facecolor(style.background_color)
|
|
125
|
+
self.aplot_correlation_matrix(
|
|
126
|
+
title=title,
|
|
127
|
+
style=style,
|
|
128
|
+
ax=ax,
|
|
129
|
+
)
|
|
130
|
+
return fig
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _prepare_data(
|
|
134
|
+
pd_df: pd.DataFrame,
|
|
135
|
+
x: str,
|
|
136
|
+
y: str,
|
|
137
|
+
value: str,
|
|
138
|
+
) -> pd.DataFrame:
|
|
139
|
+
"""Prepare data for heatmap plotting."""
|
|
140
|
+
validate_dataframe(pd_df, cols=[x, y, value])
|
|
141
|
+
plot_df = pd_df[[x, y, value]].pivot_table(
|
|
142
|
+
index=y, columns=x, values=value, aggfunc="mean"
|
|
143
|
+
)
|
|
144
|
+
return plot_df
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _compute_correlation_matrix(
|
|
148
|
+
pd_df: pd.DataFrame,
|
|
149
|
+
columns: Optional[Sequence[str]],
|
|
150
|
+
method: CorrelationMethod,
|
|
151
|
+
) -> pd.DataFrame:
|
|
152
|
+
"""Compute a correlation matrix from numeric dataframe columns."""
|
|
153
|
+
source_df = pd_df[list(columns)] if columns else pd_df
|
|
154
|
+
numeric_df = source_df.select_dtypes(include="number")
|
|
155
|
+
if numeric_df.empty:
|
|
156
|
+
raise ValueError("No numeric columns available to compute correlation matrix.")
|
|
157
|
+
return numeric_df.corr(method=cast(Any, method))
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def aplot_heatmap(
|
|
161
|
+
pd_df: pd.DataFrame,
|
|
162
|
+
x: str,
|
|
163
|
+
y: str,
|
|
164
|
+
value: str,
|
|
165
|
+
title: Optional[str] = None,
|
|
166
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
167
|
+
ax: Optional[Axes] = None,
|
|
168
|
+
**kwargs: Any,
|
|
169
|
+
) -> Axes:
|
|
170
|
+
"""Plot a matrix heatmap for multivariate pattern detection."""
|
|
171
|
+
return Heatmap(
|
|
172
|
+
pd_df=pd_df,
|
|
173
|
+
x=x,
|
|
174
|
+
y=y,
|
|
175
|
+
value=value,
|
|
176
|
+
).aplot(
|
|
177
|
+
title=title,
|
|
178
|
+
style=style,
|
|
179
|
+
ax=ax,
|
|
180
|
+
**kwargs,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def aplot_correlation_matrix(
|
|
185
|
+
pd_df: pd.DataFrame,
|
|
186
|
+
columns: Optional[Sequence[str]] = None,
|
|
187
|
+
method: CorrelationMethod = "pearson",
|
|
188
|
+
title: Optional[str] = None,
|
|
189
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
190
|
+
ax: Optional[Axes] = None,
|
|
191
|
+
**kwargs: Any,
|
|
192
|
+
) -> Axes:
|
|
193
|
+
"""Plot a correlation matrix heatmap for numeric columns."""
|
|
194
|
+
corr_df = _compute_correlation_matrix(pd_df=pd_df, columns=columns, method=method)
|
|
195
|
+
plot_ax = _get_axis(ax)
|
|
196
|
+
heatmap_kwargs: dict[str, Any] = {
|
|
197
|
+
"data": corr_df,
|
|
198
|
+
"cmap": style.palette,
|
|
199
|
+
"annot": True,
|
|
200
|
+
"fmt": ".2f",
|
|
201
|
+
"ax": plot_ax,
|
|
202
|
+
}
|
|
203
|
+
sns.heatmap(**_merge_kwargs(heatmap_kwargs, kwargs))
|
|
204
|
+
if title:
|
|
205
|
+
plot_ax.set_title(title)
|
|
206
|
+
return plot_ax
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def fplot_heatmap(
|
|
210
|
+
pd_df: pd.DataFrame,
|
|
211
|
+
x: str,
|
|
212
|
+
y: str,
|
|
213
|
+
value: str,
|
|
214
|
+
title: Optional[str] = None,
|
|
215
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
216
|
+
figsize: Tuple[float, float] = (10, 6),
|
|
217
|
+
) -> Figure:
|
|
218
|
+
"""Plot a matrix heatmap on a new figure."""
|
|
219
|
+
return Heatmap(
|
|
220
|
+
pd_df=pd_df,
|
|
221
|
+
x=x,
|
|
222
|
+
y=y,
|
|
223
|
+
value=value,
|
|
224
|
+
).fplot(
|
|
225
|
+
title=title,
|
|
226
|
+
style=style,
|
|
227
|
+
figsize=figsize,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def fplot_correlation_matrix(
|
|
232
|
+
pd_df: pd.DataFrame,
|
|
233
|
+
x: str,
|
|
234
|
+
y: str,
|
|
235
|
+
value: str,
|
|
236
|
+
title: Optional[str] = None,
|
|
237
|
+
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
238
|
+
figsize: Tuple[float, float] = (10, 6),
|
|
239
|
+
) -> Figure:
|
|
240
|
+
"""Plot a correlation matrix heatmap on a new figure."""
|
|
241
|
+
return Heatmap(
|
|
242
|
+
pd_df=pd_df,
|
|
243
|
+
x=x,
|
|
244
|
+
y=y,
|
|
245
|
+
value=value,
|
|
246
|
+
).fplot_correlation_matrix(title=title, style=style, figsize=figsize)
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""Histogram and KDE plotting helpers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional, Tuple
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from pandas.api.extensions import register_dataframe_accessor
|
|
7
|
+
import seaborn as sns
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
from matplotlib.axes import Axes
|
|
10
|
+
from matplotlib.figure import Figure
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
from .base_plot import BasePlot
|
|
14
|
+
|
|
15
|
+
from .style_template import (
|
|
16
|
+
DISTRIBUTION_STYLE_TEMPLATE,
|
|
17
|
+
NETWORK_STYLE_TEMPLATE,
|
|
18
|
+
StyleTemplate,
|
|
19
|
+
string_formatter,
|
|
20
|
+
validate_dataframe,
|
|
21
|
+
)
|
|
22
|
+
from .utils import _get_axis, _merge_kwargs
|
|
23
|
+
|
|
24
|
+
__all__ = ["DISTRIBUTION_STYLE_TEMPLATE", "aplot_histogram", "fplot_histogram"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@register_dataframe_accessor("histogram")
|
|
28
|
+
class Histogram(BasePlot):
|
|
29
|
+
"""Class for plotting histograms with optional KDE."""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
pd_df: pd.DataFrame,
|
|
34
|
+
column: str,
|
|
35
|
+
bins: int = 20,
|
|
36
|
+
kde: bool = True,
|
|
37
|
+
):
|
|
38
|
+
super().__init__(pd_df=pd_df)
|
|
39
|
+
self.column = column
|
|
40
|
+
self.bins = bins
|
|
41
|
+
self.kde = kde
|
|
42
|
+
|
|
43
|
+
def aplot(
|
|
44
|
+
self,
|
|
45
|
+
title: Optional[str] = None,
|
|
46
|
+
style: StyleTemplate = NETWORK_STYLE_TEMPLATE,
|
|
47
|
+
ax: Optional[Axes] = None,
|
|
48
|
+
**kwargs: Any,
|
|
49
|
+
) -> Axes:
|
|
50
|
+
|
|
51
|
+
validate_dataframe(self._obj, cols=[self.column])
|
|
52
|
+
plot_ax = _get_axis(ax)
|
|
53
|
+
histplot_kwargs: dict[str, Any] = {
|
|
54
|
+
"data": self._obj,
|
|
55
|
+
"x": self.column,
|
|
56
|
+
"bins": self.bins,
|
|
57
|
+
"kde": self.kde,
|
|
58
|
+
"color": style.font_color,
|
|
59
|
+
"edgecolor": style.background_color,
|
|
60
|
+
"ax": plot_ax,
|
|
61
|
+
}
|
|
62
|
+
sns.histplot(**_merge_kwargs(histplot_kwargs, kwargs))
|
|
63
|
+
plot_ax.set_facecolor(style.background_color)
|
|
64
|
+
plot_ax.set_xlabel(string_formatter(self.column))
|
|
65
|
+
plot_ax.set_ylabel("Frequency")
|
|
66
|
+
if title:
|
|
67
|
+
plot_ax.set_title(title)
|
|
68
|
+
return plot_ax
|
|
69
|
+
|
|
70
|
+
def fplot(
|
|
71
|
+
self,
|
|
72
|
+
title: Optional[str] = None,
|
|
73
|
+
style: StyleTemplate = NETWORK_STYLE_TEMPLATE,
|
|
74
|
+
figsize: Tuple[float, float] = (10, 6),
|
|
75
|
+
) -> Figure:
|
|
76
|
+
fig = Figure(
|
|
77
|
+
figsize=figsize,
|
|
78
|
+
facecolor=style.background_color,
|
|
79
|
+
edgecolor=style.background_color,
|
|
80
|
+
)
|
|
81
|
+
ax = fig.add_subplot(111)
|
|
82
|
+
ax.set_facecolor(style.background_color)
|
|
83
|
+
self.aplot(
|
|
84
|
+
title=title,
|
|
85
|
+
style=style,
|
|
86
|
+
ax=ax,
|
|
87
|
+
)
|
|
88
|
+
return fig
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def aplot_histogram(
|
|
92
|
+
pd_df: pd.DataFrame,
|
|
93
|
+
column: str,
|
|
94
|
+
bins: int = 20,
|
|
95
|
+
kde: bool = True,
|
|
96
|
+
title: Optional[str] = None,
|
|
97
|
+
style: StyleTemplate = DISTRIBUTION_STYLE_TEMPLATE,
|
|
98
|
+
ax: Optional[Axes] = None,
|
|
99
|
+
**kwargs: Any,
|
|
100
|
+
) -> Axes:
|
|
101
|
+
"""Plot a histogram with an optional kernel density estimate.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
pd_df : pd.DataFrame
|
|
106
|
+
The input DataFrame containing the data to plot.
|
|
107
|
+
column : str
|
|
108
|
+
The name of the column to plot.
|
|
109
|
+
bins : int, optional
|
|
110
|
+
The number of bins for the histogram, by default 20.
|
|
111
|
+
kde : bool, optional
|
|
112
|
+
Whether to include a kernel density estimate, by default True.
|
|
113
|
+
title : Optional[str], optional
|
|
114
|
+
The title of the plot, by default None.
|
|
115
|
+
style : StyleTemplate, optional
|
|
116
|
+
The style template to use for the plot, by default DISTRIBUTION_STYLE_TEMPLATE.
|
|
117
|
+
ax : Optional[Axes], optional
|
|
118
|
+
An optional matplotlib Axes to plot on. If None, a new figure and axes will be created, by default None.
|
|
119
|
+
**kwargs : Any
|
|
120
|
+
Additional keyword arguments to pass to seaborn.histplot.
|
|
121
|
+
"""
|
|
122
|
+
return Histogram(
|
|
123
|
+
pd_df=pd_df,
|
|
124
|
+
column=column,
|
|
125
|
+
bins=bins,
|
|
126
|
+
kde=kde,
|
|
127
|
+
).aplot(
|
|
128
|
+
title=title,
|
|
129
|
+
style=style,
|
|
130
|
+
ax=ax,
|
|
131
|
+
**kwargs,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def fplot_histogram(
|
|
136
|
+
pd_df: pd.DataFrame,
|
|
137
|
+
column: str,
|
|
138
|
+
bins: int = 20,
|
|
139
|
+
kde: bool = True,
|
|
140
|
+
title: Optional[str] = None,
|
|
141
|
+
style: StyleTemplate = DISTRIBUTION_STYLE_TEMPLATE,
|
|
142
|
+
figsize: Tuple[float, float] = (10, 6),
|
|
143
|
+
) -> Figure:
|
|
144
|
+
"""Plot a histogram with optional KDE on a new figure.
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
----------
|
|
148
|
+
pd_df : pd.DataFrame
|
|
149
|
+
The input DataFrame containing the data to plot.
|
|
150
|
+
column : str
|
|
151
|
+
The name of the column to plot.
|
|
152
|
+
bins : int, optional
|
|
153
|
+
The number of bins for the histogram, by default 20.
|
|
154
|
+
kde : bool, optional
|
|
155
|
+
Whether to include a kernel density estimate, by default True.
|
|
156
|
+
title : Optional[str], optional
|
|
157
|
+
The title of the plot, by default None.
|
|
158
|
+
style : StyleTemplate, optional
|
|
159
|
+
The style template to use for the plot, by default DISTRIBUTION_STYLE_TEMPLATE.
|
|
160
|
+
figsize : Tuple[float, float], optional
|
|
161
|
+
The size of the figure, by default (10, 6).
|
|
162
|
+
"""
|
|
163
|
+
return Histogram(
|
|
164
|
+
pd_df=pd_df,
|
|
165
|
+
column=column,
|
|
166
|
+
bins=bins,
|
|
167
|
+
kde=kde,
|
|
168
|
+
).fplot(
|
|
169
|
+
title=title,
|
|
170
|
+
style=style,
|
|
171
|
+
figsize=figsize,
|
|
172
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""MCP helper utilities for MatplotLibAPI."""
|
|
2
|
+
|
|
3
|
+
from .metadata import (
|
|
4
|
+
DEDICATED_PLOT_TOOLS,
|
|
5
|
+
PLOT_MODULE_PARAMETER_HINTS,
|
|
6
|
+
SHARED_INPUT_CONTRACT,
|
|
7
|
+
)
|
|
8
|
+
from .renderers import MATPLOTLIB_RENDERERS, PLOTLY_RENDERERS, SUPPORTED_PLOT_MODULES
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"DEDICATED_PLOT_TOOLS",
|
|
12
|
+
"MATPLOTLIB_RENDERERS",
|
|
13
|
+
"PLOTLY_RENDERERS",
|
|
14
|
+
"PLOT_MODULE_PARAMETER_HINTS",
|
|
15
|
+
"SHARED_INPUT_CONTRACT",
|
|
16
|
+
"SUPPORTED_PLOT_MODULES",
|
|
17
|
+
]
|