fullplot 0.1.0__tar.gz → 0.1.1__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.
- {fullplot-0.1.0 → fullplot-0.1.1}/CHANGELOG.md +15 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/PKG-INFO +253 -93
- {fullplot-0.1.0 → fullplot-0.1.1}/README.md +252 -92
- fullplot-0.1.1/examples/traces/11_shared_time_axis_window.py +28 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/TRACES.md +11 -6
- fullplot-0.1.1/pyproject.toml +89 -0
- fullplot-0.1.0/pyproject.toml → fullplot-0.1.1/pyproject.toml.orig +1 -1
- {fullplot-0.1.0 → fullplot-0.1.1}/src/fullplot/__init__.py +1 -1
- {fullplot-0.1.0 → fullplot-0.1.1}/src/fullplot/fullplot.py +187 -70
- {fullplot-0.1.0 → fullplot-0.1.1}/LICENSE +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/THIRD_PARTY_LICENSES.md +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/0generate_plotting_data.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/10multidimensional_slices.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/11show_multiple_figures.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/12light_theme.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/13module_level_api.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/14save_formats.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/1inspect_hdf5.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/2single_trace.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/3multiple_traces.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/4dual_axis.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/5heatmap_2d_dataset.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/6heatmap_stacked_1d.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/7log_axes.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/8log_color_map.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/9multidimensional_line_traces.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/hdf5_plotting/PLOTTING.md +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/maps/1_generate_map.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/maps/2_axis_types.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/maps/3_metadata_and_outputs.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/maps/4_hdf5_layout.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/maps/MAPS.md +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/0_generate_trace_demo_file.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/10_windowed_trace_keeps_full_time.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/1_quick_hdf5_trace_plot.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/2_extract_trace_and_filter.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/3_create_redlines_bluelines.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/4_command_and_sequence_traces.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/5_trace_math_resample_error.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/6_window_scale_offset_derivative.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/7_save_processed_traces.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/8_missing_nan_values_create_gaps.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/9_shared_time_axis_alignment.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/examples/traces/_trace_demo_data.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/src/fullplot/cli.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/src/fullplot/hdf5.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/src/fullplot/maps.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/src/fullplot/themes.py +0 -0
- {fullplot-0.1.0 → fullplot-0.1.1}/tests/test_imports.py +0 -0
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
* Added shared `TimeAxis.window(...)`, `clear_window()`, and `windowed(...)` support so every trace using the same time axis follows one common data window.
|
|
8
|
+
* Added `TimeAxis.full_values`, `raw_count`, `raw_duration`, `raw_dt_array`, `window_range`, and `has_window` for working with the original and active time ranges.
|
|
9
|
+
* Added `Trace.raw_y` so the original y-data remains available when a shared `TimeAxis` is windowed.
|
|
10
|
+
* Added `xlim`, `ylim`, and `y2lim` plotting arguments for display-only axis limits.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
* Shared `TimeAxis` windowing now propagates automatically through attached traces, HDF5 trace extraction, and direct HDF5 plotting.
|
|
15
|
+
* `TimeAxis.count`, `duration`, `dt_array`, and related active-axis properties now describe the current window, while the new `raw_*` properties describe the complete source axis.
|
|
16
|
+
* Trace constructors that use a `TimeAxis` preserve the complete source-length data so windows can be changed or cleared later.
|
|
17
|
+
|
|
3
18
|
## 0.1.0
|
|
4
19
|
|
|
5
20
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fullplot
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: A documented HDF5 plotting, trace-processing, and map-generation package for engineering simulation and test data.
|
|
5
5
|
Keywords: hdf5,plotting,engineering,simulation,test-data,map-generation,scientific-computing
|
|
6
6
|
Author: Saaketh Ramoju
|
|
@@ -60,48 +60,14 @@ FullPlot does **not** require a special FullFlow file format. If your HDF5 file
|
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
|
-
## Repository status for 0.1.0
|
|
64
|
-
|
|
65
|
-
FullPlot 0.1.0 is prepared as the first publish-ready public release of the package.
|
|
66
|
-
|
|
67
|
-
There is no separate official documentation site yet, so the repository is intentionally documentation-heavy:
|
|
68
|
-
|
|
69
|
-
* `README.md` is the primary user guide.
|
|
70
|
-
* `CHANGELOG.md` records release-level changes and bug fixes.
|
|
71
|
-
* `PUBLISHING.md` records the build, smoke-test, artifact-inspection, and upload checklist.
|
|
72
|
-
* `THIRD_PARTY_LICENSES.md` records dependency and license notes.
|
|
73
|
-
* `examples/` contains detailed runnable examples.
|
|
74
|
-
* Public classes, functions, properties, and exceptions include docstrings so `help(fullplot.Trace)`, IDE inspection, and future generated API docs are useful immediately.
|
|
75
|
-
|
|
76
|
-
The 0.1.0 release focuses on documentation, packaging, smoke testing, public API docstrings, and fixing obvious publish-blocking bugs. The core plotting, trace, and map-generation model is intentionally small.
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
63
|
## Installation
|
|
81
64
|
|
|
82
65
|
```bash
|
|
83
|
-
|
|
66
|
+
pip3 install fullplot
|
|
84
67
|
```
|
|
85
68
|
|
|
86
69
|
FullPlot requires Python 3.11 or newer.
|
|
87
70
|
|
|
88
|
-
For local development from the repository:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
python -m venv .venv
|
|
92
|
-
source .venv/bin/activate
|
|
93
|
-
python -m pip install --upgrade pip
|
|
94
|
-
python -m pip install -e .
|
|
95
|
-
python -m pytest
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
With `uv`:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
uv sync --dev
|
|
102
|
-
uv run pytest
|
|
103
|
-
```
|
|
104
|
-
|
|
105
71
|
---
|
|
106
72
|
|
|
107
73
|
## Quick start
|
|
@@ -255,7 +221,7 @@ The main classes are:
|
|
|
255
221
|
| --- | --- |
|
|
256
222
|
| `H5File` | Lightweight handle for one HDF5 file and root group. Created with `fplt.open(...)`. |
|
|
257
223
|
| `Trace` | Reusable one-dimensional x/y data object. Used for raw data, filtered data, generated limits, commands, and derived traces. |
|
|
258
|
-
| `TimeAxis` | Shared shiftable time basis. Several traces can share one
|
|
224
|
+
| `TimeAxis` | Shared shiftable and windowable time basis. Several traces can share one axis and follow the same alignment/window. |
|
|
259
225
|
| `Axis` | Independent variable definition for rectangular-grid map generation. |
|
|
260
226
|
|
|
261
227
|
Important exceptions are:
|
|
@@ -405,7 +371,7 @@ Shift the shared time axis so raw test time 95 seconds becomes model time zero:
|
|
|
405
371
|
time.zero_at(95.0)
|
|
406
372
|
```
|
|
407
373
|
|
|
408
|
-
All three traces
|
|
374
|
+
All three traces shift because they share the same `TimeAxis` object.
|
|
409
375
|
|
|
410
376
|
Use `align(...)` when matching a raw data time to a model time:
|
|
411
377
|
|
|
@@ -413,33 +379,59 @@ Use `align(...)` when matching a raw data time to a model time:
|
|
|
413
379
|
time.align(data_time=95.0, model_time=0.0)
|
|
414
380
|
```
|
|
415
381
|
|
|
382
|
+
Window the shared time axis when every attached trace should use the same section of the test:
|
|
383
|
+
|
|
384
|
+
```python
|
|
385
|
+
time.window(start=2.0, stop=6.5)
|
|
386
|
+
|
|
387
|
+
pc.x # only 2.0 ... 6.5 s
|
|
388
|
+
pc.y # matching PCMC samples
|
|
389
|
+
oipt.y # matching OIPT samples
|
|
390
|
+
fipt.y # matching FIPT samples
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
The original arrays are preserved. Restore the full range with:
|
|
394
|
+
|
|
395
|
+
```python
|
|
396
|
+
time.clear_window()
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Or create an independently windowed copy:
|
|
400
|
+
|
|
401
|
+
```python
|
|
402
|
+
mainstage_time = time.windowed(2.0, 6.5)
|
|
403
|
+
```
|
|
404
|
+
|
|
416
405
|
Useful `TimeAxis` attributes:
|
|
417
406
|
|
|
418
407
|
```python
|
|
419
|
-
time.raw
|
|
420
|
-
time.
|
|
421
|
-
time.
|
|
422
|
-
time.
|
|
423
|
-
time.
|
|
424
|
-
time.
|
|
425
|
-
time.
|
|
426
|
-
time.
|
|
427
|
-
time.
|
|
408
|
+
time.raw # original unshifted samples
|
|
409
|
+
time.full_values # all shifted samples before windowing
|
|
410
|
+
time.values # shifted samples in the active window
|
|
411
|
+
time.zero # current zero offset
|
|
412
|
+
time.count # active sample count
|
|
413
|
+
time.raw_count # original sample count
|
|
414
|
+
time.duration # active time span
|
|
415
|
+
time.raw_duration # original time span
|
|
416
|
+
time.window_range # (start, stop)
|
|
417
|
+
time.has_window # whether a shared window is active
|
|
428
418
|
```
|
|
429
419
|
|
|
420
|
+
For a trace that uses a shared `TimeAxis`, `trace.raw_y` gives the original y-array while `trace.y` follows the active time window.
|
|
421
|
+
|
|
430
422
|
---
|
|
431
423
|
|
|
432
424
|
## Missing values and windows
|
|
433
425
|
|
|
434
426
|
FullPlot preserves non-finite y-values such as `NaN`. This is deliberate. Missing test-data samples should appear as gaps in plots instead of being connected by a misleading line.
|
|
435
427
|
|
|
436
|
-
|
|
428
|
+
Use `TimeAxis.window(...)` when several traces should be cropped together. Use `Trace.window(...)` when only one trace should be valid over part of the otherwise unchanged time axis:
|
|
437
429
|
|
|
438
430
|
```python
|
|
439
431
|
startup = pc.window(start=0.0, stop=3.0, name="Startup Window")
|
|
440
432
|
```
|
|
441
433
|
|
|
442
|
-
`Trace.window(...)` keeps
|
|
434
|
+
`Trace.window(...)` keeps its current x-axis and replaces y-values outside the interval with `NaN`. This is useful when a solver or comparison routine should treat one signal as unavailable outside that interval.
|
|
443
435
|
|
|
444
436
|
Remove missing samples when you explicitly need compact finite data:
|
|
445
437
|
|
|
@@ -564,6 +556,7 @@ Trace metadata is stored as HDF5 attributes when possible.
|
|
|
564
556
|
* HDF5 datasets and `Trace` objects in the same plot,
|
|
565
557
|
* custom labels,
|
|
566
558
|
* log x/y axes,
|
|
559
|
+
* display-only `xlim`, `ylim`, and `y2lim` limits,
|
|
567
560
|
* dark and light themes,
|
|
568
561
|
* saving to PNG, SVG, PDF, or any Matplotlib-supported output,
|
|
569
562
|
* returning Matplotlib objects for custom edits.
|
|
@@ -581,6 +574,9 @@ fig, axes = run.plot(
|
|
|
581
574
|
ylabel="Pressure [psia]",
|
|
582
575
|
y2label="Command [-]",
|
|
583
576
|
title="Pressure and Valve Command",
|
|
577
|
+
xlim=(2.0, 8.0),
|
|
578
|
+
ylim=(0.0, 500.0),
|
|
579
|
+
y2lim=(-0.1, 1.1),
|
|
584
580
|
theme="light",
|
|
585
581
|
save="pressure_command.svg",
|
|
586
582
|
show=False,
|
|
@@ -603,42 +599,227 @@ For trace-only plotting:
|
|
|
603
599
|
fplt.plot([pc, pc_filtered, redline])
|
|
604
600
|
```
|
|
605
601
|
|
|
602
|
+
Plot limits only change what is displayed; they do not window or modify the underlying trace data:
|
|
603
|
+
|
|
604
|
+
```python
|
|
605
|
+
fplt.plot([pc, oipt], xlim=(2.0, 6.5))
|
|
606
|
+
```
|
|
607
|
+
|
|
606
608
|
---
|
|
607
609
|
|
|
608
|
-
## Multidimensional datasets
|
|
610
|
+
## Multidimensional datasets, axes, and slices
|
|
611
|
+
|
|
612
|
+
FullPlot can plot and trace 2D or higher-dimensional datasets by selecting one dimension to vary and holding the other dimensions fixed.
|
|
613
|
+
|
|
614
|
+
The two key arguments are:
|
|
609
615
|
|
|
610
|
-
|
|
616
|
+
| Argument | Meaning |
|
|
617
|
+
| --- | --- |
|
|
618
|
+
| `axis` | The dataset dimension that remains as the plotted line direction. |
|
|
619
|
+
| `slice` | A dictionary of `{dimension_index: fixed_index}` values used to hold the other dimensions fixed. |
|
|
620
|
+
|
|
621
|
+
For a dataset with shape:
|
|
611
622
|
|
|
612
|
-
|
|
623
|
+
```text
|
|
624
|
+
(chamber_pressure, mixture_ratio, expansion_ratio, ambient_pressure, nfz)
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
the dimension numbers are:
|
|
628
|
+
|
|
629
|
+
```text
|
|
630
|
+
axis 0 -> chamber_pressure
|
|
631
|
+
axis 1 -> mixture_ratio
|
|
632
|
+
axis 2 -> expansion_ratio
|
|
633
|
+
axis 3 -> ambient_pressure
|
|
634
|
+
axis 4 -> nfz
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
So this call plots a line that varies along chamber pressure:
|
|
613
638
|
|
|
614
639
|
```python
|
|
615
640
|
run.plot(
|
|
616
|
-
x="
|
|
617
|
-
y="
|
|
618
|
-
axis
|
|
641
|
+
x="axes/chamber_pressure",
|
|
642
|
+
y="outputs/thrust_coefficient",
|
|
643
|
+
axis=0,
|
|
644
|
+
slice={
|
|
645
|
+
1: 12, # fixed mixture_ratio index
|
|
646
|
+
2: 10, # fixed expansion_ratio index
|
|
647
|
+
3: 3, # fixed ambient_pressure index
|
|
648
|
+
4: 0, # fixed nfz index
|
|
649
|
+
},
|
|
650
|
+
xlabel="Chamber Pressure [Pa]",
|
|
651
|
+
ylabel="Thrust Coefficient [-]",
|
|
619
652
|
)
|
|
620
653
|
```
|
|
621
654
|
|
|
622
|
-
|
|
655
|
+
The dimension selected by `axis` is the dimension that becomes the line. The dimensions listed in `slice` are reduced to one fixed index.
|
|
656
|
+
|
|
657
|
+
### Creating traces from multidimensional data
|
|
658
|
+
|
|
659
|
+
`trace(...)` accepts the same `axis` and `slice` arguments as `plot(...)`. This makes it possible to create reusable traces from multidimensional map data and then plot them together.
|
|
623
660
|
|
|
624
661
|
```python
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
662
|
+
import fullplot as fplt
|
|
663
|
+
|
|
664
|
+
psia_to_pa = 6894.75728
|
|
665
|
+
|
|
666
|
+
file = fplt.open("sizer_lookups.h5")
|
|
667
|
+
result = file.at("/engine_lookup")
|
|
668
|
+
|
|
669
|
+
pc_psia = result.read("axes/chamber_pressure") / psia_to_pa
|
|
670
|
+
|
|
671
|
+
cf_eps_4 = result.trace(
|
|
672
|
+
y="outputs/thrust_coefficient",
|
|
673
|
+
x=pc_psia,
|
|
674
|
+
axis=0,
|
|
675
|
+
slice={
|
|
676
|
+
1: 12, # mixture_ratio index
|
|
677
|
+
2: 8, # expansion_ratio index
|
|
678
|
+
3: 3, # ambient_pressure index
|
|
679
|
+
4: 0, # nfz index
|
|
680
|
+
},
|
|
681
|
+
name="eps = 4",
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
cf_eps_6 = result.trace(
|
|
685
|
+
y="outputs/thrust_coefficient",
|
|
686
|
+
x=pc_psia,
|
|
687
|
+
axis=0,
|
|
688
|
+
slice={
|
|
689
|
+
1: 12,
|
|
690
|
+
2: 14,
|
|
691
|
+
3: 3,
|
|
692
|
+
4: 0,
|
|
693
|
+
},
|
|
694
|
+
name="eps = 6",
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
result.plot(
|
|
698
|
+
y=[cf_eps_4, cf_eps_6],
|
|
699
|
+
xlabel="Chamber Pressure [psia]",
|
|
700
|
+
ylabel="Thrust Coefficient [-]",
|
|
701
|
+
title="Thrust Coefficient vs Chamber Pressure",
|
|
630
702
|
)
|
|
631
703
|
```
|
|
632
704
|
|
|
633
|
-
|
|
705
|
+
This is equivalent to manually extracting:
|
|
634
706
|
|
|
635
707
|
```python
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
708
|
+
cf[:, 12, 8, 3, 0] # eps = 4 trace
|
|
709
|
+
cf[:, 12, 14, 3, 0] # eps = 6 trace
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
but keeps the plotting workflow trace-based.
|
|
713
|
+
|
|
714
|
+
### Selecting nearest physical values
|
|
715
|
+
|
|
716
|
+
`slice` uses integer indices, not physical axis values. If you want to select the nearest value on an axis, use a small helper:
|
|
717
|
+
|
|
718
|
+
```python
|
|
719
|
+
import numpy as np
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
def nearest_index(values, target):
|
|
723
|
+
values = np.asarray(values, dtype=float)
|
|
724
|
+
return int(np.argmin(np.abs(values - target)))
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
Example:
|
|
728
|
+
|
|
729
|
+
```python
|
|
730
|
+
mr = result.read("axes/mixture_ratio")
|
|
731
|
+
eps = result.read("axes/expansion_ratio")
|
|
732
|
+
pamb_psia = result.read("axes/ambient_pressure") / psia_to_pa
|
|
733
|
+
nfz = result.read("axes/nfz")
|
|
734
|
+
|
|
735
|
+
mr_i = nearest_index(mr, 2.5)
|
|
736
|
+
pamb_i = nearest_index(pamb_psia, 14.7)
|
|
737
|
+
nfz_i = nearest_index(nfz, 0)
|
|
738
|
+
|
|
739
|
+
traces = []
|
|
740
|
+
|
|
741
|
+
for target_eps in [2, 4, 6, 8, 10]:
|
|
742
|
+
eps_i = nearest_index(eps, target_eps)
|
|
743
|
+
|
|
744
|
+
traces.append(
|
|
745
|
+
result.trace(
|
|
746
|
+
y="outputs/thrust_coefficient",
|
|
747
|
+
x=pc_psia,
|
|
748
|
+
axis=0,
|
|
749
|
+
slice={
|
|
750
|
+
1: mr_i,
|
|
751
|
+
2: eps_i,
|
|
752
|
+
3: pamb_i,
|
|
753
|
+
4: nfz_i,
|
|
754
|
+
},
|
|
755
|
+
name=f"eps = {eps[eps_i]:.1f}",
|
|
756
|
+
)
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
result.plot(
|
|
760
|
+
y=traces,
|
|
761
|
+
xlabel="Chamber Pressure [psia]",
|
|
762
|
+
ylabel="Thrust Coefficient [-]",
|
|
763
|
+
title="Thrust Coefficient vs Chamber Pressure",
|
|
764
|
+
)
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### Common slicing patterns
|
|
768
|
+
|
|
769
|
+
For a dataset ordered as:
|
|
770
|
+
|
|
771
|
+
```text
|
|
772
|
+
(chamber_pressure, mixture_ratio, expansion_ratio, ambient_pressure, nfz)
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
these are common one-dimensional traces:
|
|
776
|
+
|
|
777
|
+
```python
|
|
778
|
+
cf[:, mr_i, eps_i, pamb_i, nfz_i] # vary chamber pressure
|
|
779
|
+
cf[pc_i, :, eps_i, pamb_i, nfz_i] # vary mixture ratio
|
|
780
|
+
cf[pc_i, mr_i, :, pamb_i, nfz_i] # vary expansion ratio
|
|
781
|
+
cf[pc_i, mr_i, eps_i, :, nfz_i] # vary ambient pressure
|
|
782
|
+
cf[pc_i, mr_i, eps_i, pamb_i, :] # vary nfz
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
The matching FullPlot arguments are:
|
|
786
|
+
|
|
787
|
+
```python
|
|
788
|
+
# Vary chamber pressure.
|
|
789
|
+
axis=0
|
|
790
|
+
slice={1: mr_i, 2: eps_i, 3: pamb_i, 4: nfz_i}
|
|
791
|
+
|
|
792
|
+
# Vary mixture ratio.
|
|
793
|
+
axis=1
|
|
794
|
+
slice={0: pc_i, 2: eps_i, 3: pamb_i, 4: nfz_i}
|
|
795
|
+
|
|
796
|
+
# Vary expansion ratio.
|
|
797
|
+
axis=2
|
|
798
|
+
slice={0: pc_i, 1: mr_i, 3: pamb_i, 4: nfz_i}
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Slicing for heat maps
|
|
802
|
+
|
|
803
|
+
For heat maps, leave two dimensions unsliced. For example, to plot thrust coefficient as a function of mixture ratio and chamber pressure, hold expansion ratio, ambient pressure, and `nfz` fixed:
|
|
804
|
+
|
|
805
|
+
```python
|
|
806
|
+
result.map(
|
|
807
|
+
z="outputs/thrust_coefficient",
|
|
808
|
+
x="axes/mixture_ratio",
|
|
809
|
+
y="axes/chamber_pressure",
|
|
810
|
+
slice={
|
|
811
|
+
2: eps_i,
|
|
812
|
+
3: pamb_i,
|
|
813
|
+
4: nfz_i,
|
|
814
|
+
},
|
|
815
|
+
xlabel="Mixture Ratio [-]",
|
|
816
|
+
ylabel="Chamber Pressure [Pa]",
|
|
817
|
+
zlabel="Thrust Coefficient [-]",
|
|
639
818
|
)
|
|
640
819
|
```
|
|
641
820
|
|
|
821
|
+
Use `xscale="log"`, `yscale="log"`, or `zscale="log"` only when the displayed values on that axis are positive.
|
|
822
|
+
|
|
642
823
|
---
|
|
643
824
|
|
|
644
825
|
## Heat maps
|
|
@@ -917,40 +1098,19 @@ This is deliberate. The package is meant to be a simple bridge between HDF5 engi
|
|
|
917
1098
|
|
|
918
1099
|
---
|
|
919
1100
|
|
|
920
|
-
|
|
1101
|
+
# Documentation
|
|
921
1102
|
|
|
922
|
-
|
|
1103
|
+
Full documentation:
|
|
923
1104
|
|
|
924
|
-
|
|
925
|
-
python -m compileall -q src tests examples
|
|
926
|
-
python -m pytest -q
|
|
927
|
-
uv build
|
|
928
|
-
```
|
|
1105
|
+
https://saakethramoju.github.io/softwares/fullplot/
|
|
929
1106
|
|
|
930
|
-
|
|
1107
|
+
Source code:
|
|
931
1108
|
|
|
932
|
-
|
|
933
|
-
import tempfile
|
|
934
|
-
from pathlib import Path
|
|
935
|
-
|
|
936
|
-
import h5py
|
|
937
|
-
import numpy as np
|
|
938
|
-
import fullplot as fplt
|
|
939
|
-
|
|
940
|
-
with tempfile.TemporaryDirectory() as tmp:
|
|
941
|
-
filename = Path(tmp) / "demo.h5"
|
|
1109
|
+
https://github.com/saakethramoju/FullPlot
|
|
942
1110
|
|
|
943
|
-
|
|
944
|
-
h5["time"] = np.linspace(0.0, 1.0, 11)
|
|
945
|
-
h5["pressure"] = np.linspace(100.0, 200.0, 11)
|
|
1111
|
+
PyPI:
|
|
946
1112
|
|
|
947
|
-
|
|
948
|
-
time = run.time("time")
|
|
949
|
-
pressure = run.trace("pressure", x=time)
|
|
950
|
-
redline = fplt.Trace.constant("redline", x=time, y=250.0, role="redline")
|
|
951
|
-
run.plot(x="time", y="pressure", show=False)
|
|
952
|
-
fplt.plot([pressure, redline], show=False)
|
|
953
|
-
```
|
|
1113
|
+
https://pypi.org/project/fullplot/
|
|
954
1114
|
|
|
955
1115
|
---
|
|
956
1116
|
|