gsplot 0.0.6__tar.gz → 0.1.0__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.
- {gsplot-0.0.6 → gsplot-0.1.0}/PKG-INFO +4 -1
- {gsplot-0.0.6 → gsplot-0.1.0}/README.md +3 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/figure/axes.py +2 -2
- gsplot-0.1.0/gsplot/figure/axes_base.py +288 -0
- gsplot-0.0.6/gsplot/figure/axes_base.py → gsplot-0.1.0/gsplot/figure/axes_range_base.py +108 -390
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/line.py +11 -16
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/line_base.py +12 -28
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/line_colormap_dashed.py +22 -25
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/line_colormap_solid.py +13 -22
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/scatter.py +14 -23
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/scatter_colormap.py +16 -24
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/style/graph.py +44 -49
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/style/label.py +73 -70
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/style/legend.py +26 -44
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/style/legend_colormap.py +13 -22
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/style/ticks.py +22 -28
- gsplot-0.1.0/gsplot/version.py +2 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/pyproject.toml +1 -1
- gsplot-0.0.6/gsplot/version.py +0 -2
- {gsplot-0.0.6 → gsplot-0.1.0}/LICENSE +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/__init__.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/base/base.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/base/base_alias_validator.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/color/colormap.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/config/config.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/data/load_file.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/figure/figure_tools.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/figure/show.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/figure/store.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/hello_world/hello_world.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/logger.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/path/path.py +0 -0
- {gsplot-0.0.6 → gsplot-0.1.0}/gsplot/plot/line_colormap_base.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gsplot
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: General-scientific plot based on matplotlib
|
|
5
5
|
Author: Giordano Mattoni
|
|
6
6
|
Author-email: mattoni@scphys.kyoto-u.ac.jp
|
|
@@ -39,6 +39,9 @@ Description-Content-Type: text/markdown
|
|
|
39
39
|
|
|
40
40
|
Welcome to **gsplot** (general-scientific plot), a toolkit designed to enhance the capabilities of data visualization based on [matplotlib](https://matplotlib.org). This package is specifically tailored for creating high-quality figures aimed at the scientific field.
|
|
41
41
|
|
|
42
|
+
> [!WARNING]
|
|
43
|
+
> This package is _beta_ quality. Expect breaking changes and many bugs 🐛. Please report any issue you encounter 🤝.
|
|
44
|
+
|
|
42
45
|
## ✨ Features
|
|
43
46
|
|
|
44
47
|
- **Better Plot, Less Code**: Simplify the process of creating high-quality figures ⚛️
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
|
|
20
20
|
Welcome to **gsplot** (general-scientific plot), a toolkit designed to enhance the capabilities of data visualization based on [matplotlib](https://matplotlib.org). This package is specifically tailored for creating high-quality figures aimed at the scientific field.
|
|
21
21
|
|
|
22
|
+
> [!WARNING]
|
|
23
|
+
> This package is _beta_ quality. Expect breaking changes and many bugs 🐛. Please report any issue you encounter 🤝.
|
|
24
|
+
|
|
22
25
|
## ✨ Features
|
|
23
26
|
|
|
24
27
|
- **Better Plot, Less Code**: Simplify the process of creating high-quality figures ⚛️
|
|
@@ -8,7 +8,7 @@ from matplotlib.typing import HashableList
|
|
|
8
8
|
|
|
9
9
|
from ..base.base import CreateClassParams, ParamsGetter, bind_passed_params
|
|
10
10
|
from ..plot.line_base import NumLines
|
|
11
|
-
from .
|
|
11
|
+
from .axes_range_base import AxesRangeSingleton
|
|
12
12
|
from .store import StoreSingleton
|
|
13
13
|
|
|
14
14
|
_T = TypeVar("_T")
|
|
@@ -285,7 +285,7 @@ class AxesHandler(Generic[_T]):
|
|
|
285
285
|
raise ValueError("Mosaic must be specified.")
|
|
286
286
|
|
|
287
287
|
# Initialize the axes range list by the number of axes in the current figure
|
|
288
|
-
AxesRangeSingleton().reset(
|
|
288
|
+
AxesRangeSingleton().reset()
|
|
289
289
|
|
|
290
290
|
|
|
291
291
|
@bind_passed_params()
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, TypeVar
|
|
4
|
+
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import numpy as np
|
|
7
|
+
from matplotlib.axes import Axes
|
|
8
|
+
from matplotlib.transforms import Bbox
|
|
9
|
+
from numpy.typing import NDArray
|
|
10
|
+
|
|
11
|
+
from .figure_tools import FigureLayout
|
|
12
|
+
|
|
13
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
14
|
+
|
|
15
|
+
__all__: list[str] = []
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# class AxesResolver:
|
|
19
|
+
# """
|
|
20
|
+
# Resolves an axis target to a Matplotlib `Axes` object or its index.
|
|
21
|
+
#
|
|
22
|
+
# This class provides a mechanism to convert an axis target, which can be either
|
|
23
|
+
# an integer (index of the axis) or an `Axes` object, into a consistent representation
|
|
24
|
+
# including the corresponding `Axes` object and its index within the current figure.
|
|
25
|
+
#
|
|
26
|
+
# Parameters
|
|
27
|
+
# --------------------
|
|
28
|
+
# axis_target : int or matplotlib.axes.Axes
|
|
29
|
+
# The target axis to resolve. Can be an integer representing the index of the
|
|
30
|
+
# axis in the current figure or a specific `Axes` object.
|
|
31
|
+
#
|
|
32
|
+
# Attributes
|
|
33
|
+
# --------------------
|
|
34
|
+
# axis_target : int or matplotlib.axes.Axes
|
|
35
|
+
# The input target axis (as provided by the user).
|
|
36
|
+
# _axis_index : int or None
|
|
37
|
+
# The resolved index of the target axis in the current figure.
|
|
38
|
+
# _axis : matplotlib.axes.Axes or None
|
|
39
|
+
# The resolved `Axes` object corresponding to the target.
|
|
40
|
+
#
|
|
41
|
+
# Methods
|
|
42
|
+
# --------------------
|
|
43
|
+
# _resolve_type()
|
|
44
|
+
# Resolves the type of the axis target and retrieves the corresponding
|
|
45
|
+
# `Axes` object and its index.
|
|
46
|
+
# axis_index
|
|
47
|
+
# Returns the resolved index of the axis.
|
|
48
|
+
# axis
|
|
49
|
+
# Returns the resolved `Axes` object.
|
|
50
|
+
#
|
|
51
|
+
# Raises
|
|
52
|
+
# --------------------
|
|
53
|
+
# IndexError
|
|
54
|
+
# If the provided axis index is out of range for the current figure.
|
|
55
|
+
# ValueError
|
|
56
|
+
# If the axis target is neither an integer nor an `Axes` object.
|
|
57
|
+
#
|
|
58
|
+
# Examples
|
|
59
|
+
# --------------------
|
|
60
|
+
# >>> import matplotlib.pyplot as plt
|
|
61
|
+
# >>> fig, axs = plt.subplots(2, 2)
|
|
62
|
+
# >>> resolver = AxesResolver(1) # Resolves the second axis (index 1)
|
|
63
|
+
# >>> print(resolver.axis)
|
|
64
|
+
# AxesSubplot(0.5,0.5;0.352273x0.352273)
|
|
65
|
+
#
|
|
66
|
+
# >>> resolver = AxesResolver(axs[0, 0]) # Resolves an Axes object directly
|
|
67
|
+
# >>> print(resolver.axis_index)
|
|
68
|
+
# 0
|
|
69
|
+
# """
|
|
70
|
+
#
|
|
71
|
+
# def __init__(self, axis_target: int | Axes) -> None:
|
|
72
|
+
# self.axis_target: int | Axes = axis_target
|
|
73
|
+
#
|
|
74
|
+
# self._axis_index: int | None = None
|
|
75
|
+
# self._axis: Axes | None = None
|
|
76
|
+
#
|
|
77
|
+
# self._resolve_type()
|
|
78
|
+
#
|
|
79
|
+
# def _resolve_type(self) -> None:
|
|
80
|
+
# """
|
|
81
|
+
# Resolves the type of the axis target and retrieves the corresponding
|
|
82
|
+
# `Axes` object and its index.
|
|
83
|
+
#
|
|
84
|
+
# Raises
|
|
85
|
+
# --------------------
|
|
86
|
+
# IndexError
|
|
87
|
+
# If the provided axis index is out of range for the current figure.
|
|
88
|
+
# ValueError
|
|
89
|
+
# If the axis target is neither an integer nor an `Axes` object.
|
|
90
|
+
# """
|
|
91
|
+
#
|
|
92
|
+
# def ordinal_suffix(n: int) -> str:
|
|
93
|
+
# if 11 <= n % 100 <= 13:
|
|
94
|
+
# suffix = "th"
|
|
95
|
+
# else:
|
|
96
|
+
# suffix = {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th")
|
|
97
|
+
# return f"{n}{suffix}"
|
|
98
|
+
#
|
|
99
|
+
# if isinstance(self.axis_target, int):
|
|
100
|
+
# self._axis_index = self.axis_target
|
|
101
|
+
# axes = plt.gcf().axes
|
|
102
|
+
# try:
|
|
103
|
+
# self._axis = axes[self._axis_index]
|
|
104
|
+
# except IndexError:
|
|
105
|
+
# error_message = f"Axes out of range: {self._axis_index} => Number of axes: {len(axes)}, but requested {ordinal_suffix(self._axis_index + 1)} axis."
|
|
106
|
+
# raise IndexError(error_message)
|
|
107
|
+
# elif isinstance(self.axis_target, Axes):
|
|
108
|
+
# self._axis = self.axis_target
|
|
109
|
+
# if self.axis_target in plt.gcf().axes:
|
|
110
|
+
# self._axis_index = plt.gcf().axes.index(self._axis)
|
|
111
|
+
# else:
|
|
112
|
+
# # Add the axis to the current figure if it is not present
|
|
113
|
+
# plt.gcf().add_axes(self._axis)
|
|
114
|
+
# self._axis_index = len(plt.gcf().axes) - 1
|
|
115
|
+
# else:
|
|
116
|
+
# raise ValueError(
|
|
117
|
+
# "Invalid axis target. Please provide an integer or Axes object."
|
|
118
|
+
# )
|
|
119
|
+
#
|
|
120
|
+
# @property
|
|
121
|
+
# def axis_index(self) -> int:
|
|
122
|
+
# """
|
|
123
|
+
# Returns the resolved index of the target axis.
|
|
124
|
+
#
|
|
125
|
+
# Returns
|
|
126
|
+
# --------------------
|
|
127
|
+
# int
|
|
128
|
+
# The index of the resolved axis.
|
|
129
|
+
#
|
|
130
|
+
# Raises
|
|
131
|
+
# --------------------
|
|
132
|
+
# ValueError
|
|
133
|
+
# If the axis index is not resolved.
|
|
134
|
+
# """
|
|
135
|
+
# if isinstance(self._axis_index, int):
|
|
136
|
+
# return self._axis_index
|
|
137
|
+
# else:
|
|
138
|
+
# raise ValueError("Axis index not resolved. Please check the AxisResolver")
|
|
139
|
+
#
|
|
140
|
+
# @property
|
|
141
|
+
# def axis(self) -> Axes:
|
|
142
|
+
# """
|
|
143
|
+
# Returns the resolved `Axes` object.
|
|
144
|
+
#
|
|
145
|
+
# Returns
|
|
146
|
+
# --------------------
|
|
147
|
+
# matplotlib.axes.Axes
|
|
148
|
+
# The resolved `Axes` object.
|
|
149
|
+
#
|
|
150
|
+
# Raises
|
|
151
|
+
# --------------------
|
|
152
|
+
# ValueError
|
|
153
|
+
# If the axis is not resolved.
|
|
154
|
+
# """
|
|
155
|
+
# if isinstance(self._axis, Axes):
|
|
156
|
+
# return self._axis
|
|
157
|
+
# else:
|
|
158
|
+
# raise ValueError("Axis not resolced. Please check the AxisResolver")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class AxisLayout:
|
|
162
|
+
"""
|
|
163
|
+
A utility class for managing axis layout properties in a Matplotlib figure.
|
|
164
|
+
|
|
165
|
+
This class provides methods to retrieve an axis's position and size, both in
|
|
166
|
+
normalized figure coordinates and in physical units (inches). It integrates
|
|
167
|
+
with the `AxesResolver` and `FigureLayout` classes to ensure consistent layout
|
|
168
|
+
calculations.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
--------------------
|
|
172
|
+
ax : matplotlib.axes.Axes
|
|
173
|
+
The target `Axes` object for which to manage the
|
|
174
|
+
|
|
175
|
+
Attributes
|
|
176
|
+
--------------------
|
|
177
|
+
ax : matplotlib.axes.Axes
|
|
178
|
+
The target `Axes` object for which to manage the layout.
|
|
179
|
+
fig_size : numpy.ndarray
|
|
180
|
+
The size of the figure in inches as a NumPy array.
|
|
181
|
+
|
|
182
|
+
Methods
|
|
183
|
+
--------------------
|
|
184
|
+
get_axis_position()
|
|
185
|
+
Returns the position of the axis in normalized figure coordinates.
|
|
186
|
+
get_axis_size()
|
|
187
|
+
Returns the size of the axis in normalized figure coordinates.
|
|
188
|
+
get_axis_position_inches()
|
|
189
|
+
Returns the position of the axis in physical units (inches).
|
|
190
|
+
get_axis_size_inches()
|
|
191
|
+
Returns the size of the axis in physical units (inches).
|
|
192
|
+
|
|
193
|
+
Examples
|
|
194
|
+
--------------------
|
|
195
|
+
>>> fig, ax = plt.subplots()
|
|
196
|
+
>>> layout = AxisLayout(ax)
|
|
197
|
+
>>> position = layout.get_axis_position()
|
|
198
|
+
>>> size = layout.get_axis_size()
|
|
199
|
+
>>> position_inches = layout.get_axis_position_inches()
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
def __init__(self, ax: Axes) -> None:
|
|
203
|
+
self.ax: Axes = ax
|
|
204
|
+
self.fig_size: NDArray[Any] = FigureLayout().get_figure_size()
|
|
205
|
+
|
|
206
|
+
def get_axis_position(self) -> Bbox:
|
|
207
|
+
"""
|
|
208
|
+
Retrieves the position of the axis in normalized figure coordinates.
|
|
209
|
+
|
|
210
|
+
Returns
|
|
211
|
+
--------------------
|
|
212
|
+
matplotlib.transforms.Bbox
|
|
213
|
+
The position of the axis as a bounding box in normalized coordinates.
|
|
214
|
+
|
|
215
|
+
Examples
|
|
216
|
+
--------------------
|
|
217
|
+
>>> layout = AxisLayout(axis_index=0)
|
|
218
|
+
>>> position = layout.get_axis_position()
|
|
219
|
+
>>> print(position)
|
|
220
|
+
Bbox(x0=0.1, y0=0.1, x1=0.9, y1=0.9)
|
|
221
|
+
"""
|
|
222
|
+
axis_position = self.ax.get_position()
|
|
223
|
+
return axis_position
|
|
224
|
+
|
|
225
|
+
def get_axis_size(self) -> NDArray[Any]:
|
|
226
|
+
"""
|
|
227
|
+
Retrieves the size of the axis in normalized figure coordinates.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
--------------------
|
|
231
|
+
numpy.ndarray
|
|
232
|
+
The width and height of the axis as a NumPy array.
|
|
233
|
+
|
|
234
|
+
Examples
|
|
235
|
+
--------------------
|
|
236
|
+
>>> layout = AxisLayout(axis_index=0)
|
|
237
|
+
>>> size = layout.get_axis_size()
|
|
238
|
+
>>> print(size)
|
|
239
|
+
array([0.8, 0.8])
|
|
240
|
+
"""
|
|
241
|
+
axis_position_size = np.array(self.get_axis_position().size)
|
|
242
|
+
return axis_position_size
|
|
243
|
+
|
|
244
|
+
def get_axis_position_inches(self) -> Bbox:
|
|
245
|
+
"""
|
|
246
|
+
Retrieves the position of the axis in physical units (inches).
|
|
247
|
+
|
|
248
|
+
Returns
|
|
249
|
+
--------------------
|
|
250
|
+
matplotlib.transforms.Bbox
|
|
251
|
+
The position of the axis as a bounding box in inches.
|
|
252
|
+
|
|
253
|
+
Examples
|
|
254
|
+
--------------------
|
|
255
|
+
>>> layout = AxisLayout(axis_index=0)
|
|
256
|
+
>>> position_inches = layout.get_axis_position_inches()
|
|
257
|
+
>>> print(position_inches)
|
|
258
|
+
Bbox(x0=1.6, y0=1.6, x1=14.4, y1=14.4)
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
axis_position = self.get_axis_position()
|
|
262
|
+
|
|
263
|
+
axis_position_inches = Bbox.from_bounds(
|
|
264
|
+
axis_position.x0 * self.fig_size[0],
|
|
265
|
+
axis_position.y0 * self.fig_size[1],
|
|
266
|
+
axis_position.width * self.fig_size[0],
|
|
267
|
+
axis_position.height * self.fig_size[1],
|
|
268
|
+
)
|
|
269
|
+
return axis_position_inches
|
|
270
|
+
|
|
271
|
+
def get_axis_size_inches(self) -> NDArray[Any]:
|
|
272
|
+
"""
|
|
273
|
+
Retrieves the size of the axis in physical units (inches).
|
|
274
|
+
|
|
275
|
+
Returns
|
|
276
|
+
--------------------
|
|
277
|
+
numpy.ndarray
|
|
278
|
+
The width and height of the axis in inches as a NumPy array.
|
|
279
|
+
|
|
280
|
+
Examples
|
|
281
|
+
--------------------
|
|
282
|
+
>>> layout = AxisLayout(axis_index=0)
|
|
283
|
+
>>> size_inches = layout.get_axis_size_inches()
|
|
284
|
+
>>> print(size_inches)
|
|
285
|
+
array([12.8, 12.8])
|
|
286
|
+
"""
|
|
287
|
+
axis_position_size_inches = np.array(self.get_axis_position_inches().size)
|
|
288
|
+
return axis_position_size_inches
|