eulumdat-plot 1.0.1__tar.gz → 1.0.3__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 123VincentB
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eulumdat-plot
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: Photometric polar diagram generator for EULUMDAT (.ldt) files — extension to eulumdat-py
5
5
  Author: 123VincentB
6
6
  License: MIT
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Requires-Python: >=3.9
23
23
  Description-Content-Type: text/markdown
24
+ License-File: LICENSE
24
25
  Requires-Dist: eulumdat-py>=1.0.0
25
26
  Requires-Dist: numpy>=1.21
26
27
  Requires-Dist: svgwrite>=1.4
@@ -37,12 +38,13 @@ Requires-Dist: build; extra == "dev"
37
38
  Requires-Dist: twine; extra == "dev"
38
39
  Requires-Dist: pytest>=7.0; extra == "dev"
39
40
  Requires-Dist: eulumdat-plot[full]; extra == "dev"
41
+ Dynamic: license-file
40
42
 
41
43
  # eulumdat-plot
42
44
 
43
45
  [![PyPI](https://img.shields.io/pypi/v/eulumdat-plot)](https://pypi.org/project/eulumdat-plot/)
44
46
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eulumdat-plot)](https://pypi.org/project/eulumdat-plot/)
45
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/123VincentB/eulumdat-plot/blob/main/LICENSE)
47
+ [![License: MIT](https://img.shields.io/github/license/123VincentB/eulumdat-plot)](https://github.com/123VincentB/eulumdat-plot/blob/main/LICENSE)
46
48
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19096110.svg)](https://doi.org/10.5281/zenodo.19096110)
47
49
 
48
50
  Photometric polar diagram generator for EULUMDAT (`.ldt`) files —
@@ -61,7 +63,7 @@ on top of [`eulumdat-py`](https://pypi.org/project/eulumdat-py/).
61
63
 
62
64
  ---
63
65
 
64
- ![Photometric diagram example](https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_01.png) ![Photometric diagram example](https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_02.png)
66
+ <img src="https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_01.png" width="360"> <img src="https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_02.png" width="360">
65
67
 
66
68
  ---
67
69
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![PyPI](https://img.shields.io/pypi/v/eulumdat-plot)](https://pypi.org/project/eulumdat-plot/)
4
4
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eulumdat-plot)](https://pypi.org/project/eulumdat-plot/)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/123VincentB/eulumdat-plot/blob/main/LICENSE)
5
+ [![License: MIT](https://img.shields.io/github/license/123VincentB/eulumdat-plot)](https://github.com/123VincentB/eulumdat-plot/blob/main/LICENSE)
6
6
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19096110.svg)](https://doi.org/10.5281/zenodo.19096110)
7
7
 
8
8
  Photometric polar diagram generator for EULUMDAT (`.ldt`) files —
@@ -21,7 +21,7 @@ on top of [`eulumdat-py`](https://pypi.org/project/eulumdat-py/).
21
21
 
22
22
  ---
23
23
 
24
- ![Photometric diagram example](https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_01.png) ![Photometric diagram example](https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_02.png)
24
+ <img src="https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_01.png" width="360"> <img src="https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_02.png" width="360">
25
25
 
26
26
  ---
27
27
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "eulumdat-plot"
7
- version = "1.0.1"
7
+ version = "1.0.3"
8
8
  description = "Photometric polar diagram generator for EULUMDAT (.ldt) files — extension to eulumdat-py"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -39,12 +39,14 @@ Public API
39
39
  Convert polar ``(r, θ)`` to NAT ``(x, y)`` Cartesian coordinates.
40
40
  """
41
41
 
42
- from .plot import plot_ldt
43
- from .renderer import Layout, make_svg, polar_to_nat
42
+ from .plot import plot_ldt, plot_ldt_svg
43
+ from .renderer import Layout, make_svg, make_svg_str, polar_to_nat
44
44
 
45
45
  __all__ = [
46
46
  "plot_ldt",
47
+ "plot_ldt_svg",
47
48
  "Layout",
48
49
  "make_svg",
50
+ "make_svg_str",
49
51
  "polar_to_nat",
50
52
  ]
@@ -52,7 +52,7 @@ try:
52
52
  except ImportError:
53
53
  _HAS_SCIPY = False
54
54
 
55
- from .renderer import Layout, NatCurve, make_svg, polar_to_nat
55
+ from .renderer import Layout, NatCurve, make_svg, make_svg_str, polar_to_nat
56
56
 
57
57
 
58
58
  # ---------------------------------------------------------------------------
@@ -363,3 +363,83 @@ def plot_ldt(
363
363
  strokes_solid=strokes_solid,
364
364
  strokes_dotted=strokes_dotted,
365
365
  )
366
+
367
+
368
+ def plot_ldt_svg(
369
+ ldt_path: str | Path,
370
+ *,
371
+ code: str = "",
372
+ layout: Optional[Layout] = None,
373
+ interpolate: bool = True,
374
+ interp_step_deg: float = 1.0,
375
+ interp_method: str = "linear",
376
+ ) -> str:
377
+ """
378
+ Same as :func:`plot_ldt` but returns the SVG as a string instead of
379
+ writing to disk.
380
+
381
+ Returns
382
+ -------
383
+ str
384
+ SVG document as a string (starts with ``<svg``).
385
+ """
386
+ ldt_path = Path(ldt_path)
387
+ if layout is None:
388
+ layout = Layout()
389
+
390
+ ldt = LdtReader.read(ldt_path)
391
+
392
+ I_C0 = _get_plane(ldt, 0.0)
393
+ I_C90 = _get_plane(ldt, 90.0)
394
+ I_C180 = _get_plane(ldt, 180.0)
395
+ I_C270 = _get_plane(ldt, 270.0)
396
+
397
+ available = [p for p in (I_C0, I_C90, I_C180, I_C270) if p is not None]
398
+ if not available:
399
+ raise ValueError(f"No usable C-plane data found in '{ldt_path}'.")
400
+
401
+ r_data_max = float(np.vstack(available).max())
402
+
403
+ g_deg = np.asarray(ldt.header.g_angles, dtype=float)
404
+ if interpolate and g_deg.size > 1:
405
+ g_deg, (I_C0, I_C90, I_C180, I_C270) = _resample(
406
+ g_deg, I_C0, I_C90, I_C180, I_C270,
407
+ step_deg=interp_step_deg,
408
+ method=interp_method,
409
+ )
410
+
411
+ curves_solid: List[NatCurve] = []
412
+ curves_dotted: List[NatCurve] = []
413
+ colors_solid: List[str] = []
414
+ colors_dotted: List[str] = []
415
+ strokes_solid: List[float] = []
416
+ strokes_dotted: List[float] = []
417
+
418
+ def _register(arr_right, arr_left, *, solid: bool) -> None:
419
+ cr, cl = _build_nat_pair(g_deg, arr_right, arr_left)
420
+ for curve in (cr, cl):
421
+ if curve is None:
422
+ continue
423
+ if solid:
424
+ curves_solid.append(curve)
425
+ colors_solid.append("black")
426
+ strokes_solid.append(layout.stroke_curve_solid)
427
+ else:
428
+ curves_dotted.append(curve)
429
+ colors_dotted.append("black")
430
+ strokes_dotted.append(layout.stroke_curve_dotted)
431
+
432
+ _register(I_C0, I_C180, solid=True)
433
+ _register(I_C90, I_C270, solid=False)
434
+
435
+ return make_svg_str(
436
+ curves_solid=curves_solid,
437
+ curves_dotted=curves_dotted,
438
+ r_data_max=r_data_max,
439
+ code=code,
440
+ layout=layout,
441
+ colors_solid=colors_solid,
442
+ colors_dotted=colors_dotted,
443
+ strokes_solid=strokes_solid,
444
+ strokes_dotted=strokes_dotted,
445
+ )
@@ -257,12 +257,12 @@ def _nice_levels(r_max: float) -> List[int]:
257
257
  # SVG renderer
258
258
  # ---------------------------------------------------------------------------
259
259
 
260
- def make_svg(
260
+ def _build_drawing(
261
261
  curves_solid: List[NatCurve],
262
262
  curves_dotted: List[NatCurve],
263
263
  r_data_max: float,
264
264
  *,
265
- outfile: str | Path = "photometric.svg",
265
+ filename: str = "_",
266
266
  code: str = "",
267
267
  layout: Optional[Layout] = None,
268
268
  debug: bool = False,
@@ -270,42 +270,8 @@ def make_svg(
270
270
  colors_dotted: Optional[List[str]] = None,
271
271
  strokes_solid: Optional[List[float]] = None,
272
272
  strokes_dotted: Optional[List[float]] = None,
273
- ) -> Path:
274
- """
275
- Generate a Lumtopic-style photometric polar diagram as an SVG file.
276
-
277
- Parameters
278
- ----------
279
- curves_solid :
280
- Solid curves (typically C0 / C180), each as a list of
281
- ``(x_nat, y_nat)`` points.
282
- curves_dotted :
283
- Dotted curves (typically C90 / C270), same format.
284
- r_data_max :
285
- Maximum intensity across all curves (cd/klm).
286
- Drives the radial scale computation.
287
- outfile :
288
- Destination SVG path. Default: ``"photometric.svg"``.
289
- code :
290
- Distribution code shown in the banner centre (e.g. ``"D53"``).
291
- Pass an empty string to leave it blank.
292
- layout :
293
- Visual parameters. If ``None``, :class:`Layout` defaults are used.
294
- debug :
295
- If ``True``, draw the plot area in blue and the curve bounding box
296
- in green as diagnostic overlays.
297
- colors_solid / colors_dotted :
298
- Per-curve SVG stroke colours. Defaults to black for all curves.
299
- strokes_solid / strokes_dotted :
300
- Per-curve stroke widths. Defaults to ``layout.stroke_curve_solid``
301
- and ``layout.stroke_curve_dotted`` respectively.
302
-
303
- Returns
304
- -------
305
- :class:`pathlib.Path`
306
- Absolute path to the generated SVG file.
307
- """
308
- outfile = Path(outfile)
273
+ ) -> "svgwrite.Drawing":
274
+ """Build and return the svgwrite Drawing object (without saving)."""
309
275
  if layout is None:
310
276
  layout = Layout()
311
277
 
@@ -395,7 +361,7 @@ def make_svg(
395
361
  # ------------------------------------------------------------------
396
362
  # 6. Assemble SVG
397
363
  # ------------------------------------------------------------------
398
- dwg = svgwrite.Drawing(str(outfile), size=(W, H))
364
+ dwg = svgwrite.Drawing(filename, size=(W, H))
399
365
 
400
366
  # --- Clip path (plot area only) ---
401
367
  clip_id = "plot_clip"
@@ -508,5 +474,95 @@ def make_svg(
508
474
  stroke="green", stroke_width=5, fill="none",
509
475
  ))
510
476
 
477
+ return dwg
478
+
479
+
480
+ def make_svg(
481
+ curves_solid: List[NatCurve],
482
+ curves_dotted: List[NatCurve],
483
+ r_data_max: float,
484
+ *,
485
+ outfile: str | Path = "photometric.svg",
486
+ code: str = "",
487
+ layout: Optional[Layout] = None,
488
+ debug: bool = False,
489
+ colors_solid: Optional[List[str]] = None,
490
+ colors_dotted: Optional[List[str]] = None,
491
+ strokes_solid: Optional[List[float]] = None,
492
+ strokes_dotted: Optional[List[float]] = None,
493
+ ) -> Path:
494
+ """
495
+ Generate a Lumtopic-style photometric polar diagram as an SVG file.
496
+
497
+ Parameters
498
+ ----------
499
+ curves_solid :
500
+ Solid curves (typically C0 / C180), each as a list of
501
+ ``(x_nat, y_nat)`` points.
502
+ curves_dotted :
503
+ Dotted curves (typically C90 / C270), same format.
504
+ r_data_max :
505
+ Maximum intensity across all curves (cd/klm).
506
+ Drives the radial scale computation.
507
+ outfile :
508
+ Destination SVG path. Default: ``"photometric.svg"``.
509
+ code :
510
+ Distribution code shown in the banner centre (e.g. ``"D53"``).
511
+ Pass an empty string to leave it blank.
512
+ layout :
513
+ Visual parameters. If ``None``, :class:`Layout` defaults are used.
514
+ debug :
515
+ If ``True``, draw the plot area in blue and the curve bounding box
516
+ in green as diagnostic overlays.
517
+ colors_solid / colors_dotted :
518
+ Per-curve SVG stroke colours. Defaults to black for all curves.
519
+ strokes_solid / strokes_dotted :
520
+ Per-curve stroke widths. Defaults to ``layout.stroke_curve_solid``
521
+ and ``layout.stroke_curve_dotted`` respectively.
522
+
523
+ Returns
524
+ -------
525
+ :class:`pathlib.Path`
526
+ Absolute path to the generated SVG file.
527
+ """
528
+ outfile = Path(outfile)
529
+ dwg = _build_drawing(
530
+ curves_solid, curves_dotted, r_data_max,
531
+ filename=str(outfile),
532
+ code=code, layout=layout, debug=debug,
533
+ colors_solid=colors_solid, colors_dotted=colors_dotted,
534
+ strokes_solid=strokes_solid, strokes_dotted=strokes_dotted,
535
+ )
511
536
  dwg.save()
512
537
  return outfile.resolve()
538
+
539
+
540
+ def make_svg_str(
541
+ curves_solid: List[NatCurve],
542
+ curves_dotted: List[NatCurve],
543
+ r_data_max: float,
544
+ *,
545
+ code: str = "",
546
+ layout: Optional[Layout] = None,
547
+ debug: bool = False,
548
+ colors_solid: Optional[List[str]] = None,
549
+ colors_dotted: Optional[List[str]] = None,
550
+ strokes_solid: Optional[List[float]] = None,
551
+ strokes_dotted: Optional[List[float]] = None,
552
+ ) -> str:
553
+ """
554
+ Same as :func:`make_svg` but returns the SVG as a string instead of
555
+ writing to disk.
556
+
557
+ Returns
558
+ -------
559
+ str
560
+ SVG document as a string (starts with ``<svg``).
561
+ """
562
+ dwg = _build_drawing(
563
+ curves_solid, curves_dotted, r_data_max,
564
+ code=code, layout=layout, debug=debug,
565
+ colors_solid=colors_solid, colors_dotted=colors_dotted,
566
+ strokes_solid=strokes_solid, strokes_dotted=strokes_dotted,
567
+ )
568
+ return dwg.tostring()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eulumdat-plot
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: Photometric polar diagram generator for EULUMDAT (.ldt) files — extension to eulumdat-py
5
5
  Author: 123VincentB
6
6
  License: MIT
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Requires-Python: >=3.9
23
23
  Description-Content-Type: text/markdown
24
+ License-File: LICENSE
24
25
  Requires-Dist: eulumdat-py>=1.0.0
25
26
  Requires-Dist: numpy>=1.21
26
27
  Requires-Dist: svgwrite>=1.4
@@ -37,12 +38,13 @@ Requires-Dist: build; extra == "dev"
37
38
  Requires-Dist: twine; extra == "dev"
38
39
  Requires-Dist: pytest>=7.0; extra == "dev"
39
40
  Requires-Dist: eulumdat-plot[full]; extra == "dev"
41
+ Dynamic: license-file
40
42
 
41
43
  # eulumdat-plot
42
44
 
43
45
  [![PyPI](https://img.shields.io/pypi/v/eulumdat-plot)](https://pypi.org/project/eulumdat-plot/)
44
46
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/eulumdat-plot)](https://pypi.org/project/eulumdat-plot/)
45
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/123VincentB/eulumdat-plot/blob/main/LICENSE)
47
+ [![License: MIT](https://img.shields.io/github/license/123VincentB/eulumdat-plot)](https://github.com/123VincentB/eulumdat-plot/blob/main/LICENSE)
46
48
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19096110.svg)](https://doi.org/10.5281/zenodo.19096110)
47
49
 
48
50
  Photometric polar diagram generator for EULUMDAT (`.ldt`) files —
@@ -61,7 +63,7 @@ on top of [`eulumdat-py`](https://pypi.org/project/eulumdat-py/).
61
63
 
62
64
  ---
63
65
 
64
- ![Photometric diagram example](https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_01.png) ![Photometric diagram example](https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_02.png)
66
+ <img src="https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_01.png" width="360"> <img src="https://raw.githubusercontent.com/123VincentB/eulumdat-plot/main/docs/img/sample_02.png" width="360">
65
67
 
66
68
  ---
67
69
 
@@ -1,3 +1,4 @@
1
+ LICENSE
1
2
  README.md
2
3
  pyproject.toml
3
4
  src/eulumdat_plot/__init__.py
File without changes