mgplot 0.2.23__tar.gz → 0.2.25__tar.gz
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.
- mgplot-0.2.25/.python-version +1 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/CHANGELOG.md +60 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/PKG-INFO +69 -1
- {mgplot-0.2.23 → mgplot-0.2.25}/README.md +68 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/finalise_plot.html +346 -338
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/summary_plot.html +356 -348
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot.html +443 -378
- mgplot-0.2.25/docs/search.js +46 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/pyproject.toml +1 -1
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/__init__.py +4 -2
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/axis_utils.py +64 -7
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/bar_plot.py +10 -5
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/fill_between_plot.py +8 -1
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/finalise_plot.py +10 -3
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/growth_plot.py +8 -1
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/keyword_checking.py +4 -1
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/line_plot.py +8 -2
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/run_plot.py +6 -1
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/settings.py +31 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/summary_plot.py +7 -3
- mgplot-0.2.25/test/test_chart_subdir.py +82 -0
- mgplot-0.2.25/test/test_tick_relabel.py +90 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/uv.lock +471 -400
- mgplot-0.2.23/docs/search.js +0 -46
- {mgplot-0.2.23 → mgplot-0.2.25}/.claude/settings.local.json +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/.gitignore +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/.pylintrc +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/LICENSE +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/build-all.sh +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/build-docs.sh +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/index.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/bar_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/fill_between_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/growth_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/line_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/postcovid_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/revision_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/run_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/docs/mgplot/seastrend_plot.html +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/colors.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/finalisers.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/lint-all.sh +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/multi_plot.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/postcovid_plot.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/py.typed +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/revision_plot.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/seastrend_plot.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/src/mgplot/utilities.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/test-executed.ipynb +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/test.ipynb +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/test_bar_string_index.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/test_multi_series_ticks.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/test_splat_sequences.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/test_zorder.py +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/zz-test-data/ocr_rba.csv +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/zz-test-data/revisions.csv +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/test/zz-test-data/summary.csv +0 -0
- {mgplot-0.2.23 → mgplot-0.2.25}/uv-upgrade.sh +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -1,3 +1,63 @@
|
|
|
1
|
+
Version 0.2.25 - released 5-Jun-2026 (Canberra, Australia)
|
|
2
|
+
|
|
3
|
+
* enhancement
|
|
4
|
+
- added tick_relabel keyword argument to line_plot(), bar_plot(),
|
|
5
|
+
growth_plot(), fill_between_plot() and run_plot() (and their
|
|
6
|
+
*_finalise variants): a callable applied to each generated x-axis
|
|
7
|
+
tick label after the contextual labellers have run (e.g. shorten
|
|
8
|
+
4-digit years to 2 digits)
|
|
9
|
+
- tick-label options (max_ticks, label rotation, tick_relabel) are
|
|
10
|
+
now stashed on the Axes by set_labels() and honoured when
|
|
11
|
+
finalise_plot() refreshes the labels before saving. Previously the
|
|
12
|
+
refresh regenerated labels with hard-coded defaults (max_ticks=10,
|
|
13
|
+
rotation=0), silently discarding per-plot settings
|
|
14
|
+
- added register_label_options() / get_label_options() to
|
|
15
|
+
axis_utils.py to support the above
|
|
16
|
+
- keyword checking now validates Callable annotations (checks
|
|
17
|
+
callability; previously a parameterized Callable would error)
|
|
18
|
+
- added test/test_tick_relabel.py covering tick_relabel, max_ticks
|
|
19
|
+
and label_rotation persistence through finalise_plot(), and
|
|
20
|
+
correct-figure close behaviour
|
|
21
|
+
- documented tick labelling and the multi-panel axes_only pattern
|
|
22
|
+
in README.md (new "Axis Tick Labels" and "Multi-Panel Figures"
|
|
23
|
+
sections)
|
|
24
|
+
|
|
25
|
+
* bug fix
|
|
26
|
+
- bar_plot() applied label_rotation via plt.xticks(), which targets
|
|
27
|
+
pyplot's current axes rather than the axes being plotted (wrong
|
|
28
|
+
panel in multi-axes figures), and the rotation was then lost when
|
|
29
|
+
finalise_plot() refreshed PeriodIndex labels. Rotation now goes
|
|
30
|
+
via the stashed label options (PeriodIndex) or set_xticklabels()
|
|
31
|
+
(string index)
|
|
32
|
+
- finalise_plot() closed pyplot's current figure (plt.close()) rather
|
|
33
|
+
than the figure belonging to the axes being finalised; it now closes
|
|
34
|
+
the correct figure (walking up from a SubFigure if necessary)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
Version 0.2.24 - released 4-Jun-2026 (Canberra, Australia)
|
|
39
|
+
|
|
40
|
+
* enhancement
|
|
41
|
+
- added the chart_subdir() context manager to settings.py. It
|
|
42
|
+
temporarily redirects chart output to a subdirectory of the current
|
|
43
|
+
chart_dir, optionally clearing the subdirectory of image files on
|
|
44
|
+
entry (clear=True), and restores the previous chart directory on
|
|
45
|
+
exit, even if an exception is raised. Yields the subdirectory path.
|
|
46
|
+
Useful in notebooks that group saved charts into per-topic
|
|
47
|
+
subdirectories
|
|
48
|
+
- added test/test_chart_subdir.py covering redirect/restore,
|
|
49
|
+
exception safety, clear=True semantics and nested contexts
|
|
50
|
+
- sorted __all__ in __init__.py (removed a duplicate "run_plot"
|
|
51
|
+
entry), fixing a pre-existing RUF022 lint error
|
|
52
|
+
- resolved all remaining mypy/pyright errors with runtime type
|
|
53
|
+
narrowing (no casts): plot_latest_datapoint() in summary_plot.py
|
|
54
|
+
now verifies datapoints are numeric (raising TypeError otherwise)
|
|
55
|
+
before calling float(), and apply_splat_kwargs() in
|
|
56
|
+
finalise_plot.py narrows dynamically-fetched kwarg values before
|
|
57
|
+
passing them to _apply_splat()
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
1
61
|
Version 0.2.23 - released 24-Apr-2026 (Canberra, Australia)
|
|
2
62
|
|
|
3
63
|
* bug fix
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mgplot
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.25
|
|
4
4
|
Summary: mgplot is a time-series/PeriodIndex frontend for matplotlib
|
|
5
5
|
Project-URL: Repository, https://github.com/bpalmer4/mgplot
|
|
6
6
|
Project-URL: Homepage, https://github.com/bpalmer4/mgplot
|
|
@@ -94,6 +94,74 @@ ax = mg.line_plot(data)
|
|
|
94
94
|
mg.finalise_plot(ax, title="My Chart", ylabel="Units", tag="my_chart")
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
Axis Tick Labels
|
|
98
|
+
----------------
|
|
99
|
+
For PeriodIndex data, x-axis tick labels are generated contextually:
|
|
100
|
+
the tick density is chosen to fit within `max_ticks`, and labels show
|
|
101
|
+
the period with years marked at transitions (e.g. a monthly axis shows
|
|
102
|
+
`Feb Mar ... 2024 ... Feb`, a quarterly axis shows `Q2 Q3 2025 Q2`).
|
|
103
|
+
|
|
104
|
+
Three keyword arguments control the labels on the period-indexed plot
|
|
105
|
+
functions (`line_plot`, `bar_plot`, `growth_plot`, `fill_between_plot`,
|
|
106
|
+
`run_plot`, and their `*_finalise` variants):
|
|
107
|
+
|
|
108
|
+
- `max_ticks` -- the maximum number of ticks (suggestive, not exact).
|
|
109
|
+
The global default is `mg.get_setting("max_ticks")`.
|
|
110
|
+
- `tick_relabel` -- a callable applied to each generated label string,
|
|
111
|
+
after the contextual labelling has run. Use it to restyle labels
|
|
112
|
+
without losing the transition logic.
|
|
113
|
+
- `label_rotation` -- (`bar_plot` only) rotates the x-axis tick labels.
|
|
114
|
+
|
|
115
|
+
For example, to convert 4-digit year labels to 2-digit years:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import re
|
|
119
|
+
|
|
120
|
+
def two_digit_years(label: str) -> str:
|
|
121
|
+
"""Shorten 4-digit years to 2 digits (e.g. 2024 -> 24)."""
|
|
122
|
+
return re.sub(r"\b(?:19|20)(\d{2})\b", r"\1", label)
|
|
123
|
+
|
|
124
|
+
# default labels: 2010 2012 2014 ... 2024 2026
|
|
125
|
+
# with tick_relabel: 10 12 14 ... 24 26
|
|
126
|
+
mg.line_plot_finalise(data, title="My Chart", tick_relabel=two_digit_years)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Because `tick_relabel` operates on the label strings, this works
|
|
130
|
+
unchanged on quarterly or monthly axes too: a label such as `2024`
|
|
131
|
+
marking a year transition becomes `24`, while the `Q2`/`Mar` labels
|
|
132
|
+
between transitions pass through untouched.
|
|
133
|
+
|
|
134
|
+
These options are stashed on the matplotlib Axes when the plot is drawn,
|
|
135
|
+
and `finalise_plot()` honours them when it refreshes the tick labels
|
|
136
|
+
just before saving. Editing tick labels directly on the Axes (e.g. with
|
|
137
|
+
`set_xticklabels()`) does not survive that refresh -- use `tick_relabel`
|
|
138
|
+
instead.
|
|
139
|
+
|
|
140
|
+
Multi-Panel Figures
|
|
141
|
+
-------------------
|
|
142
|
+
`finalise_plot()` works on a single Axes. For a figure with several
|
|
143
|
+
panels, finalise each panel with `axes_only=True` (axes-level styling
|
|
144
|
+
only: titles, labels, legends), then make the last call a normal
|
|
145
|
+
`finalise_plot()` carrying the figure-level arguments (`suptitle`,
|
|
146
|
+
`lfooter`, `rfooter`, `figsize`, ...), which also saves and closes
|
|
147
|
+
the figure:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
fig, (ax_left, ax_right) = plt.subplots(1, 2)
|
|
151
|
+
mg.line_plot(left_data, ax=ax_left)
|
|
152
|
+
mg.line_plot(right_data, ax=ax_right)
|
|
153
|
+
mg.finalise_plot(ax_left, title="Left Panel", ylabel="Index", axes_only=True)
|
|
154
|
+
mg.finalise_plot(
|
|
155
|
+
ax_right,
|
|
156
|
+
title="Right Panel",
|
|
157
|
+
ylabel="Index",
|
|
158
|
+
suptitle="Both Panels Together", # also used for the filename
|
|
159
|
+
lfooter="Australia. Seasonally adjusted.",
|
|
160
|
+
rfooter="Source: ABS",
|
|
161
|
+
figsize=(9, 4.5),
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
97
165
|
Convenience Finalisers
|
|
98
166
|
----------------------
|
|
99
167
|
For every plot function, there is a `*_finalise()` variant that combines
|
|
@@ -78,6 +78,74 @@ ax = mg.line_plot(data)
|
|
|
78
78
|
mg.finalise_plot(ax, title="My Chart", ylabel="Units", tag="my_chart")
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
Axis Tick Labels
|
|
82
|
+
----------------
|
|
83
|
+
For PeriodIndex data, x-axis tick labels are generated contextually:
|
|
84
|
+
the tick density is chosen to fit within `max_ticks`, and labels show
|
|
85
|
+
the period with years marked at transitions (e.g. a monthly axis shows
|
|
86
|
+
`Feb Mar ... 2024 ... Feb`, a quarterly axis shows `Q2 Q3 2025 Q2`).
|
|
87
|
+
|
|
88
|
+
Three keyword arguments control the labels on the period-indexed plot
|
|
89
|
+
functions (`line_plot`, `bar_plot`, `growth_plot`, `fill_between_plot`,
|
|
90
|
+
`run_plot`, and their `*_finalise` variants):
|
|
91
|
+
|
|
92
|
+
- `max_ticks` -- the maximum number of ticks (suggestive, not exact).
|
|
93
|
+
The global default is `mg.get_setting("max_ticks")`.
|
|
94
|
+
- `tick_relabel` -- a callable applied to each generated label string,
|
|
95
|
+
after the contextual labelling has run. Use it to restyle labels
|
|
96
|
+
without losing the transition logic.
|
|
97
|
+
- `label_rotation` -- (`bar_plot` only) rotates the x-axis tick labels.
|
|
98
|
+
|
|
99
|
+
For example, to convert 4-digit year labels to 2-digit years:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import re
|
|
103
|
+
|
|
104
|
+
def two_digit_years(label: str) -> str:
|
|
105
|
+
"""Shorten 4-digit years to 2 digits (e.g. 2024 -> 24)."""
|
|
106
|
+
return re.sub(r"\b(?:19|20)(\d{2})\b", r"\1", label)
|
|
107
|
+
|
|
108
|
+
# default labels: 2010 2012 2014 ... 2024 2026
|
|
109
|
+
# with tick_relabel: 10 12 14 ... 24 26
|
|
110
|
+
mg.line_plot_finalise(data, title="My Chart", tick_relabel=two_digit_years)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Because `tick_relabel` operates on the label strings, this works
|
|
114
|
+
unchanged on quarterly or monthly axes too: a label such as `2024`
|
|
115
|
+
marking a year transition becomes `24`, while the `Q2`/`Mar` labels
|
|
116
|
+
between transitions pass through untouched.
|
|
117
|
+
|
|
118
|
+
These options are stashed on the matplotlib Axes when the plot is drawn,
|
|
119
|
+
and `finalise_plot()` honours them when it refreshes the tick labels
|
|
120
|
+
just before saving. Editing tick labels directly on the Axes (e.g. with
|
|
121
|
+
`set_xticklabels()`) does not survive that refresh -- use `tick_relabel`
|
|
122
|
+
instead.
|
|
123
|
+
|
|
124
|
+
Multi-Panel Figures
|
|
125
|
+
-------------------
|
|
126
|
+
`finalise_plot()` works on a single Axes. For a figure with several
|
|
127
|
+
panels, finalise each panel with `axes_only=True` (axes-level styling
|
|
128
|
+
only: titles, labels, legends), then make the last call a normal
|
|
129
|
+
`finalise_plot()` carrying the figure-level arguments (`suptitle`,
|
|
130
|
+
`lfooter`, `rfooter`, `figsize`, ...), which also saves and closes
|
|
131
|
+
the figure:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
fig, (ax_left, ax_right) = plt.subplots(1, 2)
|
|
135
|
+
mg.line_plot(left_data, ax=ax_left)
|
|
136
|
+
mg.line_plot(right_data, ax=ax_right)
|
|
137
|
+
mg.finalise_plot(ax_left, title="Left Panel", ylabel="Index", axes_only=True)
|
|
138
|
+
mg.finalise_plot(
|
|
139
|
+
ax_right,
|
|
140
|
+
title="Right Panel",
|
|
141
|
+
ylabel="Index",
|
|
142
|
+
suptitle="Both Panels Together", # also used for the filename
|
|
143
|
+
lfooter="Australia. Seasonally adjusted.",
|
|
144
|
+
rfooter="Source: ABS",
|
|
145
|
+
figsize=(9, 4.5),
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
81
149
|
Convenience Finalisers
|
|
82
150
|
----------------------
|
|
83
151
|
For every plot function, there is a `*_finalise()` variant that combines
|