@@ -65,6 +65,7 @@ def __init__(
65
65
self .precisions : Dict = None
66
66
self .time_data : bool = False
67
67
self .time_format : str = None
68
+ self .dataframe : pd .DataFrame = None
68
69
69
70
# GPX
70
71
if file_path .endswith (".gpx" ):
@@ -615,7 +616,8 @@ def to_dataframe(
615
616
speed : bool = False ,
616
617
pace : bool = False ,
617
618
ascent_rate : bool = False ,
618
- ascent_speed : bool = False ) -> pd .DataFrame :
619
+ ascent_speed : bool = False ,
620
+ distance_from_start : bool = False ) -> pd .DataFrame :
619
621
"""
620
622
Convert GPX object to Pandas Dataframe.
621
623
@@ -633,13 +635,25 @@ def to_dataframe(
633
635
Toggle ascent rate, by default False
634
636
ascent_speed : bool, optional
635
637
Toggle ascent speed, by default False
638
+ distance_from_start : bool, optional
639
+ Toggle distance from start, by default False
636
640
637
641
Returns
638
642
-------
639
643
pd.DataFrame
640
644
Dataframe containing data from GPX.
641
645
"""
642
- return self .gpx .to_dataframe (projection , elevation , speed , pace , ascent_rate , ascent_speed )
646
+ if not self .time_data :
647
+ speed = False
648
+ pace = False
649
+ ascent_speed = False
650
+ return self .gpx .to_dataframe (projection ,
651
+ elevation ,
652
+ speed ,
653
+ pace ,
654
+ ascent_rate ,
655
+ ascent_speed ,
656
+ distance_from_start )
643
657
644
658
def to_csv (
645
659
self ,
@@ -775,7 +789,7 @@ def _matplotlib_plot_text(
775
789
plt .text (speed [0 ], speed [1 ],
776
790
f"Speed:\n { self .avg_speed ():.2f} km/h" , ** text_parameters )
777
791
778
- def matplotlib_axes_plot (
792
+ def matplotlib_map_plot (
779
793
self ,
780
794
axes : Axes ,
781
795
projection : Optional [str ] = None ,
@@ -833,60 +847,45 @@ def matplotlib_axes_plot(
833
847
column_y = "y"
834
848
self .gpx .project (projection ) # Project all track points
835
849
836
- # Create dataframe containing data from the GPX file
837
- gpx_df = None
838
- if color == "elevation" :
839
- gpx_df = self .to_dataframe (projection = True , elevation = True , speed = False , pace = False , ascent_rate = False , ascent_speed = False )
840
- elif color == "speed" :
841
- gpx_df = self .to_dataframe (projection = True , elevation = False , speed = True , pace = False , ascent_rate = False , ascent_speed = False )
842
- elif color == "pace" :
843
- gpx_df = self .to_dataframe (projection = True , elevation = False , speed = False , pace = True , ascent_rate = False , ascent_speed = False )
844
- elif color == "ascent_rate" :
845
- gpx_df = self .to_dataframe (projection = True , elevation = False , speed = False , pace = False , ascent_rate = True , ascent_speed = False )
846
- elif color == "ascent_speed" :
847
- gpx_df = self .to_dataframe (projection = True , elevation = False , speed = False , pace = False , ascent_rate = False , ascent_speed = True )
848
- else :
849
- gpx_df = self .to_dataframe (projection = True , elevation = False , speed = False , pace = False , ascent_rate = False , ascent_speed = False )
850
-
851
850
# Scatter all track points
852
851
if color == "elevation" :
853
852
cmap = matplotlib .colors .LinearSegmentedColormap .from_list ("" , ["green" ,"blue" ])
854
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ],
855
- c = gpx_df ["ele" ], cmap = cmap )
853
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ],
854
+ c = self . dataframe ["ele" ], cmap = cmap )
856
855
elif color == "speed" :
857
856
# cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["lightskyblue", "deepskyblue", "blue", "mediumblue", "midnightblue"])
858
857
cmap = matplotlib .colors .LinearSegmentedColormap .from_list ("" , ["lightskyblue" , "mediumblue" , "midnightblue" ])
859
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ],
860
- c = gpx_df ["speed" ], cmap = cmap )
858
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ],
859
+ c = self . dataframe ["speed" ], cmap = cmap )
861
860
elif color == "pace" :
862
861
cmap = matplotlib .colors .LinearSegmentedColormap .from_list ("" , ["lightskyblue" , "midnightblue" ])
863
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ],
864
- c = gpx_df ["pace" ], cmap = cmap )
862
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ],
863
+ c = self . dataframe ["pace" ], cmap = cmap )
865
864
elif color == "vertical_drop" :
866
865
cmap = matplotlib .colors .LinearSegmentedColormap .from_list ("" , ["yellow" , "orange" , "red" , "purple" , "black" ])
867
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ],
868
- c = abs (gpx_df ["ascent_rate" ]), cmap = cmap )
866
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ],
867
+ c = abs (self . dataframe ["ascent_rate" ]), cmap = cmap )
869
868
elif color == "ascent_rate" :
870
869
cmap = matplotlib .colors .LinearSegmentedColormap .from_list ("" , ["darkgreen" , "green" , "yellow" , "red" , "black" ])
871
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ],
872
- c = gpx_df ["ascent_rate" ], cmap = cmap )
870
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ],
871
+ c = self . dataframe ["ascent_rate" ], cmap = cmap )
873
872
elif color == "ascent_speed" :
874
873
cmap = matplotlib .colors .LinearSegmentedColormap .from_list ("" , ["deeppink" , "lightpink" , "lightcoral" , "red" , "darkred" ])
875
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ],
876
- c = gpx_df ["ascent_speed" ], cmap = cmap )
874
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ],
875
+ c = self . dataframe ["ascent_speed" ], cmap = cmap )
877
876
else :
878
- im = axes .scatter (gpx_df [column_x ], gpx_df [column_y ], color = color )
877
+ im = axes .scatter (self . dataframe [column_x ], self . dataframe [column_y ], color = color )
879
878
880
879
# Colorbar
881
880
if colorbar :
882
881
plt .colorbar (im )
883
882
884
883
# Scatter start and stop points with different color
885
884
if start_stop_colors is not None :
886
- axes .scatter (gpx_df [column_x ][0 ],
887
- gpx_df [column_y ][0 ], color = start_stop_colors [0 ])
888
- axes .scatter (gpx_df [column_x ][len (gpx_df [column_x ])- 1 ],
889
- gpx_df [column_y ][len (gpx_df [column_x ])- 1 ], color = start_stop_colors [1 ])
885
+ axes .scatter (self . dataframe [column_x ][0 ],
886
+ self . dataframe [column_y ][0 ], color = start_stop_colors [0 ])
887
+ axes .scatter (self . dataframe [column_x ][len (self . dataframe [column_x ])- 1 ],
888
+ self . dataframe [column_y ][len (self . dataframe [column_x ])- 1 ], color = start_stop_colors [1 ])
890
889
891
890
# Scatter way points with different color
892
891
if way_points_color :
@@ -905,18 +904,28 @@ def matplotlib_axes_plot(
905
904
self ._matplotlib_plot_text (axes .get_figure (), duration , distance , ascent , pace , speed )
906
905
907
906
# Add ticks
908
- axes .set_xticks ([min (gpx_df [column_x ]), max (gpx_df [column_x ])])
909
- axes .set_yticks ([min (gpx_df [column_y ]), max (gpx_df [column_y ])])
907
+ axes .set_xticks ([min (self . dataframe [column_x ]), max (self . dataframe [column_x ])])
908
+ axes .set_yticks ([min (self . dataframe [column_y ]), max (self . dataframe [column_y ])])
910
909
911
910
# Add axis limits (useless??)
912
911
if projection is not None :
913
- axes .set_xlim (left = min (gpx_df [column_x ]),
914
- right = max (gpx_df [column_x ]))
915
- axes .set_ylim (bottom = min (gpx_df [column_y ]),
916
- top = max (gpx_df [column_y ]))
912
+ axes .set_xlim (left = min (self .dataframe [column_x ]),
913
+ right = max (self .dataframe [column_x ]))
914
+ axes .set_ylim (bottom = min (self .dataframe [column_y ]),
915
+ top = max (self .dataframe [column_y ]))
916
+
917
+ def matplotlib_elevation_profile_plot (
918
+ self ,
919
+ axes : Axes ):
920
+ # Clear axes
921
+ axes .clear ()
922
+
923
+ # Plot
924
+ im = axes .plot (self .dataframe ["distance_from_start" ].values , self .dataframe ["ele" ].values ) # .values to avoid -> Multi-dimensional indexing (e.g. `obj[:, None]`) is no longer supported. Convert to a numpy array before indexing instead.
917
925
918
926
def matplotlib_plot (
919
927
self ,
928
+ map : bool = True ,
920
929
projection : Optional [str ] = None ,
921
930
color : str = "#101010" ,
922
931
colorbar : bool = False ,
@@ -928,6 +937,7 @@ def matplotlib_plot(
928
937
ascent : Optional [Tuple [float , float ]] = None ,
929
938
pace : Optional [Tuple [float , float ]] = None ,
930
939
speed : Optional [Tuple [float , float ]] = None ,
940
+ elevation_profile : bool = False ,
931
941
file_path : Optional [str ] = None ):
932
942
"""
933
943
Plot GPX using Matplotlib.
@@ -959,23 +969,49 @@ def matplotlib_plot(
959
969
speed : Optional[Tuple[float, float]], optional
960
970
Display speed, by default None
961
971
"""
972
+ # Create dataframe containing data from the GPX file
973
+ self .dataframe = self .to_dataframe (projection = True ,
974
+ elevation = True ,
975
+ speed = True ,
976
+ pace = True ,
977
+ ascent_rate = True ,
978
+ ascent_speed = True ,
979
+ distance_from_start = True )
980
+
962
981
# Create figure with axes
963
982
fig = plt .figure (figsize = (14 , 8 ))
964
- fig .add_subplot (111 )
965
-
966
- # Plot on axes
967
- self .matplotlib_axes_plot (fig .axes [0 ],
968
- projection ,
969
- color ,
970
- colorbar ,
971
- start_stop_colors ,
972
- way_points_color ,
973
- title ,
974
- duration ,
975
- distance ,
976
- ascent ,
977
- pace ,
978
- speed )
983
+
984
+ # Plot map
985
+ if map :
986
+ if elevation_profile :
987
+ fig .add_subplot (2 , 1 , 1 )
988
+ else :
989
+ fig .add_subplot (1 , 1 , 1 )
990
+ self .matplotlib_map_plot (fig .axes [0 ],
991
+ projection ,
992
+ color ,
993
+ colorbar ,
994
+ start_stop_colors ,
995
+ way_points_color ,
996
+ title ,
997
+ duration ,
998
+ distance ,
999
+ ascent ,
1000
+ pace ,
1001
+ speed )
1002
+
1003
+ # Plot elevation profile
1004
+ if elevation_profile :
1005
+ if map :
1006
+ fig .add_subplot (2 , 1 , 2 )
1007
+ axes_idx = 1
1008
+ if colorbar :
1009
+ axes_idx = 2
1010
+ else :
1011
+ fig .add_subplot (1 , 1 , 1 )
1012
+ axes_idx = 0
1013
+ self .matplotlib_elevation_profile_plot (fig .axes [axes_idx ])
1014
+
979
1015
980
1016
# Save or display plot
981
1017
if file_path is not None :
0 commit comments