| import matplotlib.pyplot as plt |
| from mpl_toolkits.mplot3d import Axes3D |
| import numpy as np |
|
|
| def read_xyz(filename): |
| """ |
| Reads an XYZ file and returns coordinates and atom types. |
| """ |
| coords = [] |
| atoms = [] |
| with open(filename, 'r') as f: |
| lines = f.readlines() |
| |
| for line in lines[2:]: |
| parts = line.split() |
| atoms.append(parts[0]) |
| coords.append([float(parts[1]), float(parts[2]), float(parts[3])]) |
| return np.array(coords), atoms |
|
|
| def plot_crystal(ax, coords, atoms, title): |
| """ |
| Plots a single crystal in a 3D subplot. |
| """ |
| |
| colors = {'Ti': 'gray', 'O': 'red', 'Ca': 'green', 'Pb': 'black', 'I': 'purple'} |
| |
| |
| |
| for i, atom in enumerate(atoms): |
| color = colors.get(atom, 'blue') |
| ax.scatter(coords[i,0], coords[i,1], coords[i,2], |
| c=color, s=200, edgecolors='k', alpha=0.8) |
| |
| |
| |
| num_atoms = len(coords) |
| for i in range(num_atoms): |
| for j in range(i + 1, num_atoms): |
| dist = np.linalg.norm(coords[i] - coords[j]) |
| |
| if dist < 2.8: |
| ax.plot([coords[i,0], coords[j,0]], |
| [coords[i,1], coords[j,1]], |
| [coords[i,2], coords[j,2]], |
| c='black', linewidth=1, alpha=0.5) |
|
|
| ax.set_title(title) |
| ax.set_xlabel('X') |
| ax.set_ylabel('Y') |
| ax.set_zlabel('Z') |
| |
| |
| ax.set_xlim(-2, 5) |
| ax.set_ylim(-2, 5) |
| ax.set_zlim(-2, 5) |
|
|
| def create_comparison_figure(): |
| |
| |
| noise_pos, atoms = read_xyz("gen_step_00.xyz") |
| final_pos, _ = read_xyz("gen_final.xyz") |
| |
| |
| fig = plt.figure(figsize=(12, 6)) |
| |
| |
| ax1 = fig.add_subplot(121, projection='3d') |
| plot_crystal(ax1, noise_pos, atoms, "Step 0: Random Noise") |
| |
| |
| ax2 = fig.add_subplot(122, projection='3d') |
| plot_crystal(ax2, final_pos, atoms, "Step 50: Generated Crystal") |
| |
| plt.tight_layout() |
| plt.savefig("result_plot.png", dpi=300) |
| print("Saved comparison figure to 'result_plot.png'") |
| plt.show() |
|
|
| if __name__ == "__main__": |
| create_comparison_figure() |