Visualization Tutorial — Droplet Surface and Contact Angle
This tutorial demonstrates how to visualize a droplet and compute its contact angle using the wetting_angle_kit package. We’ll use the slicing contact angle method and visualize the resulting droplet with the DropletSlicePlotter class.
1. Overview
The visualization workflow involves the following steps:
Parse atomic positions from a trajectory file.
Identify water molecules (oxygen and hydrogen atoms).
Compute the droplet surface and contact angle using the slicing method.
Visualize the droplet, fitted circle, tangent, and wall.
2. Import Required Modules
import numpy as np
from wetting_angle_kit.parsers import (
LammpsDumpParser,
LammpsDumpWaterFinder,
LammpsDumpWallParser,
)
from wetting_angle_kit.analysis.slicing import SlicingFrameFitter
from wetting_angle_kit.visualization import DropletSlicePlotter
3. Define the Input Trajectory
filename = (
"../wetting_angle_kit/tests/trajectories/traj_10_3_330w_nve_4k_reajust.lammpstrj"
)
4. Identify Water Molecules
wat_find = LammpsDumpWaterFinder(
filename, particle_type_wall={3}, oxygen_type=1, hydrogen_type=2
)
oxygen_indices = wat_find.get_water_oxygen_ids(frame_index=0)
print("Number of water molecules detected:", len(oxygen_indices))
5. Parse Atomic Coordinates
parser = LammpsDumpParser(filepath=filename)
oxygen_position = parser.parse(frame_index=10, indices=oxygen_indices)
# Wall parser: ``liquid_particle_types`` lists everything the parser
# should *exclude* (so that what remains are the wall atoms).
coord_wall = LammpsDumpWallParser(filename, liquid_particle_types=[1, 2])
wall_coords = coord_wall.parse(frame_index=10)
6. Compute Contact Angles
processor = SlicingFrameFitter(
liquid_coordinates=oxygen_position,
liquid_geom_center=np.mean(oxygen_position, axis=0),
droplet_geometry="cylinder_y",
delta_cylinder=5,
max_dist=100,
)
list_angles, array_surfaces, array_popt = processor.predict_contact_angle()
print("Mean contact angles (°):", list_angles)
7. Visualize the Droplet
plotter = DropletSlicePlotter(center=True)
# ``predict_contact_angle`` returns three parallel lists (one entry per
# slice that produced a usable angle); pick a single index across all
# three so the overlay refers to one and the same slice.
slice_idx = 0
fig = plotter.plot_surface_points(
oxygen_position=oxygen_position,
surface_data=[array_surfaces[slice_idx]],
popt=array_popt[slice_idx],
wall_coords=wall_coords,
alpha=list_angles[slice_idx],
)
# Interactive view in a notebook
fig.show()
# Or save a standalone HTML page
fig.write_html("droplet_plot.html")
print("Plot saved as 'droplet_plot.html'")