fullplot 0.1.1__tar.gz → 2.0.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.1 → fullplot-2.0.1}/CHANGELOG.md +14 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/PKG-INFO +313 -5
- {fullplot-0.1.1 → fullplot-2.0.1}/README.md +309 -2
- fullplot-2.0.1/examples/hdf5_plotting/15field_results.py +93 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/PLOTTING.md +46 -3
- fullplot-2.0.1/examples/linearization/0generate_linearization_data.py +46 -0
- fullplot-2.0.1/examples/linearization/1inspect_linearization.py +29 -0
- fullplot-2.0.1/examples/linearization/2read_transient_points.py +32 -0
- fullplot-2.0.1/examples/linearization/LINEARIZATION.md +27 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/pyproject.toml +7 -2
- {fullplot-0.1.1 → fullplot-2.0.1}/pyproject.toml.orig +7 -2
- {fullplot-0.1.1 → fullplot-2.0.1}/src/fullplot/__init__.py +5 -11
- {fullplot-0.1.1 → fullplot-2.0.1}/src/fullplot/fullplot.py +158 -37
- fullplot-2.0.1/src/fullplot/linearization.py +335 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/src/fullplot/maps.py +15 -0
- fullplot-0.1.1/tests/test_imports.py +0 -9
- {fullplot-0.1.1 → fullplot-2.0.1}/LICENSE +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/THIRD_PARTY_LICENSES.md +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/0generate_plotting_data.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/10multidimensional_slices.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/11show_multiple_figures.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/12light_theme.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/13module_level_api.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/14save_formats.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/1inspect_hdf5.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/2single_trace.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/3multiple_traces.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/4dual_axis.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/5heatmap_2d_dataset.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/6heatmap_stacked_1d.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/7log_axes.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/8log_color_map.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/hdf5_plotting/9multidimensional_line_traces.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/maps/1_generate_map.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/maps/2_axis_types.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/maps/3_metadata_and_outputs.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/maps/4_hdf5_layout.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/maps/MAPS.md +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/0_generate_trace_demo_file.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/10_windowed_trace_keeps_full_time.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/11_shared_time_axis_window.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/1_quick_hdf5_trace_plot.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/2_extract_trace_and_filter.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/3_create_redlines_bluelines.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/4_command_and_sequence_traces.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/5_trace_math_resample_error.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/6_window_scale_offset_derivative.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/7_save_processed_traces.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/8_missing_nan_values_create_gaps.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/9_shared_time_axis_alignment.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/TRACES.md +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/examples/traces/_trace_demo_data.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/src/fullplot/cli.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/src/fullplot/hdf5.py +0 -0
- {fullplot-0.1.1 → fullplot-2.0.1}/src/fullplot/themes.py +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
* Added metadata/coordinate-aware numeric field orientation and H5File.surface(), with time-first line slicing and legacy FullFlow array-history reading.
|
|
6
|
+
* Added standalone field plotting examples and tests for generic HDF5, coordinate validation, ambiguity and shared map/surface axes.
|
|
7
|
+
|
|
8
|
+
## 2.0.0
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
* Added `H5File.linearization()` to read previously saved FullFlow steady-state and transient state-space results without installing or running FullFlow.
|
|
13
|
+
* Added `H5File.linearizations()` to discover available networks, solver runs, base operating points, and saved transient point times.
|
|
14
|
+
* Added the public `Linearization` data class with `A`, `B`, `C`, `D`, baseline vectors, state/input/output labels, operating time, diagnostics, model-option metadata, and source identifiers.
|
|
15
|
+
* Added single-time and multiple-time transient selection through `time=` and `times=`. Multiple times return a dictionary keyed by requested time.
|
|
16
|
+
|
|
3
17
|
## 0.1.1
|
|
4
18
|
|
|
5
19
|
### Added
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fullplot
|
|
3
|
-
Version: 0.1
|
|
4
|
-
Summary:
|
|
5
|
-
Keywords: hdf5,plotting,engineering,simulation,test-data,map-generation,scientific-computing
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: HDF5 plotting, trace processing, linearization reading, and map generation for engineering data.
|
|
5
|
+
Keywords: hdf5,plotting,engineering,simulation,test-data,linearization,state-space,map-generation,scientific-computing
|
|
6
6
|
Author: Saaketh Ramoju
|
|
7
7
|
Author-email: Saaketh Ramoju <skramoju@gmail.com>
|
|
8
8
|
License-Expression: GPL-3.0-only
|
|
@@ -30,6 +30,7 @@ Project-URL: Issues, https://github.com/saakethramoju/FullPlot/issues
|
|
|
30
30
|
Project-URL: Changelog, https://github.com/saakethramoju/FullPlot/blob/main/CHANGELOG.md
|
|
31
31
|
Project-URL: Documentation, https://github.com/saakethramoju/FullPlot#readme
|
|
32
32
|
Project-URL: PyPI, https://pypi.org/project/fullplot/
|
|
33
|
+
Provides-Extra: examples
|
|
33
34
|
Description-Content-Type: text/markdown
|
|
34
35
|
|
|
35
36
|
# FullPlot
|
|
@@ -193,6 +194,220 @@ settings = run.values("metadata")
|
|
|
193
194
|
|
|
194
195
|
---
|
|
195
196
|
|
|
197
|
+
## Reading FullFlow linearizations
|
|
198
|
+
|
|
199
|
+
FullPlot can read **previously calculated** FullFlow steady-state and transient linearization records. The result is a labeled `Linearization` object containing the state-space matrices and the operating point at which they were computed.
|
|
200
|
+
|
|
201
|
+
A continuous-time linear model takes the form
|
|
202
|
+
|
|
203
|
+
```math
|
|
204
|
+
\Delta\dot{x}=A\Delta x+B\Delta u
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
```math
|
|
208
|
+
\Delta y=C\Delta x+D\Delta u
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
where:
|
|
212
|
+
|
|
213
|
+
- `x`: physical dynamic state vector (for example stored mass or energy),
|
|
214
|
+
- `u`: selected input vector (for example valve area),
|
|
215
|
+
- `y`: selected output vector (for example chamber pressure),
|
|
216
|
+
- `A`: how state changes affect the state derivatives,
|
|
217
|
+
- `B`: how input changes affect the state derivatives,
|
|
218
|
+
- `C`: how state changes affect outputs,
|
|
219
|
+
- `D`: how input changes directly affect outputs.
|
|
220
|
+
|
|
221
|
+
`\Delta` denotes a deviation from the saved operating point. For a non-equilibrium transient point, the model also needs the saved baseline derivative:
|
|
222
|
+
|
|
223
|
+
```math
|
|
224
|
+
\dot{x}\approx\dot{x}_0+A(x-x_0)+B(u-u_0)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
```math
|
|
228
|
+
y\approx y_0+C(x-x_0)+D(u-u_0)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
FullPlot **does not create these matrices**. It reads them from FullFlow's linearization HDF5 output, without needing the original nonlinear network or property-model packages.
|
|
232
|
+
|
|
233
|
+
### Discover available results
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
import fullplot as fplt
|
|
237
|
+
|
|
238
|
+
file = fplt.open("Linearization.h5")
|
|
239
|
+
info = file.linearizations()
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`linearizations()` prints a summary of each available run and returns a list of dictionaries. Each record includes `network`, `solver`, `run`, `path`, `time`, matrix dimensions (`states`, `inputs`, `outputs`), and saved transient point times (`times`). When only transient points were saved, `time` is `None` because there is no separate base result.
|
|
243
|
+
|
|
244
|
+
For programmatic discovery without printing:
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
info = file.linearizations(print_output=False)
|
|
248
|
+
|
|
249
|
+
for run in info:
|
|
250
|
+
print(run["solver"], run["time"], run["times"])
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Read one linearization
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
steady = file.linearization(solver="steady_state")
|
|
257
|
+
|
|
258
|
+
print(steady.A)
|
|
259
|
+
print(steady.B)
|
|
260
|
+
print(steady.C)
|
|
261
|
+
print(steady.D)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Read the final/base transient result with:
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
final = file.linearization(solver="transient")
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Omitting `time` selects the **base result**, not the latest point stored in `points/`. If only saved points are present, specify `time=` or `times=`. If the file contains both steady-state and transient records, select `solver=` explicitly. If only one record is available, it can be inferred.
|
|
271
|
+
|
|
272
|
+
### Read transient operating points
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
point = file.linearization(solver="transient", time=0.1)
|
|
276
|
+
|
|
277
|
+
print(point.time)
|
|
278
|
+
print(point.A.shape)
|
|
279
|
+
print(point.states)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Read several points at once:
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
points = file.linearization(
|
|
286
|
+
solver="transient",
|
|
287
|
+
times=[0.1, 0.3],
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
for requested_time, linear in points.items():
|
|
291
|
+
print(requested_time, linear.A, linear.D)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`times=` returns an ordinary dictionary keyed by the **requested** times, even if HDF5 stores `0.3` as `0.30000000000000004`. Times are matched within a narrow floating-point tolerance. If a time does not exist, FullPlot reports the available point times. If multiple points match the same time, it rejects the ambiguous selection.
|
|
295
|
+
|
|
296
|
+
Saved points can have **different numbers of states, inputs, or outputs**. FullPlot returns each result independently; it does not attempt to concatenate incompatible matrices.
|
|
297
|
+
|
|
298
|
+
### Scope into a run
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
run = file.at("/Water_Flow/linearization/transient/runs/base")
|
|
302
|
+
|
|
303
|
+
point = run.linearization(time=0.1)
|
|
304
|
+
final = run.linearization()
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
A handle scoped directly to a point group can read that point without a time argument:
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
point = file.at(
|
|
311
|
+
"/Water_Flow/linearization/transient/runs/base/points/0"
|
|
312
|
+
).linearization()
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
If several networks contain matching records, `.linearization()` raises an ambiguity error instead of choosing one arbitrarily. Use `.at()` to select the desired network or run. For non-base model-option runs, scope to the run group or supply its HDF5 run path (such as `run="Pump_Model/polytropic"`). A single unambiguous non-base run can also be selected automatically.
|
|
316
|
+
|
|
317
|
+
### Data available in `Linearization`
|
|
318
|
+
|
|
319
|
+
| Attribute | Description |
|
|
320
|
+
| --- | --- |
|
|
321
|
+
| `A`, `B`, `C`, `D` | NumPy state-space matrices |
|
|
322
|
+
| `x0`, `xdot0`, `u0`, `y0` | Nominal states, state rates, inputs, and outputs |
|
|
323
|
+
| `states`, `inputs`, `outputs` | Ordered Python string tuples corresponding to matrix rows and columns |
|
|
324
|
+
| `time` | Operating-point time |
|
|
325
|
+
| `diagnostics` | Saved condition numbers and other numerical diagnostics |
|
|
326
|
+
| `model_options` | Saved FullFlow model-option metadata |
|
|
327
|
+
| `network`, `solver`, `run`, `path` | Source identification and HDF5 path |
|
|
328
|
+
|
|
329
|
+
Dimensions are checked on reading:
|
|
330
|
+
|
|
331
|
+
```math
|
|
332
|
+
A\in\mathbb R^{n_x\times n_x},\quad B\in\mathbb R^{n_x\times n_u},\quad
|
|
333
|
+
C\in\mathbb R^{n_y\times n_x},\quad D\in\mathbb R^{n_y\times n_u}.
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
FullPlot validates the baseline-vector lengths and requires compatible label counts. HDF5 byte strings are decoded to regular Python strings. Incorrect or missing datasets raise `LinearizationError`.
|
|
337
|
+
|
|
338
|
+
### Using the matrices
|
|
339
|
+
|
|
340
|
+
Matrix labels determine the meaning of each row and column:
|
|
341
|
+
|
|
342
|
+
```python
|
|
343
|
+
linear = file.linearization(solver="transient", time=0.1)
|
|
344
|
+
|
|
345
|
+
state_index = linear.states.index("Pipe 1.mass_flow")
|
|
346
|
+
input_index = linear.inputs.index("Pipe 1.cross_sectional_area")
|
|
347
|
+
|
|
348
|
+
sensitivity = linear.B[state_index, input_index]
|
|
349
|
+
print(sensitivity)
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
For a small deviation from the nominal operating point:
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
import numpy as np
|
|
356
|
+
|
|
357
|
+
dx = np.zeros(len(linear.states))
|
|
358
|
+
du = np.zeros(len(linear.inputs))
|
|
359
|
+
du[0] = 1e-6
|
|
360
|
+
|
|
361
|
+
xdot = linear.xdot0 + linear.A @ dx + linear.B @ du
|
|
362
|
+
y = linear.y0 + linear.C @ dx + linear.D @ du
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
These are **local predictions**, not a substitute for the nonlinear model away from the operating point. FullPlot reads the saved arrays; it does not provide built-in eigenvalue analysis, controller tuning, state-space integration, linearization heat maps, or matrix-coefficient trace extraction.
|
|
366
|
+
|
|
367
|
+
### FullFlow HDF5 format
|
|
368
|
+
|
|
369
|
+
The reader supports the current FullFlow per-run and per-point layout:
|
|
370
|
+
|
|
371
|
+
```text
|
|
372
|
+
Network/
|
|
373
|
+
linearization/
|
|
374
|
+
steady_state/
|
|
375
|
+
runs/
|
|
376
|
+
base/
|
|
377
|
+
A, B, C, D
|
|
378
|
+
x0, xdot0, u0, y0
|
|
379
|
+
states, inputs, outputs, time
|
|
380
|
+
diagnostics/, model_options/
|
|
381
|
+
transient/
|
|
382
|
+
runs/
|
|
383
|
+
base/
|
|
384
|
+
A, B, C, D
|
|
385
|
+
x0, xdot0, u0, y0
|
|
386
|
+
states, inputs, outputs, time
|
|
387
|
+
diagnostics/, model_options/
|
|
388
|
+
points/
|
|
389
|
+
0/
|
|
390
|
+
A, B, C, D, ...
|
|
391
|
+
time
|
|
392
|
+
1/
|
|
393
|
+
A, B, C, D, ...
|
|
394
|
+
time
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Reading a saved linearization is **not** the same as calculating one from a normal simulation-history file. Ordinary result traces alone cannot determine the original system equations or their derivatives. Matrix generation remains FullFlow's responsibility.
|
|
398
|
+
|
|
399
|
+
### Linearization examples
|
|
400
|
+
|
|
401
|
+
Run the small demo generator, then the two reading examples:
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
python examples/linearization/0generate_linearization_data.py
|
|
405
|
+
python examples/linearization/1inspect_linearization.py
|
|
406
|
+
python examples/linearization/2read_transient_points.py
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
The demo uses a tiny, self-contained HDF5 file in FullFlow's export format. Replace its filename with your own FullFlow result to inspect real networks. No FullFlow dependency is needed for these reading examples.
|
|
410
|
+
|
|
196
411
|
## Core public API
|
|
197
412
|
|
|
198
413
|
Most users only need these names:
|
|
@@ -213,6 +428,7 @@ fplt.Trace
|
|
|
213
428
|
fplt.TimeAxis
|
|
214
429
|
fplt.Axis
|
|
215
430
|
fplt.generate_map
|
|
431
|
+
fplt.Linearization
|
|
216
432
|
```
|
|
217
433
|
|
|
218
434
|
The main classes are:
|
|
@@ -223,6 +439,7 @@ The main classes are:
|
|
|
223
439
|
| `Trace` | Reusable one-dimensional x/y data object. Used for raw data, filtered data, generated limits, commands, and derived traces. |
|
|
224
440
|
| `TimeAxis` | Shared shiftable and windowable time basis. Several traces can share one axis and follow the same alignment/window. |
|
|
225
441
|
| `Axis` | Independent variable definition for rectangular-grid map generation. |
|
|
442
|
+
| `Linearization` | Labeled FullFlow state-space matrices and their saved operating point. |
|
|
226
443
|
|
|
227
444
|
Important exceptions are:
|
|
228
445
|
|
|
@@ -235,6 +452,7 @@ Important exceptions are:
|
|
|
235
452
|
| `FullPlotMapError` | Base map-generation exception. |
|
|
236
453
|
| `MapGenerationError` | Map generation failed during evaluation, resume, or file layout validation. |
|
|
237
454
|
| `MapOutputError` | The map `evaluate(...)` function returned invalid outputs. |
|
|
455
|
+
| `LinearizationError` | A saved FullFlow linearization is missing, ambiguous, or malformed. |
|
|
238
456
|
|
|
239
457
|
---
|
|
240
458
|
|
|
@@ -861,6 +1079,91 @@ run.map(
|
|
|
861
1079
|
|
|
862
1080
|
---
|
|
863
1081
|
|
|
1082
|
+
## Time-dependent numerical fields and 3D surfaces
|
|
1083
|
+
|
|
1084
|
+
A distributed simulation may record `mass_distribution`, `temperature`,
|
|
1085
|
+
`heat_flux`, or `aero_forces` as multidimensional HDF5 datasets. FullPlot can
|
|
1086
|
+
read these directly; it does not require FullFlow at plotting time.
|
|
1087
|
+
|
|
1088
|
+
For FullFlow 4.0.3 output, numeric field histories have time on axis 0:
|
|
1089
|
+
|
|
1090
|
+
| Field | Dataset shape | Interpretation |
|
|
1091
|
+
| --- | --- | --- |
|
|
1092
|
+
| Mass or temperature | `(time, station)` | One scalar per station per timestep |
|
|
1093
|
+
| Aerodynamic forces | `(time, station, 3)` | Three force components per station |
|
|
1094
|
+
| Fixed final field | `(station,)` or `(station, 3)` | No time axis |
|
|
1095
|
+
|
|
1096
|
+
FullFlow's `State(np.ndarray)` and `StateArray` are saved identically as
|
|
1097
|
+
numerical fields. The HDF5 field has a `time_axis` attribute and a reference to
|
|
1098
|
+
the time dataset. FullPlot uses this information where available, so you do not
|
|
1099
|
+
need to transpose time-first arrays just to make a heat map.
|
|
1100
|
+
|
|
1101
|
+
### Plot a FullFlow field
|
|
1102
|
+
|
|
1103
|
+
```python
|
|
1104
|
+
import fullplot as fplt
|
|
1105
|
+
|
|
1106
|
+
run = fplt.open("2thermal_cells.h5").at("Thermal_Cells/transient")
|
|
1107
|
+
field = "components/Nose_Thermal/temperature"
|
|
1108
|
+
position = "components/Nose_Thermal/stations"
|
|
1109
|
+
|
|
1110
|
+
run.map(
|
|
1111
|
+
z=field,
|
|
1112
|
+
x="time",
|
|
1113
|
+
y=position,
|
|
1114
|
+
xlabel="Time [s]",
|
|
1115
|
+
ylabel="Axial Position [m]",
|
|
1116
|
+
zlabel="Temperature [K]",
|
|
1117
|
+
)
|
|
1118
|
+
|
|
1119
|
+
run.plot(
|
|
1120
|
+
y=field,
|
|
1121
|
+
x="time",
|
|
1122
|
+
slice={1: 3}, # temperature at station index 3
|
|
1123
|
+
xlabel="Time [s]",
|
|
1124
|
+
ylabel="Temperature [K]",
|
|
1125
|
+
)
|
|
1126
|
+
|
|
1127
|
+
run.surface(
|
|
1128
|
+
z=field,
|
|
1129
|
+
x="time",
|
|
1130
|
+
y=position,
|
|
1131
|
+
xlabel="Time [s]",
|
|
1132
|
+
ylabel="Axial Position [m]",
|
|
1133
|
+
zlabel="Temperature [K]",
|
|
1134
|
+
)
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
`map()` renders the third variable as color; `surface()` draws a true 3D
|
|
1138
|
+
Matplotlib surface. Both accept `slice=`, `save=`, `show=`, and the usual title
|
|
1139
|
+
and label arguments. `surface()` returns the figure and 3D axes, not a
|
|
1140
|
+
browser-based interactive Plotly object. For `(time, station, component)`, use
|
|
1141
|
+
`slice={2: 0}` to select a force component before plotting.
|
|
1142
|
+
|
|
1143
|
+
### Axis selection and compatibility
|
|
1144
|
+
|
|
1145
|
+
For a 2D field, `x` and `y` must match its two coordinate dimensions (center or
|
|
1146
|
+
edge arrays are supported where appropriate). FullPlot uses coordinate
|
|
1147
|
+
lengths and available `time_axis`/`time_dataset` metadata to determine the
|
|
1148
|
+
orientation. If both orientations remain possible, provide
|
|
1149
|
+
`orientation="xy"` for data indexed `[x, y]` or `orientation="yx"` for `[y, x]`.
|
|
1150
|
+
A fixed station field recorded on every step may be reduced automatically to
|
|
1151
|
+
its unchanged one-dimensional coordinate array. For generic HDF5 data without
|
|
1152
|
+
axis hints, the established row/column behavior remains available.
|
|
1153
|
+
|
|
1154
|
+
`plot()` selects the time dimension automatically if present in the metadata;
|
|
1155
|
+
for other multidimensional data, supply `axis=` or `slice=` as needed. Numeric
|
|
1156
|
+
JSON-string array histories from older FullFlow HDF5 exports can also be read
|
|
1157
|
+
with `read()` and displayed without a conversion script. Unrelated text fields
|
|
1158
|
+
remain text.
|
|
1159
|
+
|
|
1160
|
+
The standalone example
|
|
1161
|
+
[`15field_results.py`](examples/hdf5_plotting/15field_results.py) creates a
|
|
1162
|
+
numeric HDF5 field and makes a heat map, a trace, and a 3D surface. You can
|
|
1163
|
+
also pass a FullFlow thermal example's HDF5 file as its first argument.
|
|
1164
|
+
|
|
1165
|
+
---
|
|
1166
|
+
|
|
864
1167
|
## Map generation
|
|
865
1168
|
|
|
866
1169
|
FullPlot can generate simple rectangular-grid HDF5 maps.
|
|
@@ -988,11 +1291,12 @@ The CLI does not create plots. Use the Python API for plotting so scripts can co
|
|
|
988
1291
|
|
|
989
1292
|
## Examples
|
|
990
1293
|
|
|
991
|
-
The repository includes
|
|
1294
|
+
The repository includes four example folders:
|
|
992
1295
|
|
|
993
1296
|
```text
|
|
994
1297
|
examples/
|
|
995
1298
|
├── hdf5_plotting/
|
|
1299
|
+
├── linearization/
|
|
996
1300
|
├── maps/
|
|
997
1301
|
└── traces/
|
|
998
1302
|
```
|
|
@@ -1009,6 +1313,7 @@ examples/
|
|
|
1009
1313
|
* log axes and log color scales,
|
|
1010
1314
|
* multidimensional line traces,
|
|
1011
1315
|
* multidimensional slices,
|
|
1316
|
+
* native time-first field histories and 3D surface plots,
|
|
1012
1317
|
* light theme plots,
|
|
1013
1318
|
* module-level API calls,
|
|
1014
1319
|
* saving figures.
|
|
@@ -1037,6 +1342,9 @@ examples/
|
|
|
1037
1342
|
* output discovery,
|
|
1038
1343
|
* HDF5 layout inspection.
|
|
1039
1344
|
|
|
1345
|
+
`examples/linearization/` demonstrates discovering and reading saved FullFlow
|
|
1346
|
+
steady-state and transient state-space models.
|
|
1347
|
+
|
|
1040
1348
|
---
|
|
1041
1349
|
|
|
1042
1350
|
## Themes
|
|
@@ -1098,7 +1406,7 @@ This is deliberate. The package is meant to be a simple bridge between HDF5 engi
|
|
|
1098
1406
|
|
|
1099
1407
|
---
|
|
1100
1408
|
|
|
1101
|
-
|
|
1409
|
+
## Documentation
|
|
1102
1410
|
|
|
1103
1411
|
Full documentation:
|
|
1104
1412
|
|