During my recent trek in Colombia, my GPS watch battery died. I tried using my phone to track my voyage through the jungle and into the mountains, but honestly, until now I thought this was simply an unsuccessful attempt to track my voyage. I couldn’t view my trek on Garmin like I usually do, and I thought had no data to export.
Recently, as I was clearing the caches and files on my phone, I discovered some GPS data which coincided with my time in Colombia. My plan was to export the data and figure out an elegant way to plot it.
Attacking the Problem
As a follow-up to my last post on visualizing hiking statistics using Python, I decided to use Python to visualize this “missing” Colombia hike. Whereas before, I wanted to glean statistical information off of my hiking dataset, the Python use case here is slightly different. My primary motive here is to solve a problem – which is that I am currently unable to view a map of my hike.
Getting the Data
The first step here was to export the data on my phone as a GPX file, which I was able to do with a free GPS app that has the ability to load the orphaned GPS data on my phone. Once I had the data, it was time to start coding.
Importing the Hikes into Python for Visualization
First, install gpxpy, a GPX parser which you can find on Github.
1 2 3 |
#pip install gpxpy - run this in anaconda prompt import gpxpy import matplotlib.pyplot as plt |
Then, import the exported GPX tracks.
1 |
gpx_file1 = open('C:\\Users\\Desktop\\1. El Cedral to La Pastora.gpx', 'r') |
The parse function allows us to parse the data within the GPX files.
1 |
gpx1=gpxpy.parse(gpx_file1) |
Next, I assign hike titles to strings which I will reference later on.
1 |
gpx_filename1="1: El Cedral to La Pastora" |
We can use loops to load in the latitude and longitude coordinates from each GPX file into separate arrays.
1 2 3 4 5 6 7 8 9 |
lat1=[] lon1=[] for track in gpx1.tracks: for segment in track.segments: for point in segment.points: lat1.append(point.latitude) lon1.append(point.longitude) |
Now that the coordinates are stored in the arrays, I can plot the arrays to draw out my missing trek!
1 2 3 4 5 6 7 8 9 10 |
fig = plt.figure(facecolor = '1') plt.figure(figsize=(20,20)) ax = plt.Axes(fig, [.01,1,2,.01], ) ax1=plt.subplot(331) ax1.set_title("El Cedral to La Pastora") plt.plot(lon1,lat1, color='red') ax1.get_xaxis().set_visible(False) ax1.get_yaxis().set_visible(False) |
Here is what it looks like when you combine all of them into one plot.
This is fantastic! Now, I can see my exact movements for each part of the trek, but there are still two improvements that can be made. First, it would be nice to see all the tracks in one figure, instead of seven separate plots. Also, it would be nice to see the locations of each of these – as of now, they are just drawings without any axes.
Visualizing all GPX Tracks in One Plot
The following piece of code allows us to accomplish this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
from os import listdir from os.path import isfile, join import matplotlib.pyplot as plt import gpxpy data_path = 'C:\\Users\\Desktop' data = [f for f in listdir(data_path) if isfile(join(data_path,f))] lat = [] lon = [] fig = plt.figure(facecolor = '1') plt.figure(figsize=(10,10)) ax = plt.Axes(fig, [0.1, 0.1, 1., 1.], ) ax.set_aspect('equal') ax.set_axis_off() #fig.add_axes(ax) for activity in data: gpx_filename = join(data_path,activity) gpx_file = open(gpx_filename, 'r') gpx = gpxpy.parse(gpx_file) for track in gpx.tracks: for segment in track.segments: for point in segment.points: lat.append(point.latitude) lon.append(point.longitude) plt.plot(lon, lat, color = 'red', lw = 1, alpha = 1) lat = [] lon = [] distance = gpx1.length_2d()+gpx2.length_2d()+gpx3.length_2d()+\ gpx4.length_2d()+gpx5.length_2d()+gpx6.length_2d()+gpx7.length_2d() distance/=1609.344 plt.figtext(.5,.9,'Hiking in Colombia, 2019', fontsize=30, ha='center') plt.figtext(.135,.85,'Days: 4',fontsize=15,ha='left',color='blue') plt.figtext(.135,.82,'Miles: %i' %distance,fontsize=15,ha='left',color='blue') plt.ylabel("Latitude",fontsize=25, ha='center') plt.xlabel("Longitude",fontsize=25, ha='center') |
The finished product looks fantastic! This is exactly what I was looking for when I started this project! I can now see exactly where and how far I traveled during my trek. One final enhancement we can make to this is to distinguish each segment of the trek.
Distinguishing Each Part of the Trek in a Single Plot
Here is the code which allows us to distinguish the individual tracks in a single plot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
from plotly.subplots import make_subplots import plotly.graph_objects as go fig = make_subplots(rows=1, cols=1) for activity in data: gpx_filename = join(data_path,activity) activity2 = activity.rstrip('.gpx') gpx_file = open(gpx_filename, 'r') gpx = gpxpy.parse(gpx_file) for track in gpx.tracks: for segment in track.segments: for point in segment.points: lat.append(point.latitude) lon.append(point.longitude) fig.add_trace( go.Scatter(x=lon, y=lat,name=activity2, hoverinfo='name'), row=1, col=1 ) lat = [] lon = [] fig.update_layout(height=720, width=900, title_text="Hiking, Colombia 2019") fig.show() |
0 Comments