flightplotting 0.1.3__tar.gz → 0.2.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.
- {flightplotting-0.1.3/flightplotting.egg-info → flightplotting-0.2.1}/PKG-INFO +5 -1
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/__init__.py +1 -1
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/model.py +12 -29
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/plots.py +8 -9
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/templates.py +6 -5
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/traces.py +27 -17
- {flightplotting-0.1.3 → flightplotting-0.2.1/flightplotting.egg-info}/PKG-INFO +5 -1
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting.egg-info/SOURCES.txt +1 -1
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting.egg-info/requires.txt +0 -1
- {flightplotting-0.1.3 → flightplotting-0.2.1}/setup.cfg +1 -2
- flightplotting-0.2.1/tests/test_plots.py +18 -0
- flightplotting-0.1.3/tests/test_traces.py +0 -10
- {flightplotting-0.1.3 → flightplotting-0.2.1}/COPYING +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/MANIFEST.in +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/README.md +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/data/ColdDraftF3APlane.obj +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/data/__init__.py +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting/titlerenderer.py +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting.egg-info/dependency_links.txt +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/flightplotting.egg-info/top_level.txt +0 -0
- {flightplotting-0.1.3 → flightplotting-0.2.1}/setup.py +0 -0
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightplotting
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Tools for Plotting Flight Data in Plotly
|
|
5
5
|
Home-page: https://github.com/PyFlightCoach/FlightPlotting
|
|
6
6
|
Author: Thomas David
|
|
7
7
|
Author-email: thomasdavid0@gmail.com
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: COPYING
|
|
10
|
+
Requires-Dist: setuptools
|
|
11
|
+
Requires-Dist: flightdata
|
|
12
|
+
Requires-Dist: pfc-geometry
|
|
13
|
+
Requires-Dist: plotly
|
|
10
14
|
|
|
11
15
|
# FlightPlotting
|
|
12
16
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
from flightplotting.plots import plotsec, plot_analysis, plotdtw, create_3d_plot
|
|
4
|
-
from flightplotting.traces import axestrace, trace3d, dtwtrace, vector, vectors
|
|
4
|
+
from flightplotting.traces import axestrace, trace3d, dtwtrace, vector, vectors, boxtrace, axis_rate_traces
|
|
@@ -2,42 +2,25 @@ import numpy as np
|
|
|
2
2
|
import plotly.graph_objects as go
|
|
3
3
|
from geometry import Transformation, Quaternion, Point
|
|
4
4
|
from pkg_resources import resource_stream
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
import numpy.typing as npt
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class OBJ:
|
|
10
|
+
vertices: Point
|
|
11
|
+
faces: npt.NDArray
|
|
12
|
+
normals: npt.NDArray = None
|
|
5
13
|
|
|
6
|
-
class OBJ(object):
|
|
7
|
-
def __init__(self, vertices: Point, faces: np.ndarray):
|
|
8
|
-
self.vertices = vertices
|
|
9
|
-
self.faces = faces
|
|
10
14
|
|
|
11
15
|
@staticmethod
|
|
12
16
|
def from_obj_data(odata):
|
|
13
|
-
"""[summary]
|
|
14
|
-
lifted in its entirity from here: https://chart-studio.plotly.com/~empet/15040/plotly-mesh3d-from-a-wavefront-obj-f/#/
|
|
15
|
-
odata is the string read from an obj file
|
|
16
|
-
"""
|
|
17
|
-
vertices = []
|
|
18
|
-
faces = []
|
|
19
17
|
lines = odata.splitlines()
|
|
20
18
|
|
|
21
|
-
for
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if slist[0] == 'v':
|
|
25
|
-
vertex = np.array(slist[1:], dtype=float)
|
|
26
|
-
vertices.append(vertex)
|
|
27
|
-
elif slist[0] == 'f':
|
|
28
|
-
face = []
|
|
29
|
-
for k in range(1, len(slist)):
|
|
30
|
-
face.append([int(s)
|
|
31
|
-
for s in slist[k].replace('//', '/').split('/')])
|
|
32
|
-
if len(face) > 3: # triangulate the n-polyonal face, n>3
|
|
33
|
-
faces.extend([[face[0][0]-1, face[k][0]-1, face[k+1][0]-1]
|
|
34
|
-
for k in range(1, len(face)-1)])
|
|
35
|
-
else:
|
|
36
|
-
faces.append([face[j][0]-1 for j in range(len(face))])
|
|
37
|
-
else:
|
|
38
|
-
pass
|
|
19
|
+
vertices = np.array([l.split(' ')[1:] for l in lines if l[:2]=='v '] , dtype=float)
|
|
20
|
+
normals = [l.split(' ')[1:] for l in lines if l[:3]=='vn ']
|
|
21
|
+
faces = np.array([[fn.split('//')[0] for fn in l.split(' ')[1:]] for l in lines if l[:2]=='f '], dtype=int)-1
|
|
39
22
|
|
|
40
|
-
return OBJ(Point(
|
|
23
|
+
return OBJ(Point(vertices),faces, normals)
|
|
41
24
|
|
|
42
25
|
@staticmethod
|
|
43
26
|
def from_obj_file(file):
|
|
@@ -16,10 +16,9 @@ from flightplotting.traces import (
|
|
|
16
16
|
axestrace
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
from
|
|
19
|
+
from flightdata import State
|
|
20
20
|
from geometry import Coord
|
|
21
21
|
from flightplotting.model import obj, OBJ
|
|
22
|
-
from flightanalysis import State
|
|
23
22
|
import numpy as np
|
|
24
23
|
from typing import List, Union
|
|
25
24
|
|
|
@@ -43,7 +42,7 @@ def plotsec(secs: Union[State, list[State]], scale=5, nmodels=0, fig=None,
|
|
|
43
42
|
if nmodels > 0:
|
|
44
43
|
traces += meshes(nmodels, sec, _color, obj.scale(scale))
|
|
45
44
|
if cg:
|
|
46
|
-
traces
|
|
45
|
+
traces.append(cgtrace(sec, line=dict(color=_color, width=2)))
|
|
47
46
|
|
|
48
47
|
if origin:
|
|
49
48
|
traces += axestrace(Coord.zero(), 50)
|
|
@@ -73,8 +72,9 @@ def plotsec(secs: Union[State, list[State]], scale=5, nmodels=0, fig=None,
|
|
|
73
72
|
|
|
74
73
|
|
|
75
74
|
|
|
76
|
-
def plotdtw(sec: State, manoeuvres: List[str], span=3):
|
|
77
|
-
fig
|
|
75
|
+
def plotdtw(sec: State, manoeuvres: List[str], span=3, fig=None):
|
|
76
|
+
if fig is None:
|
|
77
|
+
fig = go.Figure(layout=go.Layout(template="flight3d+judge_view"))
|
|
78
78
|
|
|
79
79
|
traces = []#tiptrace(sec, span)
|
|
80
80
|
|
|
@@ -95,10 +95,9 @@ def plotdtw(sec: State, manoeuvres: List[str], span=3):
|
|
|
95
95
|
except Exception as ex:
|
|
96
96
|
pass
|
|
97
97
|
print("no data for manoeuvre {}, {}".format(name, ex))
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
)
|
|
98
|
+
|
|
99
|
+
fig.add_traces(traces)
|
|
100
|
+
|
|
102
101
|
|
|
103
102
|
return fig
|
|
104
103
|
|
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
import plotly.graph_objects as go
|
|
3
3
|
import plotly.io as pio
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
flight3d_template = go.layout.Template(layout=go.Layout(
|
|
6
6
|
margin=dict(l=0, r=0, t=0, b=0),
|
|
7
7
|
scene=dict(
|
|
8
8
|
aspectmode='data',
|
|
9
|
-
#xaxis=dict(visible=True, showticklabels=True),
|
|
10
|
-
#yaxis=dict(visible=True, showticklabels=True),
|
|
11
|
-
#zaxis=dict(visible=True, showticklabels=True),
|
|
12
9
|
),
|
|
13
10
|
legend=dict(
|
|
14
11
|
font=dict(size=20),
|
|
@@ -19,10 +16,14 @@ pio.templates["flight3d"] = go.layout.Template(layout=go.Layout(
|
|
|
19
16
|
)
|
|
20
17
|
))
|
|
21
18
|
|
|
19
|
+
pio.templates["flight3d"] = flight3d_template
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
judges_view_template = go.layout.Template(layout=go.Layout(scene_camera=dict(
|
|
24
22
|
up=dict(x=0, y=0, z=1),
|
|
25
23
|
center=dict(x=0, y=0, z=-0.2),
|
|
26
24
|
eye=dict(x=0.0, y=-3, z=-0.8),
|
|
27
25
|
projection=dict(type='perspective')
|
|
28
26
|
)))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
pio.templates["judge_view"] = judges_view_template
|
|
@@ -5,8 +5,7 @@ from geometry import Point, Coord, Transformation
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from typing import List, Union
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from flightanalysis.schedule import Manoeuvre, Schedule
|
|
8
|
+
from flightdata import State
|
|
10
9
|
from flightplotting.model import obj, OBJ
|
|
11
10
|
import plotly.express as px
|
|
12
11
|
|
|
@@ -53,19 +52,15 @@ def vectors(npoints: int, seq: State, vectors: Point, **kwargs):
|
|
|
53
52
|
|
|
54
53
|
|
|
55
54
|
def trace3d(datax, datay, dataz, **kwargs):
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
),
|
|
66
|
-
**kwargs
|
|
67
|
-
)
|
|
68
|
-
)
|
|
55
|
+
|
|
56
|
+
if not 'mode' in kwargs:
|
|
57
|
+
kwargs['mode'] = 'lines'
|
|
58
|
+
if kwargs['mode'] == 'lines' and not 'line' in kwargs:
|
|
59
|
+
kwargs['line']=dict(width=2, dash="solid")
|
|
60
|
+
if not 'showlegend' in kwargs:
|
|
61
|
+
kwargs['showlegend'] = False
|
|
62
|
+
|
|
63
|
+
return go.Scatter3d(x=datax,y=datay,z=dataz,**kwargs)
|
|
69
64
|
|
|
70
65
|
|
|
71
66
|
def cgtrace(seq, **kwargs):
|
|
@@ -80,7 +75,7 @@ def cgtrace(seq, **kwargs):
|
|
|
80
75
|
)
|
|
81
76
|
|
|
82
77
|
|
|
83
|
-
def manoeuvretraces(schedule
|
|
78
|
+
def manoeuvretraces(schedule, section: State, colours = px.colors.qualitative.Plotly):
|
|
84
79
|
traces = []
|
|
85
80
|
for man, color in zip(schedule.manoeuvres, colours):
|
|
86
81
|
st = man.get_data(section)
|
|
@@ -89,7 +84,7 @@ def manoeuvretraces(schedule: Schedule, section: State, colours = px.colors.qual
|
|
|
89
84
|
return traces
|
|
90
85
|
|
|
91
86
|
|
|
92
|
-
def elementtraces(manoeuvre
|
|
87
|
+
def elementtraces(manoeuvre, sec: State):
|
|
93
88
|
traces = []
|
|
94
89
|
for id, element in enumerate(manoeuvre.elements):
|
|
95
90
|
elm = element.get_data(sec)
|
|
@@ -152,6 +147,21 @@ def dtwtrace(sec: State, elms, showlegend = True):
|
|
|
152
147
|
|
|
153
148
|
|
|
154
149
|
|
|
150
|
+
|
|
151
|
+
def axis_rate_traces(sts: dict[str, State], cols='pqr'):
|
|
152
|
+
cols = px.colors.qualitative.D3
|
|
153
|
+
traces = []
|
|
154
|
+
dashes = ['solid', 'dot', 'dash', 'longdash', 'dashdot', 'longdashdot']
|
|
155
|
+
for i, rv in enumerate(list('pqr')):
|
|
156
|
+
for k, st in sts.items():
|
|
157
|
+
|
|
158
|
+
traces.append(go.Scatter(
|
|
159
|
+
x=st.data.index, y=getattr(st, rv), name=f'{k} {rv}', line=dict(color=cols[i], dash=dashes[list(sts.keys()).index(k)])
|
|
160
|
+
))
|
|
161
|
+
return traces
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
155
165
|
def sec_col_trace(sec, columns, dash="solid", colours = px.colors.qualitative.Plotly, yfunc=lambda x: x):
|
|
156
166
|
trs = []
|
|
157
167
|
for i, axis in enumerate(columns):
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightplotting
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Tools for Plotting Flight Data in Plotly
|
|
5
5
|
Home-page: https://github.com/PyFlightCoach/FlightPlotting
|
|
6
6
|
Author: Thomas David
|
|
7
7
|
Author-email: thomasdavid0@gmail.com
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: COPYING
|
|
10
|
+
Requires-Dist: setuptools
|
|
11
|
+
Requires-Dist: flightdata
|
|
12
|
+
Requires-Dist: pfc-geometry
|
|
13
|
+
Requires-Dist: plotly
|
|
10
14
|
|
|
11
15
|
# FlightPlotting
|
|
12
16
|
|
|
@@ -5,7 +5,7 @@ author_email = thomasdavid0@gmail.com
|
|
|
5
5
|
description = Tools for Plotting Flight Data in Plotly
|
|
6
6
|
long_description = file: README.md
|
|
7
7
|
long_description_content_type = text/markdown
|
|
8
|
-
version = 0.1
|
|
8
|
+
version = 0.2.1
|
|
9
9
|
url = https://github.com/PyFlightCoach/FlightPlotting
|
|
10
10
|
|
|
11
11
|
[options]
|
|
@@ -13,7 +13,6 @@ install_requires =
|
|
|
13
13
|
setuptools
|
|
14
14
|
flightdata
|
|
15
15
|
pfc-geometry
|
|
16
|
-
flightanalysis
|
|
17
16
|
plotly
|
|
18
17
|
include_package_data = True
|
|
19
18
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from flightdata import Flight, State
|
|
2
|
+
from pytest import fixture
|
|
3
|
+
from flightplotting import plotsec
|
|
4
|
+
from flightplotting.traces import cgtrace
|
|
5
|
+
import plotly.graph_objects as go
|
|
6
|
+
|
|
7
|
+
@fixture
|
|
8
|
+
def state():
|
|
9
|
+
return State.from_flight(Flight.from_json('tests/data/p23_flight.json'))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_plotsec_cg(state):
|
|
13
|
+
fig = plotsec(state, tips=False, cg=True)
|
|
14
|
+
assert isinstance(fig, go.Figure)
|
|
15
|
+
|
|
16
|
+
def test_cgtrace(state):
|
|
17
|
+
trace = cgtrace(state)
|
|
18
|
+
assert isinstance(trace, go.Scatter3d)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
from flightanalysis import State, Loop
|
|
2
|
-
from geometry import Transformation, Euler, P0
|
|
3
|
-
import numpy as np
|
|
4
|
-
|
|
5
|
-
st = Loop(100, 1, 1).create_template(Transformation(P0(), Euler(np.pi, 0, 0)), 20)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from flightplotting import plotsec
|
|
9
|
-
|
|
10
|
-
plotsec(st, nmodels=5).show()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|