Let's Build a Flight Tracker Part 4: Explosion in San Francisco
KTVU 2 Helicopter

Let's Build a Flight Tracker Part 4: Explosion in San Francisco

Today in our python tutorial we are going use two new libraries: plotly and pandas. Plotly is a data visualization library and pandas is a statistical data analysis library. Both are very powerful tools. With these two libraries we can display our flight and airports on a beautiful map! I want to create something like an example I found implemented on the plotly website.

No alt text provided for this image
https://plotly.com/python/mapbox-layers/

Meanwhile in Oakland California, a news helicopter just took off. The chopper belongs to KTVU2 News. KTVU is a Fox-affiliated television station. The website for the helicopter is below.

They haven't written anything about today yet. I have no idea why the chopper is in the air. Maybe we are ahead of the story! Lets create our map using their flight data. Fire up the tracker!

[bot@botnet plane]$ python tracker.py A815A1

Create a new python program titled plot.py.

import plotly.express as px
import pandas as pd

Then we build two new Pandas DataFrames.

# Read the data from the "data.csv" file into a Pandas DataFrame
data = pd.read_csv("data.csv")

# Read the airport data from the "GlobalAirportDatabase.csv" file into a Pandas DataFrame
airports = pd.read_csv("GlobalAirportDatabase.csv", header=None)

Add some code to create a boundary for the map. We're going to automatically center the map on the flight path with lon_min, lon_max, lat_min, and lat_max. lat_center and lon_center are the averages of these values where we will center the map. Since the GlobalAirportDatabase.csv file we created has no header, we'll have to assign some names for the columns as well.

# Calculate the minimum and maximum values of longitude and latitud
lon_min = data["Longitude"].min()
lon_max = data["Longitude"].max()
lat_min = data["Latitude"].min()
lat_max = data["Latitude"].max()

# Calculate the center latitude and longitude
lat_center = (lat_min + lat_max) / 2
long_center = (lon_min + lon_max) / 2

# Give the columns of the airport data meaningful names
airports.columns = ["Name1", "Name2", "Name3", "Name4", "Name5", "Latitude", "Longitude"]e

We need to make a scatter plot of the airports and then add another trace on top to map the flight route.

# Create a scatter plot of the airports using Plotly Express
fig = px.scatter_mapbox(airports, text="Name1", lat="Latitude", lon="Longitude", hover_name="Name3",
                        color_discrete_sequence=["fuchsia"], zoom=5, height=600,
                        center={"lat": lat_center, "lon": lon_center})

# Add a line trace to the plot to represent the flight route
fig.add_scattermapbox(
    mode="text+lines", # Add both text labels and lines to the trace
    lat=data['Latitude'], # Latitude values
    lon=data['Longitude'], # Longitude values
    text=data['Time'], # Text labels
    connectgaps=False, # Connect the points in the line trace with lines
    showlegend=False # Do not show a legend for this trace
)

And after that, I want to see each location where the airplane returns "On Ground" equal to "True" so another DataFrame needs to be created on top of the other two.

# Select only the rows in the DataFrame where the "On Ground" column is equal to True
df_on_ground = data[data["On Ground"] == True]

# Add a scatter mapbox trace for the locations where the flight was on the ground
fig.add_scattermapbox(
    lat=df_on_ground["Latitude"], # Latitude values
    lon=df_on_ground["Longitude"], # Longitude values
    mode="markers", # Show markers instead of lines
    marker=dict(
        color="green", # Set marker color to green
        size=10, # Set marker size to 10
        opacity=0.7 # Set marker opacity to 0.7
    ),
    showlegend=False # Do not show a legend for this trace
)

Finally, we set our map style, remove the margins around the plot, and show the plot.

# Set the mapbox style to "open-street-map"
fig.update_layout(mapbox_style="open-street-map")

# Remove the margins around the plot
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})

# Show the plot
fig.show()

Now lets execute the program.

python plot.py

Your browser will open up and instantiate the map.

No alt text provided for this image
Path of KTVU 2 Helicopter on Feb 9, 2023

This is really cool, all of our Airports from GlobalAirportDatabase.csv are displayed here. We no longer have to stare at the console all day!

I zoomed in on the KTVU 2 FOX News helicopter.

No alt text provided for this image

Here is the completed code for plot.py

import plotly.express as px
import pandas as pd

# Read the data from the "data.csv" file into a Pandas DataFrame
data = pd.read_csv("data.csv")

# Read the airport data from the "GlobalAirportDatabase.csv" file into a Pandas DataFrame
airports = pd.read_csv("GlobalAirportDatabase.csv", header=None)

# Calculate the minimum and maximum values of longitude and latitude
lon_min = data["Longitude"].min()
lon_max = data["Longitude"].max()
lat_min = data["Latitude"].min()
lat_max = data["Latitude"].max()

# Calculate the center latitude and longitude
lat_center = (lat_min + lat_max) / 2
lon_center = (lon_min + lon_max) / 2

# Give the columns of the airport data meaningful names
airports.columns = ["Name1", "Name2", "Name3", "Name4", "Name5", "Latitude", "Longitude"]

# Create a scatter plot of the airports using Plotly Express
fig = px.scatter_mapbox(airports, text="Name1", lat="Latitude", lon="Longitude", hover_name="Name3",
                        color_discrete_sequence=["fuchsia"], zoom=10, height=600,
                        center={"lat": lat_center, "lon": lon_center})

# Add a line trace to the plot to represent the flight route
fig.add_scattermapbox(
    mode="text+lines", # Add both text labels and lines to the trace
    lat=data['Latitude'], # Latitude values
    lon=data['Longitude'], # Longitude values
    text=data['Time'], # Text labels
    connectgaps=False, # Connect the points in the line trace with lines
    showlegend=False # Do not show a legend for this trace
)

# Select only the rows in the DataFrame where the "On Ground" column is equal to True
df_on_ground = data[data["On Ground"] == True]

# Add a scatter mapbox trace for the locations where the flight was on the ground
fig.add_scattermapbox(
    lat=df_on_ground["Latitude"], # Latitude values
    lon=df_on_ground["Longitude"], # Longitude values
    mode="markers", # Show markers instead of lines
    marker=dict(
        color="green", # Set marker color to green
        size=10, # Set marker size to 10
        opacity=0.7 # Set marker opacity to 0.7
    ),
    showlegend=False # Do not show a legend for this trace
)

# Set the mapbox style to "open-street-map"
fig.update_layout(mapbox_style="open-street-map")

# Remove the margins around the plot
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})

fig.show()

Update on the story, there is a House Fire in San Francisco, CA. The helicopter is on scene! A heavy fire from an explosion was threatening multiple homes. Ninety firefighters on scene, one person was transported to the hospital with multiple burns. Two firefighters with multiple injuries. The firefighters searched the nearby homes and found "no victims". Thank you Firefighters for your bravery and service.

No alt text provided for this image

The complete story is below. At the time I am writing this article, the cause of the fire is still unknown. Shout out to KTVU FOX 2 for covering this story.

This project is really coming together. Let's take a step back and reorganize things. I moved the haversine() method from tracker.py into it's own file. I did the same for get_nearest_airport(), get_current_time(), and create_datadatabase(). I already discussed these in previous tutorials and don't plan on changing them. My project folder now looks like this.

No alt text provided for this image

This is the current layout. I'm also going to make the project available on my Github. Feel free to play around with the code and suggest improvements like error handling.

More tutorials to come soon - Henry.

要查看或添加评论,请登录

Henry Meier的更多文章

  • Chess Part 2: Finish The Game

    Chess Part 2: Finish The Game

    Welcome back, today we are working on the Front-End. OK, on to the big boy file.

  • Chess Part 1: Multiplayer

    Chess Part 1: Multiplayer

    It's been quite some time since I was able to write an article. Many of my articles have started to blow up so I…

  • Neural Network in C Part 4: Hidden Layer Analysis

    Neural Network in C Part 4: Hidden Layer Analysis

    I want to look under the hood today. Obviously we can see the input layer and output layer.

  • Neural Network in C Part 3: Assembly VS C

    Neural Network in C Part 3: Assembly VS C

    Our Neural Network is fast but we can make it even faster. We will convert the code to assembly, then race the two side…

    2 条评论
  • Neural Network in C Part 2: C Programming

    Neural Network in C Part 2: C Programming

    In this article, we explore how to build a simple feed forward neural network in C to recognize handwritten digits from…

  • Neural Network in C Part 1: Idea

    Neural Network in C Part 1: Idea

    Welcome, normally I enjoy programming in Python and using the TensorFlow library to create machine learning…

  • Free CRM Part 2: Client Notes, Dark Mode, Adding Customers

    Free CRM Part 2: Client Notes, Dark Mode, Adding Customers

    We have a lot of stuff to add to our free CRM software. Small businesses are counting on us! Small businesses don't…

  • Free CRM Part 1: Idea

    Free CRM Part 1: Idea

    Salesforce is expensive. Lets make our own CRM (Customer Relationship Management) software.

  • Firmware Engineering Part 3: OLED Display

    Firmware Engineering Part 3: OLED Display

    The temperature/humidity sensor works. Currently, this device communicates with a website and shares data over MQTT.

  • Firmware Engineering Part 2: Data Logging Website

    Firmware Engineering Part 2: Data Logging Website

    Last article, we wrote a simple MicroPython program for the ESP32. This device broadcasts raw temperature and humidity…

社区洞察

其他会员也浏览了