newcohospitality.com

Understanding Digital Signals: Visualizing Them with Python

Written on

Example from the Seaborn graph gallery.

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.
Complete waveform of a song in Garageband.
  • Next, we have a digital signal representing a woman's heartbeat sourced from the MIT-BIH Arrhythmia Database.
Woman's heartbeat represented from two different angles (EKG leads).
  • Here, we see digital signals from both AM and FM radio broadcasts.
Comparison of AM and FM radio signals.
  • 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.
A photo exemplifying a type of digital signal.
  • Lastly, we have an EEG reading during an epileptic seizure.
Electroencephalograph recording of 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:

  1. Explaining the phenomena through frequency and amplitude analysis to identify patterns (essentially time series analysis).
  2. Predicting outcomes based on the data using machine learning and AI techniques.
  3. 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.

Cross spectral density comparison of two digital signals in Matplotlib.

We will visualize a few different signals. Choose any of the following options:

  1. A simple sine wave
  2. Heartbeat data (EKG)
  3. An audio file in .wav format
  4. 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

Graph output of the sine wave.

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.

  1. 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.)

EKG data from the MIT-BIH Arrhythmia Database in CSV format.
  1. 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

  1. 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)

  1. 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()

EKG data from patient 116 visualized in lead II.

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 points
First 1000 data points from patient 116’s EKG showing 4 heartbeats.

This 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.

Photo of a music environment.
  1. 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

  1. 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.

  1. 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.

  1. Prepare the Data for Graphing

We need to perform three tasks:

  1. Extract just the audio data from the opened wavefile.
  2. Obtain the framerate and duration of the wavefile.
  3. 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)
  1. 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:

Initial visualization of audio data, may require adjustments for clarity.

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()

The initial milliseconds of a song visualized in Matplotlib.

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.

Mount Azuma-kofuji, an active stratovolcano in Fukushima.

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.

Seismogram of the Fukushima earthquake from various channels (BH1, BH2, etc.).
  1. 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:

Earthquake data from SAGE Wilber 3 displayed in Excel.

You should observe two columns: one for timestamps and another for the actual seismic data. (We will discard the first eight rows before graphing.)

  1. 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:

  1. Loading the CSV ("fukushima_2016.csv") directly into Pandas.
  2. Skipping the first eight rows (skiprows=8) since they are informational.
  3. Setting the first column (index_col=0) as the index for timestamps.
  4. Automatically converting the timestamps column to datetime format (parse_dates=True).

The output from print(fukushima) should look like:

Cleaned Fukushima earthquake data in Pandas, ready for graphing.
  1. 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:

Earthquake data visualization, may require further refinement.

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.

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.