Understanding Digital Signals: Visualizing Them with Python
Written on
To grasp the concept of digital signals, we should start by examining them in graphical representations.
- The first illustration displays a digital representation of a song created in Garageband.
- Next, we have a digital signal representing a woman's heartbeat sourced from the MIT-BIH Arrhythmia Database.
- Here, we see digital signals from both AM and FM radio broadcasts.
- Additionally, a digital image of a husky qualifies as a digital signal too! Understanding the patterns of the digital signals above will clarify why a photo is categorized as a "digital signal" from both mathematical and neuroscientific viewpoints.
- Lastly, we have an EEG reading during an epileptic seizure.
Generally, when referring to a "digital signal," we mean data lines that fluctuate over time, which can be effectively visualized with graphs. These fluctuations convey phenomena across various fields such as biology, chemistry, and physics.
The primary objectives of analyzing these signals include:
- Explaining the phenomena through frequency and amplitude analysis to identify patterns (essentially time series analysis).
- Predicting outcomes based on the data using machine learning and AI techniques.
- Modulating the signal—this could relate to artistic or musical applications, enhancing aspects like volume, color, and texture, or even altering signals for purposes like cybersecurity and photo forensics.
How to Visualize Digital Signals Using Python
Python offers multiple libraries for creating graphs, including Matplotlib, Seaborn, and Plotly. For this guide, we will utilize Matplotlib.
We will visualize a few different signals. Choose any of the following options:
- A simple sine wave
- Heartbeat data (EKG)
- An audio file in .wav format
- Seismic data from an earthquake
Pre-requisites for Graphing
Before we begin, ensure you have the following installed:
- Python 3
- Matplotlib
- Numpy
- Pandas
You can find installation instructions in the links provided above. If you're using an online platform like Kaggle or Google Colab, these packages are likely pre-installed.
1. Plotting a Sine Wave
The sine wave is the simplest form of a digital signal and serves as the foundational element for other digital signals. We will create the wave using Numpy and visualize it with Matplotlib.
Start by importing the necessary libraries:
# Import libraries for sine wave creation
import numpy as np
import matplotlib.pyplot as plt
Next, we will generate the sine wave:
# Define the wave's amplitude
amplitude = 3
# Define the wave's frequency
frequency = 10
# Define the sampling rate
sampling_rate = 1000
# Define the duration in seconds
duration = 1
# Create an array of timestamps using Numpy
time = np.arange(0, duration, 1/sampling_rate)
# Generate the sine wave
sine_wave = amplitude * np.sin(np.pi * 2 * frequency * time)
This sets the parameters for the sine wave and generates it. A higher sampling rate produces smoother lines, while a lower rate results in jagged lines.
To visualize the sine wave, use Matplotlib's plot() function:
plt.plot(time, sine_wave)
plt.show() # Optional line
To add labels and a title, include these lines before plt.plot():
plt.title("A Sine Wave")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
The complete code for the sine wave graph is:
# Import libraries needed for the sine wave
import numpy as np
import matplotlib.pyplot as plt
# Set the height of the wave
amplitude = 3
# Set the width of the wave
frequency = 10
# Set the sampling rate
sampling_rate = 1000
# Define duration
duration = 1
# Create timestamps
time = np.arange(0, duration, 1/sampling_rate)
# Create sine wave
sine_wave = amplitude * np.sin(np.pi * 2 * frequency * time)
# Plot the sine wave
plt.title("A Sine Wave")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.plot(time, sine_wave)
# plt.show() # Uncomment this if running in command line
2. Plotting Heartbeat Data (EKG)
This section will utilize actual heartbeat data from a real patient. The MIT-BIH Arrhythmia Database contains publicly accessible electrocardiograms (EKGs) from numerous patients. We can leverage Python to read and graph the EKG data.
- Download the EKG Data
Start by acquiring a set of heartbeat data from a patient. The data can be downloaded in CSV format from Kaggle. (The original database is available at Physionet.org, though it can be challenging for beginners to download.)
- Import Pandas
Pandas will simplify the loading and plotting of the data, making it an essential library for any data science work in Python.
To import Pandas, include this at the top of your Python file:
# Our Python file
import pandas as pd
- Load the EKG Data from CSV
After downloading the data, we can open one of the CSVs using Pandas. Choose any of the CSV files (e.g., 100.csv, 109.csv, etc.) and use that filename in your code. We will use 116.csv for this example.
import pandas as pd
# Adding index_col=0 simplifies graphing
ekg = pd.read_csv("116.csv", index_col=0)
- Visualizing the EKG Data
Now that we have the EKG data loaded into Pandas, we can graph it with Matplotlib. However, we first need to determine which specific data to visualize.
Each EKG file contains data from two different leads (two sets of wires from a 12-lead EKG). For this example, we will visualize lead II, as it is considered the primary lead in an EKG.
To graph lead II, use the following code:
import matplotlib.pyplot as plt
ekg["MLII"].plot()
Since ekg is a Pandas object, it knows how to utilize Matplotlib’s plot() function without additional specifications.
The complete code to visualize the EKG is:
import matplotlib.pyplot as plt
import pandas as pd
ekg = pd.read_csv("116.csv", index_col=0)
ekg["MLII"].plot()
The EKG data spans 30 minutes, making it challenging to discern individual heartbeats. We can zoom in on a few heartbeats by modifying the last line of code:
ekg[0:1000]["MLII"].plot() # Plot only the first 1000 data pointsThis code modification allows us to focus on the first 1000 elements of the EKG data array.
For more advanced heartbeat analysis, consider exploring our electrocardiogram analysis series.
3. Plotting a Song (.wav File)
Music recordings are a common type of digital signal. They can exist in various formats (like mp3, FLAC, WAV), but not all formats are easily accessible in Python. We will work with a WAV file, which is relatively straightforward to open using Python’s wave library.
- Import Python’s wave Library
The wave library is included with Python 3 by default. To use it, add import wave at the top of your Python file.
# wave_viewer.py
import wave
- Acquire a WAV File
A WAV file is any file ending with .wav. These can be music tracks, sound effects, or anything else. You can find free WAV files from various online sources, such as Freesound.
- Open the WAV File Using the wave Library
Opening the WAV file is straightforward:
wavefile = wave.open("my_music.wav", "r")This command opens the file for reading.
- Prepare the Data for Graphing
We need to perform three tasks:
- Extract just the audio data from the opened wavefile.
- Obtain the framerate and duration of the wavefile.
- Create an array of timestamps corresponding to the audio length.
To extract the audio data:
# wave_viewer.py
import numpy as np
import wave
wavefile = wave.open("my_music.wav", "r")
frames = wavefile.readframes(-1)
signal = np.fromstring(frames, "int16")
Now, we will obtain the framerate and the data length:
framerate = wavefile.getframerate()
data_length = signal.shape[0]
time_length = data_length / framerate
Finally, we will create an array of timestamps to use as the X-axis:
time = np.linspace(0., time_length, data_length)
- Visualizing the Audio Data
To plot the data, we only need two lines:
plt.plot(time, signal)
plt.show() # Optional if using a notebook
The output will look like this:
The graph may be difficult to interpret due to the volume of data. Let's narrow down the view by modifying the code to plot the first 200 data points:
plt.plot(time[0:200], signal[0:200])
plt.show()
This zoomed-in view makes it easier to understand the data's structure.
Here’s the full code for graphing the WAV file:
# wave_viewer.py
import numpy as np
import wave
# Open the WAV file and extract the signal data
wavefile = wave.open("YOUR_MUSIC_FILE.wav", "r")
frames = wavefile.readframes(-1)
signal = np.fromstring(frames, "int16")
# Get the framerate and data length
framerate = wavefile.getframerate()
data_length = signal.shape[0]
time_length = data_length / framerate
# Create timestamps for graphing
time = np.linspace(0., time_length, data_length)
# Graph the data using Matplotlib
plt.plot(time, signal)
plt.show()
4. Plotting an Earthquake (Seismogram Data)
Let's visualize an earthquake: the 2016 Fukushima earthquake.
We retrieved the seismogram data for this earthquake from the SAGE Wilber 3 online dashboard, which provides earthquake data globally. This specific data originates from a seismic station in Matsushiro, Japan, commencing one minute before the first P wave and continuing for ten minutes. Although Matsushiro is around 300 miles (500 km) from the earthquake's epicenter and therefore less intense, it still recorded measurable activity.
- Download the Data
Downloading data from the original SAGE Wilber 3 dashboard can be complicated, so we have made it available as a CSV on Kaggle.
When you open the CSV in Excel or Google Sheets, it should resemble the following:
You should observe two columns: one for timestamps and another for the actual seismic data. (We will discard the first eight rows before graphing.)
- Open the Data in Python
Similar to the EKG example, we can utilize Pandas to easily open the data. It simplifies working with and visualizing scientific data in Python.
After installing Pandas, create a new Python file with the following code:
import pandas as pd
fukushima = pd.read_csv("fukushima_2016.csv", skiprows=8, index_col=0, parse_dates=True)
print(fukushima)
In this code, we are:
- Loading the CSV ("fukushima_2016.csv") directly into Pandas.
- Skipping the first eight rows (skiprows=8) since they are informational.
- Setting the first column (index_col=0) as the index for timestamps.
- Automatically converting the timestamps column to datetime format (parse_dates=True).
The output from print(fukushima) should look like:
- Visualizing the Earthquake Data
As the data is already formatted as a Pandas object, we can graph it with just three additional lines:
import matplotlib.pyplot as plt
fukushima.plot()
plt.show() # Optional in a notebook environment
The complete code for visualizing the earthquake data is:
# Fukushima 2016 earthquake graph
import matplotlib.pyplot as plt
import pandas as pd
file_path = "YOUR_FUKUSHIMA_CSV_FILE.csv"
fukushima = pd.read_csv(file_path, skiprows=8, index_col=0, parse_dates=True)
fukushima.plot()
plt.show() # Optional if you're in a notebook
The output will look like this:
This plot clearly indicates an earthquake event, though it was recorded 300 miles away in Matsushiro, Japan.
For more data from the Matsushiro seismic station, refer to the SAGE Wilber 3 dashboard.
Other Articles in this Series
This ongoing series on Digital Signal Processing will continue to evolve. Stay tuned for additional articles.
Questions and Feedback
For questions or feedback, reach out at protobioengineering@gmail.com or connect with us on Instagram (@protobioengineering).
If you enjoyed this article, please consider supporting us by buying us a coffee.