colormap-complex 0.1.2__tar.gz → 0.2.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.
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/PKG-INFO +3 -3
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/README.md +1 -1
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/pyproject.toml +9 -3
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex/__init__.py +1 -1
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex/_main.py +47 -16
- colormap_complex-0.2.0/src/colormap_complex/data/bremm.npy +0 -0
- colormap_complex-0.2.0/src/colormap_complex/data/cubediagonal.npy +0 -0
- colormap_complex-0.2.0/src/colormap_complex/data/schumann.npy +0 -0
- colormap_complex-0.2.0/src/colormap_complex/data/steiger.npy +0 -0
- colormap_complex-0.2.0/src/colormap_complex/data/teulingfig2.npy +0 -0
- colormap_complex-0.2.0/src/colormap_complex/data/ziegler.npy +0 -0
- colormap_complex-0.2.0/src/colormap_complex/matplotlib.py +69 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/PKG-INFO +3 -3
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/SOURCES.txt +7 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/tests/test_main.py +9 -17
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/LICENSE +0 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/setup.cfg +0 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/setup.py +0 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex/py.typed +0 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/dependency_links.txt +0 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/requires.txt +0 -0
- {colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: colormap-complex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Complex / 2d colormap / Domain coloring for matplotlib etc.
|
|
5
5
|
Author-email: 34j <34j.95a2p@simplelogin.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
Requires-Dist: colour-science>=0.4.4
|
|
@@ -84,7 +84,7 @@ import numpy as np
|
|
|
84
84
|
lin = np.linspace(-1, 1, 100)
|
|
85
85
|
x, y = np.meshgrid(lin, lin)
|
|
86
86
|
z = x + 1j * y
|
|
87
|
-
c = colormap(type="oklab"
|
|
87
|
+
c = colormap(type="oklab")(z.real, z.imag, scale=True)
|
|
88
88
|
plt.imshow(c, extent=(-1, 1, -1, 1), origin='lower')
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -57,7 +57,7 @@ import numpy as np
|
|
|
57
57
|
lin = np.linspace(-1, 1, 100)
|
|
58
58
|
x, y = np.meshgrid(lin, lin)
|
|
59
59
|
z = x + 1j * y
|
|
60
|
-
c = colormap(type="oklab"
|
|
60
|
+
c = colormap(type="oklab")(z.real, z.imag, scale=True)
|
|
61
61
|
plt.imshow(c, extent=(-1, 1, -1, 1), origin='lower')
|
|
62
62
|
```
|
|
63
63
|
|
|
@@ -4,14 +4,14 @@ requires = [ "setuptools" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "colormap-complex"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Complex / 2d colormap / Domain coloring for matplotlib etc."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "34j", email = "34j.95a2p@simplelogin.com" },
|
|
13
13
|
]
|
|
14
|
-
requires-python = ">=3.
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Development Status :: 2 - Pre-Alpha",
|
|
17
17
|
"Intended Audience :: Developers",
|
|
@@ -38,7 +38,7 @@ urls.repository = "https://github.com/34j/colormap-complex"
|
|
|
38
38
|
dev = [
|
|
39
39
|
"pytest>=8,<9",
|
|
40
40
|
"pytest-cov>=6,<7",
|
|
41
|
-
"matplotlib>=3.
|
|
41
|
+
"matplotlib>=3.10.1",
|
|
42
42
|
"scipy>=1.13.1",
|
|
43
43
|
"python-slugify>=8.0.4",
|
|
44
44
|
]
|
|
@@ -49,6 +49,12 @@ docs = [
|
|
|
49
49
|
"sphinx-autobuild>=2024,<2025; python_version>='3.11'",
|
|
50
50
|
]
|
|
51
51
|
|
|
52
|
+
[tool.setuptools.packages.find]
|
|
53
|
+
where = ["src"]
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.package-data]
|
|
56
|
+
colormap_complex = ["**/*.npy"]
|
|
57
|
+
|
|
52
58
|
[tool.ruff]
|
|
53
59
|
line-length = 100
|
|
54
60
|
lint.select = [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, Literal, Protocol, TypeVar
|
|
3
3
|
|
|
4
4
|
import colour
|
|
5
5
|
import numpy as np
|
|
@@ -70,6 +70,42 @@ def interpnd(base: NDArray[TBase], *indices: NDArray[np.number]) -> NDArray[TBas
|
|
|
70
70
|
return base[indices_0] * (1 - indices_p) + base[indices_1] * indices_p
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
class Colormap(Protocol):
|
|
74
|
+
"""Colormap protocol."""
|
|
75
|
+
|
|
76
|
+
__name__: str
|
|
77
|
+
|
|
78
|
+
def __call__(
|
|
79
|
+
self,
|
|
80
|
+
x: NDArray[np.number],
|
|
81
|
+
y: NDArray[np.number],
|
|
82
|
+
/,
|
|
83
|
+
*,
|
|
84
|
+
scale: bool = False,
|
|
85
|
+
) -> NDArray[np.number]:
|
|
86
|
+
"""
|
|
87
|
+
Colormap function.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
x : NDArray[np.number]
|
|
92
|
+
Array of shape (...,)
|
|
93
|
+
y : NDArray[np.number]
|
|
94
|
+
Array of shape (...,)
|
|
95
|
+
scale : bool
|
|
96
|
+
Whether to scale the input to the range [0, 1].
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
NDArray[np.number]
|
|
101
|
+
Colormap of shape (..., 3).
|
|
102
|
+
The colormap is in the range [0, 1].
|
|
103
|
+
If colormap is cyclic, x axis corresponds to the cyclic
|
|
104
|
+
dimension.
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
|
|
73
109
|
def colormap(
|
|
74
110
|
*,
|
|
75
111
|
type: Literal[
|
|
@@ -87,36 +123,26 @@ def colormap(
|
|
|
87
123
|
"ziegler",
|
|
88
124
|
] = "bremm",
|
|
89
125
|
cut_outbound: bool = True,
|
|
90
|
-
scale: bool = True,
|
|
91
126
|
clip: bool = True,
|
|
92
|
-
) ->
|
|
127
|
+
) -> Colormap:
|
|
93
128
|
"""
|
|
94
129
|
2D colormap function.
|
|
95
130
|
|
|
96
131
|
Parameters
|
|
97
132
|
----------
|
|
98
|
-
x : NDArray[np.number]
|
|
99
|
-
Array of shape (...,)
|
|
100
|
-
y : NDArray[np.number]
|
|
101
|
-
Array of shape (...,)
|
|
102
133
|
type : Literal['oklab', 'oklch', 'prolab', 'prolch', 'hsv', 'ycbcr',
|
|
103
134
|
'bremm', 'cubediagonal', 'schumann', 'steiger', 'teulingfig2', 'ziegler']
|
|
104
135
|
Type of colormap.
|
|
105
136
|
cut_outbound : bool
|
|
106
137
|
If using CIE XYZ, cut colors that are out of bounds
|
|
107
138
|
for the sRGB color space.
|
|
108
|
-
scale : bool
|
|
109
|
-
Whether to scale the input to the range [0, 1].
|
|
110
139
|
clip : bool
|
|
111
140
|
Whether to clip the output to the range [0, 1].
|
|
112
141
|
|
|
113
142
|
Returns
|
|
114
143
|
-------
|
|
115
|
-
|
|
116
|
-
Colormap
|
|
117
|
-
The colormap is in the range [0, 1].
|
|
118
|
-
If colormap is cyclic, x axis corresponds to the cyclic
|
|
119
|
-
dimension.
|
|
144
|
+
Colrmap
|
|
145
|
+
Colormap function.
|
|
120
146
|
|
|
121
147
|
"""
|
|
122
148
|
if type not in ALL_COLORMAPS:
|
|
@@ -124,10 +150,13 @@ def colormap(
|
|
|
124
150
|
if type in _CACHED_COLORMAPS:
|
|
125
151
|
file = Path(__file__).parent / "data" / f"{type}.npy"
|
|
126
152
|
if not file.exists():
|
|
127
|
-
raise
|
|
153
|
+
raise FileNotFoundError("Colormap file not found.")
|
|
128
154
|
colormap = np.load(file) / 255
|
|
155
|
+
# 512 x 512 x 3
|
|
129
156
|
|
|
130
|
-
def inner(
|
|
157
|
+
def inner(
|
|
158
|
+
x: NDArray[np.number], y: NDArray[np.number], /, *, scale: bool = False
|
|
159
|
+
) -> NDArray[np.number]:
|
|
131
160
|
if scale:
|
|
132
161
|
xmin = np.min(x)
|
|
133
162
|
xmax = np.max(x)
|
|
@@ -194,4 +223,6 @@ def colormap(
|
|
|
194
223
|
srgb = np.clip(srgb, 0, 1)
|
|
195
224
|
return srgb
|
|
196
225
|
|
|
226
|
+
inner.__name__ = type
|
|
227
|
+
inner.__doc__ = f"Colormap function of type {type}."
|
|
197
228
|
return inner
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from matplotlib.colors import BivarColormapFromImage, ListedColormap
|
|
7
|
+
|
|
8
|
+
from ._main import Colormap
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_mpl_colormap(colormap: Colormap, /, N: int = 128, M: int = 128) -> BivarColormapFromImage:
|
|
12
|
+
"""
|
|
13
|
+
Get a matplotlib colormap from a function.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
colormap : Colormap
|
|
18
|
+
The colormap function to use.
|
|
19
|
+
N : int
|
|
20
|
+
The number of colors in the x axis.
|
|
21
|
+
M : int
|
|
22
|
+
The number of colors in the y axis.
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
BivarColormapFromImage
|
|
27
|
+
Matplotlib colormap.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
return BivarColormapFromImage(
|
|
31
|
+
colormap(np.linspace(0, 1, N)[:, None], np.linspace(0, 1, M)[None, :]),
|
|
32
|
+
name=colormap.__name__,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_mpl_1d_colormap(
|
|
37
|
+
colormap: Colormap,
|
|
38
|
+
v: float,
|
|
39
|
+
/,
|
|
40
|
+
axis: Literal[0, 1] = 0,
|
|
41
|
+
N: int = 128,
|
|
42
|
+
) -> ListedColormap:
|
|
43
|
+
"""
|
|
44
|
+
Get a matplotlib colormap from a function.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
colormap : Callable[[NDArray[np.number]], NDArray[np.number]]
|
|
49
|
+
The colormap function to use.
|
|
50
|
+
v : float
|
|
51
|
+
The value to use for the colormap.
|
|
52
|
+
axis : Literal[0, 1]
|
|
53
|
+
The axis to take the colormap from.
|
|
54
|
+
N : int
|
|
55
|
+
The number of colors in the colormap.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
BivarColormapFromImage
|
|
60
|
+
Matplotlib colormap.
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
if axis == 0:
|
|
64
|
+
x = np.linspace(0, 1, N)
|
|
65
|
+
y = np.full_like(x, v)
|
|
66
|
+
else:
|
|
67
|
+
y = np.linspace(0, 1, N)
|
|
68
|
+
x = np.full_like(y, v)
|
|
69
|
+
return ListedColormap(colormap(x, y), name=colormap.__name__)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: colormap-complex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Complex / 2d colormap / Domain coloring for matplotlib etc.
|
|
5
5
|
Author-email: 34j <34j.95a2p@simplelogin.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
Requires-Dist: colour-science>=0.4.4
|
|
@@ -84,7 +84,7 @@ import numpy as np
|
|
|
84
84
|
lin = np.linspace(-1, 1, 100)
|
|
85
85
|
x, y = np.meshgrid(lin, lin)
|
|
86
86
|
z = x + 1j * y
|
|
87
|
-
c = colormap(type="oklab"
|
|
87
|
+
c = colormap(type="oklab")(z.real, z.imag, scale=True)
|
|
88
88
|
plt.imshow(c, extent=(-1, 1, -1, 1), origin='lower')
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -4,10 +4,17 @@ pyproject.toml
|
|
|
4
4
|
setup.py
|
|
5
5
|
src/colormap_complex/__init__.py
|
|
6
6
|
src/colormap_complex/_main.py
|
|
7
|
+
src/colormap_complex/matplotlib.py
|
|
7
8
|
src/colormap_complex/py.typed
|
|
8
9
|
src/colormap_complex.egg-info/PKG-INFO
|
|
9
10
|
src/colormap_complex.egg-info/SOURCES.txt
|
|
10
11
|
src/colormap_complex.egg-info/dependency_links.txt
|
|
11
12
|
src/colormap_complex.egg-info/requires.txt
|
|
12
13
|
src/colormap_complex.egg-info/top_level.txt
|
|
14
|
+
src/colormap_complex/data/bremm.npy
|
|
15
|
+
src/colormap_complex/data/cubediagonal.npy
|
|
16
|
+
src/colormap_complex/data/schumann.npy
|
|
17
|
+
src/colormap_complex/data/steiger.npy
|
|
18
|
+
src/colormap_complex/data/teulingfig2.npy
|
|
19
|
+
src/colormap_complex/data/ziegler.npy
|
|
13
20
|
tests/test_main.py
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
1
2
|
from os import environ
|
|
2
3
|
from pathlib import Path
|
|
3
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
import matplotlib.pyplot as plt
|
|
6
7
|
import numpy as np
|
|
7
8
|
import pytest
|
|
8
9
|
from matplotlib.cm import ScalarMappable
|
|
9
|
-
from matplotlib.colors import
|
|
10
|
+
from matplotlib.colors import Normalize
|
|
10
11
|
from scipy.special import (
|
|
11
12
|
airy,
|
|
12
13
|
digamma,
|
|
@@ -23,6 +24,7 @@ from scipy.special import (
|
|
|
23
24
|
from slugify import slugify
|
|
24
25
|
|
|
25
26
|
from colormap_complex import ALL_COLORMAPS, ColormapType, colormap
|
|
27
|
+
from colormap_complex.matplotlib import get_mpl_1d_colormap
|
|
26
28
|
|
|
27
29
|
CI = environ.get("CI", "false").lower() == "true"
|
|
28
30
|
CACHE_PATH = Path(__file__).parent / ".cache"
|
|
@@ -117,17 +119,12 @@ def test_complex_function(
|
|
|
117
119
|
angle = np.angle(z)
|
|
118
120
|
if magnitude_growth:
|
|
119
121
|
r = np.fmod(np.log(r), 1)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
r,
|
|
123
|
-
)
|
|
122
|
+
cmap = colormap(type="oklch")
|
|
123
|
+
c = cmap(angle / (2 * np.pi), r, scale=True)
|
|
124
124
|
ax[2].set_title("f(z) (oklch)")
|
|
125
125
|
cba = fig.colorbar(
|
|
126
126
|
ScalarMappable(
|
|
127
|
-
norm=Normalize(angle.min(), angle.max()),
|
|
128
|
-
cmap=ListedColormap(
|
|
129
|
-
colormap(type="oklch", scale=False)(np.linspace(0, 1, 256), np.array(0.5))
|
|
130
|
-
),
|
|
127
|
+
norm=Normalize(angle.min(), angle.max()), cmap=get_mpl_1d_colormap(cmap, 0.5)
|
|
131
128
|
),
|
|
132
129
|
ax=ax[2],
|
|
133
130
|
)
|
|
@@ -136,12 +133,7 @@ def test_complex_function(
|
|
|
136
133
|
cbr = fig.colorbar(
|
|
137
134
|
ScalarMappable(
|
|
138
135
|
norm=Normalize(0, 1) if magnitude_growth else Normalize(np.min(r), np.max(r)),
|
|
139
|
-
cmap=
|
|
140
|
-
colormap(type="oklch", scale=False)(
|
|
141
|
-
np.array(0.5),
|
|
142
|
-
np.linspace(0, 1, 256),
|
|
143
|
-
)
|
|
144
|
-
),
|
|
136
|
+
cmap=get_mpl_1d_colormap(cmap, 0.5, axis=1),
|
|
145
137
|
),
|
|
146
138
|
ax=ax[2],
|
|
147
139
|
)
|
|
@@ -149,7 +141,7 @@ def test_complex_function(
|
|
|
149
141
|
cbr.set_ticks([0, 0.5, 1])
|
|
150
142
|
cbr.set_ticklabels([r"$1$", r"$e^{\frac{1}{2}}$", r"$e$"])
|
|
151
143
|
else:
|
|
152
|
-
c = colormap(type="oklab")(z.real, z.imag)
|
|
144
|
+
c = colormap(type="oklab")(z.real, z.imag, scale=True)
|
|
153
145
|
ax[2].set_title("f(z) (oklab)")
|
|
154
146
|
ax[2].imshow(c, extent=(-1, 1, -1, 1), origin="lower")
|
|
155
147
|
for ax_ in ax:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/requires.txt
RENAMED
|
File without changes
|
{colormap_complex-0.1.2 → colormap_complex-0.2.0}/src/colormap_complex.egg-info/top_level.txt
RENAMED
|
File without changes
|