matplotlib-multicolored-line 0.2.0__tar.gz → 0.3.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.
Files changed (16) hide show
  1. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/PKG-INFO +1 -1
  2. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/pyproject.toml +1 -1
  3. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line/__init__.py +1 -1
  4. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line/_main.py +37 -9
  5. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line.egg-info/PKG-INFO +1 -1
  6. matplotlib_multicolored_line-0.3.0/tests/test_main.py +114 -0
  7. matplotlib_multicolored_line-0.2.0/tests/test_main.py +0 -47
  8. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/LICENSE +0 -0
  9. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/README.md +0 -0
  10. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/setup.cfg +0 -0
  11. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/setup.py +0 -0
  12. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line/py.typed +0 -0
  13. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line.egg-info/SOURCES.txt +0 -0
  14. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line.egg-info/dependency_links.txt +0 -0
  15. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line.egg-info/requires.txt +0 -0
  16. {matplotlib_multicolored_line-0.2.0 → matplotlib_multicolored_line-0.3.0}/src/matplotlib_multicolored_line.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matplotlib-multicolored-line
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Plot multicolored lines in Matplotlib
5
5
  Author-email: 34j <34j.95a2p@simplelogin.com>
6
6
  License-Expression: CC0-1.0
@@ -4,7 +4,7 @@ requires = [ "setuptools" ]
4
4
 
5
5
  [project]
6
6
  name = "matplotlib-multicolored-line"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Plot multicolored lines in Matplotlib"
9
9
  readme = "README.md"
10
10
  license = "CC0-1.0"
@@ -1,4 +1,4 @@
1
- __version__ = "0.2.0"
1
+ __version__ = "0.3.0"
2
2
  from ._main import colored_line
3
3
 
4
4
  __all__ = ["colored_line"]
@@ -31,8 +31,13 @@ def colored_line(
31
31
  *args : array-like
32
32
  The horizontal and vertical coordinates of the data points
33
33
  of shape (N,) or (N, m).
34
- c : array-like
35
- The color values, which should be the same size as x and y.
34
+ c : array-like or array-like of color, optional
35
+ The line values. Possible values:
36
+ - array-like of numbers of shape (N,) or (N, m) to be mapped
37
+ to colors using cmap and norm.
38
+ - array-like of numbers of shape (N, m, 3) or (N, m, 4),
39
+ where the last dimension is RGB or RGBA.
40
+ - array-like of colors of shape (N,) or (N, m).
36
41
  ax : matplotlib.axes.Axes, optional
37
42
  The axes to plot on. If not provided, the current axes will be used.
38
43
  start : array-like, optional
@@ -52,12 +57,13 @@ def colored_line(
52
57
  The generated line collection representing the colored line.
53
58
 
54
59
  """
55
- if "array" in kwargs:
56
- warnings.warn(
57
- 'The provided "array" keyword argument will be overridden',
58
- UserWarning,
59
- stacklevel=2,
60
- )
60
+ for key in ["array", "colors"]:
61
+ if key in kwargs:
62
+ warnings.warn(
63
+ f'The provided "{key}" keyword argument will be overridden',
64
+ UserWarning,
65
+ stacklevel=2,
66
+ )
61
67
 
62
68
  # parse args
63
69
  if len(args) == 1:
@@ -72,10 +78,33 @@ def colored_line(
72
78
  x, y, c = map(np.asarray, (x, y, c))
73
79
  if x.ndim == 1:
74
80
  x = x[:, None]
81
+ elif x.ndim == 2:
82
+ pass
83
+ else:
84
+ raise ValueError(f"{x.ndim=} should be 1 or 2")
75
85
  if y.ndim == 1:
76
86
  y = y[:, None]
87
+ elif y.ndim == 2:
88
+ pass
89
+ else:
90
+ raise ValueError(f"{y.ndim=} should be 1 or 2")
77
91
  x, y = np.broadcast_arrays(x, y)
78
92
 
93
+ if c.ndim == 1:
94
+ c = c[:, None]
95
+ if c.ndim == 2:
96
+ c = np.broadcast_to(c, x.shape).reshape((-1,))
97
+ if np.issubdtype(c.dtype, np.number):
98
+ kwargs["array"] = c
99
+ else:
100
+ kwargs["colors"] = c
101
+ elif c.ndim == 3:
102
+ c = np.broadcast_to(c, (*x.shape, c.shape[-1])).reshape((-1, c.shape[-1]))
103
+ c = [tuple(c[i]) for i in range(c.shape[0])]
104
+ kwargs["colors"] = c
105
+ else:
106
+ raise ValueError(f"{c.ndim=} should be 2 or 3")
107
+
79
108
  # (N, m, 2)
80
109
  xy = np.stack((x, y), axis=-1)
81
110
  # (N, m, 2)
@@ -88,7 +117,6 @@ def colored_line(
88
117
  segments = np.stack((xy_start, xy, xy_end), axis=-2)
89
118
  segments = np.reshape(segments, (-1, segments.shape[-2], segments.shape[-1]))
90
119
 
91
- kwargs["array"] = c.reshape(-1)
92
120
  lc = LineCollection(segments, **kwargs)
93
121
 
94
122
  # Plot the line collection to the axes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matplotlib-multicolored-line
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Plot multicolored lines in Matplotlib
5
5
  Author-email: 34j <34j.95a2p@simplelogin.com>
6
6
  License-Expression: CC0-1.0
@@ -0,0 +1,114 @@
1
+ from collections.abc import Sequence
2
+ from pathlib import Path
3
+
4
+ import matplotlib.pyplot as plt
5
+ import numpy as np
6
+ import pytest
7
+ from numpy.typing import ArrayLike
8
+
9
+ from matplotlib_multicolored_line import colored_line
10
+
11
+ CACHE_PATH = Path(__file__).parent / ".cache"
12
+
13
+
14
+ @pytest.fixture(autouse=True)
15
+ def setup_cache() -> None:
16
+ CACHE_PATH.mkdir(parents=True, exist_ok=True)
17
+
18
+
19
+ t = np.linspace(-7.4, -0.5, 200)
20
+
21
+
22
+ @pytest.mark.parametrize(
23
+ "name, args, c",
24
+ [
25
+ ("notebook1", (0.9 * np.sin(t), 0.5 * np.sin(t)), t),
26
+ ("notebook2", ([0, 1, 2, 3, 4], [0, 1, 2, 1, 1]), [1, 2, 3, 4, 5]),
27
+ ("singley", (np.random.normal(size=(5,)),), np.random.normal(size=(5,))),
28
+ ("singley.rgb", (np.random.normal(size=(5,)),), np.random.normal(size=(5, 1, 3))),
29
+ ("singley.rgba", (np.random.normal(size=(5,)),), np.random.normal(size=(5, 1, 4))),
30
+ (
31
+ "singley.colors",
32
+ (np.random.normal(size=(5,)),),
33
+ np.random.choice(["black", "red"], size=(5,)),
34
+ ),
35
+ (
36
+ "singlexy",
37
+ (
38
+ np.random.normal(size=(5,)),
39
+ np.random.normal(size=(5,)),
40
+ ),
41
+ np.random.normal(size=(5,)),
42
+ ),
43
+ (
44
+ "singlexy.rgb",
45
+ (
46
+ np.random.normal(size=(5,)),
47
+ np.random.normal(size=(5,)),
48
+ ),
49
+ np.random.normal(size=(5, 1, 3)),
50
+ ),
51
+ (
52
+ "singlexy.rgba",
53
+ (
54
+ np.random.normal(size=(5,)),
55
+ np.random.normal(size=(5,)),
56
+ ),
57
+ np.random.normal(size=(5, 1, 4)),
58
+ ),
59
+ (
60
+ "singlexy.colors",
61
+ (
62
+ np.random.normal(size=(5,)),
63
+ np.random.normal(size=(5,)),
64
+ ),
65
+ np.random.choice(["black", "red"], size=(5,)),
66
+ ),
67
+ ("multiy", (np.random.normal(size=(5, 2)),), np.random.normal(size=(5, 2))),
68
+ ("multiy.rgb", (np.random.normal(size=(5, 2)),), np.random.uniform(size=(5, 2, 3))),
69
+ ("multiy.rgba", (np.random.normal(size=(5, 2)),), np.random.uniform(size=(5, 2, 4))),
70
+ (
71
+ "multiy.colors",
72
+ (np.random.normal(size=(5, 2)),),
73
+ np.random.choice(["black", "red"], size=(5, 2)),
74
+ ),
75
+ (
76
+ "multixy",
77
+ (
78
+ np.random.normal(size=(5, 2)),
79
+ np.random.normal(size=(5, 2)),
80
+ ),
81
+ np.random.normal(size=(5, 2)),
82
+ ),
83
+ (
84
+ "multixy.rgb",
85
+ (
86
+ np.random.normal(size=(5, 2)),
87
+ np.random.normal(size=(5, 2)),
88
+ ),
89
+ np.random.uniform(size=(5, 2, 3)),
90
+ ),
91
+ (
92
+ "multixy.rgba",
93
+ (
94
+ np.random.normal(size=(5, 2)),
95
+ np.random.normal(size=(5, 2)),
96
+ ),
97
+ np.random.uniform(size=(5, 2, 4)),
98
+ ),
99
+ (
100
+ "multixy.colors",
101
+ (
102
+ np.random.normal(size=(5, 2)),
103
+ np.random.normal(size=(5, 2)),
104
+ ),
105
+ np.random.choice(["black", "red"], size=(5, 2)),
106
+ ),
107
+ ],
108
+ )
109
+ def test_multicolor(name: str, args: Sequence[ArrayLike], c: ArrayLike) -> None:
110
+ fig, ax = plt.subplots()
111
+ lc = colored_line(*args, c=c, ax=ax, linewidth=10)
112
+ if "rgb" not in name:
113
+ fig.colorbar(lc)
114
+ fig.savefig(CACHE_PATH / f"example.{name}.jpg")
@@ -1,47 +0,0 @@
1
- from pathlib import Path
2
-
3
- import matplotlib.pyplot as plt
4
- import numpy as np
5
- import pytest
6
-
7
- from matplotlib_multicolored_line import colored_line
8
-
9
- CACHE_PATH = Path(__file__).parent / ".cache"
10
-
11
-
12
- @pytest.fixture(autouse=True)
13
- def setup_cache() -> None:
14
- CACHE_PATH.mkdir(parents=True, exist_ok=True)
15
-
16
-
17
- def test_main() -> None:
18
- t = np.linspace(-7.4, -0.5, 200)
19
- x = 0.9 * np.sin(t)
20
- y = 0.9 * np.cos(1.6 * t)
21
-
22
- fig, ax = plt.subplots()
23
- lc = colored_line(x, y, c=t, ax=ax, linewidth=10)
24
- fig.colorbar(lc)
25
- fig.savefig(CACHE_PATH / "example.jpg")
26
-
27
-
28
- def test_main_small() -> None:
29
- x = [0, 1, 2, 3, 4]
30
- y = [0, 1, 2, 1, 1]
31
- c = [1, 2, 3, 4, 5]
32
-
33
- fig, ax = plt.subplots()
34
- lc = colored_line(x, y, c=c, ax=ax, linewidth=10)
35
- fig.colorbar(lc)
36
- fig.savefig(CACHE_PATH / "example_small.jpg")
37
-
38
-
39
- def test_multiple() -> None:
40
- np.random.seed(0)
41
- y = np.random.normal(size=(5, 2))
42
- c = np.random.normal(size=(5, 2))
43
-
44
- fig, ax = plt.subplots()
45
- lc = colored_line(y, c=c, ax=ax, linewidth=10)
46
- fig.colorbar(lc)
47
- fig.savefig(CACHE_PATH / "example_multiple.jpg")