Lode Nachtergaele commited on
Commit
e39eb6b
1 Parent(s): 812bb44

downgrade to Altair 4.2.2

Browse files
Files changed (4) hide show
  1. app.py +150 -33
  2. poetry.lock +18 -8
  3. pyproject.toml +1 -1
  4. requirements.txt +4 -4
app.py CHANGED
@@ -5,15 +5,21 @@ from typing import List
5
  from urllib.request import pathname2url
6
  from xml.dom import minidom
7
 
 
 
 
 
 
8
  import numpy as np
9
  import pandas as pd
10
  from scipy.signal import find_peaks
11
  import streamlit as st
12
 
13
- # import folium
14
- # from streamlit_folium import st_folium
15
  import altair as alt
16
  from io import StringIO
 
17
 
18
 
19
  def get_gpx(uploaded_file):
@@ -176,49 +182,129 @@ def generate_height_profile_json(df: pd.DataFrame) -> str:
176
  df["smoothed_grade_color"] = df["smoothed_grade"].map(grade_to_color)
177
  # df["grade_color"] = df["grade"].map(grade_to_color)
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  elevation = (
180
- alt.Chart(
181
- df[["distance_from_start", "smoothed_elevation", "smoothed_grade_color"]]
 
 
 
 
 
 
 
 
 
 
 
 
182
  )
183
- .mark_bar()
184
  .encode(
185
- x=alt.X("distance_from_start")
186
- .axis(
187
- grid=False,
188
- tickCount=10,
189
- labelExpr="datum.label + ' km'",
190
- title=None,
191
- )
192
- .scale(domain=(0, total_distance_round)),
193
- y=alt.Y("smoothed_elevation").axis(
194
- domain=False,
195
- ticks=False,
196
- tickCount=5,
197
- labelExpr="datum.label + ' m'",
198
- title=None,
 
 
 
 
 
199
  ),
200
- color=alt.Color("smoothed_grade_color").scale(None),
201
  )
202
  )
203
 
204
  df_peaks_filtered = find_climbs(df)
 
 
 
 
 
 
 
 
 
205
  line_peaks = (
206
  alt.Chart(df_peaks_filtered[["distance_from_start", "elev", "max_elevation"]])
207
  .mark_rule(color="red")
208
  .encode(
209
- x=alt.X("distance_from_start:Q").scale(domain=(0, total_distance_round)),
 
 
 
210
  y="elev",
211
  y2="max_elevation",
212
  )
213
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  chart = (
215
- (elevation + line_peaks).properties(width="container")
216
- # .properties(height=100, width=750)
217
  .configure_view(
218
  strokeWidth=0,
219
  )
220
  )
221
- return chart
222
 
223
 
224
  gpx_file = st.file_uploader("Upload gpx file", type=["gpx"])
@@ -226,14 +312,45 @@ gpx_file = st.file_uploader("Upload gpx file", type=["gpx"])
226
  if gpx_file is not None:
227
  ave_lat, ave_lon, lon_list, lat_list, h_list = get_gpx(gpx_file)
228
  df = pd.DataFrame({"lon": lon_list, "lat": lat_list, "elev": h_list})
229
- # route_map = folium.Map(
230
- # location=[ave_lat, ave_lon],
231
- # zoom_start=12,
232
- # )
233
- # folium.PolyLine(
234
- # list(zip(lat_list, lon_list)), color="red", weight=2.5, opacity=1
235
- # ).add_to(route_map)
236
- # st_data = st_folium(route_map, height=450, width=850)
237
- chart = generate_height_profile_json(df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
  st.altair_chart(chart, use_container_width=True)
 
5
  from urllib.request import pathname2url
6
  from xml.dom import minidom
7
 
8
+ from folium.plugins import BeautifyIcon
9
+ from folium.features import DivIcon
10
+
11
+ # import folium.plugins as plugins
12
+
13
  import numpy as np
14
  import pandas as pd
15
  from scipy.signal import find_peaks
16
  import streamlit as st
17
 
18
+ import folium
19
+ from streamlit_folium import st_folium
20
  import altair as alt
21
  from io import StringIO
22
+ import branca
23
 
24
 
25
  def get_gpx(uploaded_file):
 
182
  df["smoothed_grade_color"] = df["smoothed_grade"].map(grade_to_color)
183
  # df["grade_color"] = df["grade"].map(grade_to_color)
184
 
185
+ # elevation = (
186
+ # alt.Chart(
187
+ # df[["distance_from_start", "smoothed_elevation", "smoothed_grade_color"]]
188
+ # )
189
+ # .mark_bar()
190
+ # .encode(
191
+ # x=alt.X("distance_from_start")
192
+ # .axis(
193
+ # grid=False,
194
+ # tickCount=10,
195
+ # labelExpr="datum.label + ' km'",
196
+ # title=None,
197
+ # )
198
+ # .scale(domain=(0, total_distance_round)),
199
+ # y=alt.Y("smoothed_elevation").axis(
200
+ # domain=False,
201
+ # ticks=False,
202
+ # tickCount=5,
203
+ # labelExpr="datum.label + ' m'",
204
+ # title=None,
205
+ # ),
206
+ # color=alt.Color("smoothed_grade_color").scale(None),
207
+ # )
208
+ # )
209
+ max_elevation = df["elev"].max().round(-1)
210
  elevation = (
211
+ alt.Chart(df)
212
+ .mark_area(
213
+ color=alt.Gradient(
214
+ gradient="linear",
215
+ stops=[
216
+ alt.GradientStop(color="lightgrey", offset=0),
217
+ alt.GradientStop(color="darkgrey", offset=1),
218
+ ],
219
+ x1=1,
220
+ x2=1,
221
+ y1=1,
222
+ y2=0,
223
+ ),
224
+ line={"color": "darkgreen"},
225
  )
 
226
  .encode(
227
+ x=alt.X(
228
+ "distance_from_start",
229
+ axis=alt.Axis(
230
+ domain=False,
231
+ ticks=False,
232
+ tickCount=10,
233
+ labelExpr="datum.label + ' km'",
234
+ ),
235
+ scale=alt.Scale(domain=(0, total_distance_round)),
236
+ ),
237
+ y=alt.Y(
238
+ "elev",
239
+ axis=alt.Axis(
240
+ domain=False,
241
+ ticks=False,
242
+ tickCount=5,
243
+ labelExpr="datum.label + ' m'",
244
+ ),
245
+ scale=alt.Scale(domain=(0, max_elevation)),
246
  ),
 
247
  )
248
  )
249
 
250
  df_peaks_filtered = find_climbs(df)
251
+ # line_peaks = (
252
+ # alt.Chart(df_peaks_filtered[["distance_from_start", "elev", "max_elevation"]])
253
+ # .mark_rule(color="red")
254
+ # .encode(
255
+ # x=alt.X("distance_from_start:Q").scale(domain=(0, total_distance_round)),
256
+ # y="elev",
257
+ # y2="max_elevation",
258
+ # )
259
+ # )
260
  line_peaks = (
261
  alt.Chart(df_peaks_filtered[["distance_from_start", "elev", "max_elevation"]])
262
  .mark_rule(color="red")
263
  .encode(
264
+ x=alt.X(
265
+ "distance_from_start:Q",
266
+ scale=alt.Scale(domain=(0, total_distance_round)),
267
+ ),
268
  y="elev",
269
  y2="max_elevation",
270
  )
271
  )
272
+ df_annot = (
273
+ df_peaks_filtered.reset_index(drop=True)
274
+ .assign(number=lambda df_: df_.index + 1)
275
+ .assign(circle_pos=lambda df_: df_["max_elevation"] + 20)[
276
+ ["distance_from_start", "max_elevation", "circle_pos", "number"]
277
+ ]
278
+ )
279
+ # annotation = (
280
+ # alt.Chart(df_annot)
281
+ # .mark_text(align="center", baseline="bottom", fontSize=16, dy=-10)
282
+ # .encode(
283
+ # x=alt.X("distance_from_start:Q").scale(domain=(0, total_distance_round)),
284
+ # y="max_elevation",
285
+ # text="number",
286
+ # )
287
+ # )
288
+ annotation = (
289
+ alt.Chart(df_annot)
290
+ .mark_text(align="center", baseline="bottom", fontSize=16, dy=-10)
291
+ .encode(
292
+ x=alt.X(
293
+ "distance_from_start:Q",
294
+ scale=alt.Scale(domain=(0, total_distance_round)),
295
+ ),
296
+ y="max_elevation",
297
+ text="number",
298
+ )
299
+ )
300
  chart = (
301
+ (elevation + line_peaks + annotation)
302
+ .properties(width="container")
303
  .configure_view(
304
  strokeWidth=0,
305
  )
306
  )
307
+ return chart, df_peaks_filtered
308
 
309
 
310
  gpx_file = st.file_uploader("Upload gpx file", type=["gpx"])
 
312
  if gpx_file is not None:
313
  ave_lat, ave_lon, lon_list, lat_list, h_list = get_gpx(gpx_file)
314
  df = pd.DataFrame({"lon": lon_list, "lat": lat_list, "elev": h_list})
315
+ route_map = folium.Map(
316
+ location=[ave_lat, ave_lon],
317
+ zoom_start=12,
318
+ )
319
+ folium.PolyLine(
320
+ list(zip(lat_list, lon_list)), color="red", weight=2.5, opacity=1
321
+ ).add_to(route_map)
322
+
323
+ chart, df_peaks = generate_height_profile_json(df)
324
+ for index, row in df_peaks.reset_index(drop=True).iterrows():
325
+ icon = BeautifyIcon(
326
+ icon="arrow-down",
327
+ icon_shape="marker",
328
+ number=str(index + 1),
329
+ border_color="red",
330
+ background_color="white",
331
+ )
332
+ icon_div = DivIcon(
333
+ icon_size=(150, 36),
334
+ icon_anchor=(7, 20),
335
+ html=f"<div style='font-size: 18pt; color : black'>{index+1}</div>",
336
+ )
337
+ length = (
338
+ f"{row['length']:.1f} km"
339
+ if row["length"] >= 1
340
+ else f"{row['length']*1000:.0f} m"
341
+ )
342
+ popup_text = f"""Lenght: {length}<br>
343
+ Avg. grade: {row['grade']/1000:.1f}%"""
344
+ popup = folium.Popup(popup_text, min_width=100, max_width=200)
345
+ folium.Marker(
346
+ [row["lat"], row["lon"]],
347
+ popup=popup,
348
+ icon=icon_div,
349
+ ).add_to(route_map)
350
+ route_map.add_child(folium.CircleMarker([row["lat"], row["lon"]], radius=15))
351
+
352
+ st.table(df_peaks)
353
+
354
+ st_data = st_folium(route_map, height=450, width=850)
355
 
356
  st.altair_chart(chart, use_container_width=True)
poetry.lock CHANGED
@@ -2,26 +2,25 @@
2
 
3
  [[package]]
4
  name = "altair"
5
- version = "5.0.1"
6
- description = "Vega-Altair: A declarative statistical visualization library for Python."
7
  optional = false
8
  python-versions = ">=3.7"
9
  files = [
10
- {file = "altair-5.0.1-py3-none-any.whl", hash = "sha256:9f3552ed5497d4dfc14cf48a76141d8c29ee56eae2873481b4b28134268c9bbe"},
11
- {file = "altair-5.0.1.tar.gz", hash = "sha256:087d7033cb2d6c228493a053e12613058a5d47faf6a36aea3ff60305fd8b4cb0"},
12
  ]
13
 
14
  [package.dependencies]
 
15
  jinja2 = "*"
16
  jsonschema = ">=3.0"
17
  numpy = "*"
18
  pandas = ">=0.18"
19
  toolz = "*"
20
- typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
21
 
22
  [package.extras]
23
- dev = ["black (<24)", "hatch", "ipython", "m2r", "mypy", "pandas-stubs", "pytest", "pytest-cov", "ruff", "types-jsonschema", "types-setuptools", "vega-datasets", "vl-convert-python"]
24
- doc = ["docutils", "geopandas", "jinja2", "myst-parser", "numpydoc", "pillow", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinxext-altair"]
25
 
26
  [[package]]
27
  name = "attrs"
@@ -278,6 +277,17 @@ files = [
278
  {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
279
  ]
280
 
 
 
 
 
 
 
 
 
 
 
 
281
  [[package]]
282
  name = "exceptiongroup"
283
  version = "1.1.2"
@@ -1493,4 +1503,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
1493
  [metadata]
1494
  lock-version = "2.0"
1495
  python-versions = ">=3.10,<3.13"
1496
- content-hash = "748a07a0f37a12766536420ac445825e1cabd04ca2fb89f4038c9dd55e1cd57b"
 
2
 
3
  [[package]]
4
  name = "altair"
5
+ version = "4.2.2"
6
+ description = "Altair: A declarative statistical visualization library for Python."
7
  optional = false
8
  python-versions = ">=3.7"
9
  files = [
10
+ {file = "altair-4.2.2-py3-none-any.whl", hash = "sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87"},
11
+ {file = "altair-4.2.2.tar.gz", hash = "sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5"},
12
  ]
13
 
14
  [package.dependencies]
15
+ entrypoints = "*"
16
  jinja2 = "*"
17
  jsonschema = ">=3.0"
18
  numpy = "*"
19
  pandas = ">=0.18"
20
  toolz = "*"
 
21
 
22
  [package.extras]
23
+ dev = ["black", "docutils", "flake8", "ipython", "m2r", "mistune (<2.0.0)", "pytest", "recommonmark", "sphinx", "vega-datasets"]
 
24
 
25
  [[package]]
26
  name = "attrs"
 
277
  {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
278
  ]
279
 
280
+ [[package]]
281
+ name = "entrypoints"
282
+ version = "0.4"
283
+ description = "Discover and load entry points from installed packages."
284
+ optional = false
285
+ python-versions = ">=3.6"
286
+ files = [
287
+ {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"},
288
+ {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"},
289
+ ]
290
+
291
  [[package]]
292
  name = "exceptiongroup"
293
  version = "1.1.2"
 
1503
  [metadata]
1504
  lock-version = "2.0"
1505
  python-versions = ">=3.10,<3.13"
1506
+ content-hash = "b34d5fefcbbd82b4d635d5e7d866bde0aa6dbf2f7d5a59bb4ab832bac56622a2"
pyproject.toml CHANGED
@@ -11,10 +11,10 @@ readme = "README.md"
11
  python = ">=3.10,<3.13"
12
  streamlit = "1.24.0"
13
  scipy = "1.11.1"
14
- altair = "5.0.1"
15
  watchdog = "^3.0.0"
16
  folium = "^0.14.0"
17
  streamlit-folium = "^0.12.0"
 
18
 
19
 
20
  [tool.poetry.group.dev.dependencies]
 
11
  python = ">=3.10,<3.13"
12
  streamlit = "1.24.0"
13
  scipy = "1.11.1"
 
14
  watchdog = "^3.0.0"
15
  folium = "^0.14.0"
16
  streamlit-folium = "^0.12.0"
17
+ altair = "4.2.2"
18
 
19
 
20
  [tool.poetry.group.dev.dependencies]
requirements.txt CHANGED
@@ -1,6 +1,6 @@
1
- streamlit==1.24.0
2
- # folium==0.14.0
3
- # streamlit-folium==0.12.0
4
- # altair==5.0.1
5
  # pandas==2.0.3
6
  scipy==1.11.1
 
1
+ # streamlit==1.24.0
2
+ folium==0.14.0
3
+ streamlit-folium==0.12.0
4
+ # altair==4.2.2
5
  # pandas==2.0.3
6
  scipy==1.11.1