How can I wrap a soundwave plot into a circle or radial?

321 views Asked by At

My first ever post, and I’m a relatively new coder.

I’m interested in data visualisation, and I’m trying to create a poster that can depict a Soundwave in a circular format.

I’ve tried to attach a photoshop mock-up of what I’m aiming for, but I’m new and so I don’t have enough status points for images (will try and host elsewhere and link back to a URL)

Is there a way to take a plot and wrap into a circular format directly from a plotting library? I’ve searched high and low for the right code, but can’t seem to pin down something that works for sound wave plots.

I could export a normal wave plot and “wrap to polar” in photoshop, or some other Python code that wraps “images” or plots using a different library, but I’m wondering if I’m missing something obvious with built-in plotting options.

I’ve searched the matplotlib documentation (perhaps not very well, I am new to coding) and can only find references to circular bar plots and radar charts. Not found a way that stands out (to me) how to take any similar arguments and apply to a Soundwave.

Bonus points if the same could be done for spectrographs! Thank you!

enter image description here

Many thanks in advance, all guidance gratefully received.

1

There are 1 answers

1
Kat On BEST ANSWER

You really should, at a minimum, include the code you've attempted to accomplish this task and what went wrong. This forum is really for help, not so much do it for me.

However, if you had any line data, you could make it a polar graph.

To make this happen in Plotly, if the amplitude is on the y-axis, you need to scale the x-axis values to a range of 0-360 (like degrees in a circle).

This is a basic UDF to rescale data, where old and new lows and highs are the ranges of the current scale and the future scale.

def newScale(oldLow, oldHigh, newLow, newHigh, arr):
    """change scale, where `arr` is a numeric value to be rescaled"""
    return(newLow + (newHigh - newLow) * (arr - oldLow)/(oldHigh - oldLow))

It might look something like this:

import plotly.graph_objects as go

# - import data

# x_data =...
# y_data =...

# - rescale x_data

orig_min = min(x_data)
orig_max = max(x_data)

x_rescaled = [newScale(orig_min, orig_max, 0, 360, xer) for xer in x_data]

# - make a graph with data
fig = go.Figure()

fig.add_trace(go.Scatterpolar(r = y_data, theta = x_rescaled, mode = "lines"))

fig.show()

As a polar graph (using the code above) in both (the right graph has 1/3 the data)

enter image description here enter image description here

This is what it would have looked like as a line graph:

enter image description here

If you wanted concentric rings of audio data like your image, you would scale the y-axis, as well. The scale you would use depends on the data, where the goal is that the scales do not overlap.