What's inside
- Project Overview
- Customizing the Plot and Enhancing Visualization
- Conclusion and Future Work
- Reach Out for Professional Python Services
I must confess Python wasn’t part of my university curriculum, and by the third year, I knew only the basics.
Nevertheless, I was aware of this programming language and its capability to enable efficient coding through libraries that achieve remarkable feats with only a few lines of code.
Hence, my choice was to master Python, and what could be a more effective approach than immersing myself in a hands-on practical example?
I chose to try Python’s strength in data visualization in a project that simulated cellular automata. This choice was motivated by the broad applicability of cellular automata in various simulations such as sea surface, road traffic, and fire spread.
In essence, a cellular automaton can be represented as a two-dimensional array of values that change according to established rules based on values in neighboring cells.
Project Overview
In my project, I wanted to simulate the propagation of a sound wave, inspired by this research study: Komatsuzaki T., Iwata Y., Morishita S. (2012) “Modeling Sound Wave Propagation around Sound Barriers Using Cellular Automata”.
Each cell in the model contains information about neighboring cells' current pressure and airflow rate from neighboring cells. In each simulation step, I calculate the new pressure value based on the previous values.
Customizing the Plot and Enhancing Visualization
Initial Visualization with Matplotlib
Now, let's bring in Matplotlib to visualize our 2D data. With Matplotlib, code for drawing a graph takes just a few lines of code.
We simulate a space of 6x4m which gives us 60,000 cells.
We start off by plotting the pressure, which is calculated using a sine function. The imshow()
function displays an array of numbers in the range [-100, 100]. vmin
and vmax
parameters determine the color range.
pressure = [
[
sin(x + y) for x in range(size_x)
] for y in range(size_y)
]
min_presure = -1
max_pressure = 1
ca_plot = plt.imshow(
pressure,
interpolation='bilinear',
vmin=min_presure,
vmax=max_pressure)
plt.colorbar(ca_plot)
plt.show()
Nice! 20 lines in total and we have a plot with GUI that allows us to zoom, pan and save what we see.
Simulation and Visualization of the Sound Wave
Next, we simulate the outflow rate for all cells using the pressure difference.
for i in range(size_y):
for j in range(size_x):
cell_pressure = P[i][j]
V[i][j][0] = V[i][j][0] + cell_pressure - P[i - 1][j] if i > 0 else cell_pressure
V[i][j][1] = V[i][j][1] + cell_pressure - P[i][j + 1] if j < size_x - 1 else cell_pressure
V[i][j][2] = V[i][j][2] + cell_pressure - P[i + 1][j] if i < size_y - 1 else cell_pressure
V[i][j][3] = V[i][j][3] + cell_pressure - P[i][j - 1] if j > 0 else cell_pressure
We then simulate the flow itself - that is, we update the pressure taking in account outflow velocities. A little more code and we can see the result:
for i in range(size_y):
for j in range(size_x):
self.pressure[i][j] -= 0.5 * damping * \
sum(self._velocities[i][j])
# main.py
simulation = Simulation()
for i in range(50):
simulation.step()
ca_plot = plt.imshow(
simulation.pressure,
interpolation='bilinear',
vmin=min_presure,
vmax=max_pressure)
plt.colorbar(ca_plot)
plt.show()
Animation of the Sound Wave Propagation
def animation_func(i):
simulation.step()
ca_plot.set_data(simulation.pressure)
return ca_plot
animation = FuncAnimation(figure, animation_func, interval=1)
An animation would be useful for a better illustration of wave propagation. matplotlib.animation.FuncAnimation
allows us to do just that.
Optimizing the Code and Improving the Animation
At this stage, you might find that the animation is quite slow. We could use numpy.array and start optimizing the code (actually, when I tried that once, the time of a single step increased from 91.5 ms to 279 ms). We can also use CUDA here. But what we want is to generate a film rather than display real-time animation, so let's leave optimization for the next time.
Customizing the Plot
NLet'smaximize the window, add a title, and change the color map. The color map 'seismic' has been chosen here, but there are many other options that can be found in the Matplotlib documentation.
ca_plot = plt.imshow(
simulation.pressure,
cmap='seismic',
interpolation='bilinear',
vmin=min_presure,
vmax=max_pressure)
mng = plt.get_current_fig_manager()
mng.window.showMaximized()
plt.title(f"1 m -> {scale} cells, 1 cell -> {1 / scale}m")
Adding a Soundproof Wall to the Simulation
Next, we add a soundproof wall into our simulation. To do this, we create another array to hold its location. When calculating velocities, we skip the cells that represent the wall.
if wall[i][j] == 1:
V[i][j][0] = V[i][j][1] = V[i][j][2] = V[i][j][3] = 0.0
continue
Recording the Animation as a Video
The last step is to record our animation as a video, which requires the installation of ‘ffmpeg’.
writer = FFMpegWriter(fps=30)
frames = 100
with writer.saving(figure, "writer_test.mp4", 200):
for i in range(frames):
animation_func(i)
writer.grab_frame()
print(f'\rframe: {i}/{frames}', end='')
The Result
Wave propagation - Python cellular automaton
Combining the concepts of Wave Propagation, Cellular Automata and Python, the video is showing how to use Python to model wave propagation using a cellular automaton.
The code is only (!) 120 lines, which is very impressive. It means that the code is relatively concise, making it a good learning resource if you are looking to understand the basic principles without being overwhelmed by a lot of code.
The paper I reference in the video description (“Modeling Sound Wave Propagation around Sound Barriers Using Cellular Automata”, authors Komatsuzaki T., Iwata Y., Morishita S.) provides a foundation and context for the code. If you're interested in understanding the deeper mechanics and scientific rationale behind the simulation, this paper would be a good place to start.
You can find the source code of this project here
Conclusion and Future Work
I was quite pleased with the final result of my project. In the future, I would love to add the capability to draw walls in a graphics editor and then load them into our simulation.
It's also interesting to note that while working on this project, I discovered a similar effort by a group of developers using Java.
However, their code was 1,500 lines long, unlike my 120 lines. This is a testament to Python’s incredible conciseness and the power of Matplotlib.
If you're interested in using Python to its full potential, don't forget to check out these 25 Most Popular Python Machine Learning Libraries and the 9 Best Natural Language Processing Libraries
Thank you for following along with this tutorial.
Stay tuned for future articles where we will continue our exploration of data visualization with Python.
Reach Out for Professional Python Services
As you've seen, Python has immense capabilities, and mastering them can be exciting and rewarding. However, we understand that it can be a challenging task, especially when trying to solve complex problems, or if under a time crunch.
This is where we come in.
As a software house specialized in Python, we're fully equipped to take on projects of any size, helping you navigate through the intricacies of this versatile language. Whether you're seeking to build a powerful data visualization tool like the one we've explored in this blog or need help with machine learning, natural language processing, web development, or any other Python-related tasks, we're ready to assist you. Contact us.