How the Rh visit map is made: 8 steps
Where does the Rh atom spend its time on the α-Al₂O₃ surface? This page shows how 240,000 MD frames become one contour map.
All 8 steps at a glance
1Collect the Rh positions
traj = Trajectory(path)
irh = traj[0].get_chemical_symbols().index("Rh")
frames = [int(i) for i in indices.read_text().split()] if indices else range(0, len(traj), stride)
rh += [traj[i].positions[irh] for i in frames]plot_rh_on_slab_map.py, lines 57–60
- The code opens each trajectory, chains A to E.
- It finds the Rh atom.
- It keeps the Rh position from every frame.
- The result is 240,000 positions. Each dot is one frame.
2Change to cell fractions
frac = np.linalg.solve(cell.T, load_rh_positions(args.traj, stride=args.stride).T).T[:, :2] % 1.0plot_rh_visit_maps.py, line 185
- The cell is slanted. A square is easier to divide into bins.
- The code writes each position as fractions of the two cell vectors,
uandv. % 1.0keeps only the part after the decimal point. This puts every dot back inside one cell.- Now the cell is a square from 0 to 1. The orange lines show the bin grid. Only every 6th line is drawn.
3Count the frames in each bin
hist, _, _ = np.histogram2d(frac[:, 0], frac[:, 1], bins=N_BINS, range=[[0, 1], [0, 1]])plot_rh_visit_maps.py, line 186
- The code divides the square into 60 × 60 bins.
- It counts the dots in each bin.
- Dark bins have many frames. White bins have zero or few frames.
4Blur the counts and turn them into shares
p = gaussian_filter(d["hist"], 1.0, mode="wrap")
p /= p.sum()plot_rh_visit_maps.py, lines 75–76
- The first line blurs the counts by about 1 bin. This removes single-bin noise.
mode="wrap"makes the blur continue across the cell edges. The right edge touches the left edge, and the top edge touches the bottom edge.- The second line divides by the total. Now each bin holds its share of the time, and all the bins add up to 1.
5Sort the bins and find the three cut values
order = np.sort(p.ravel())[::-1]
cum = np.cumsum(order)
def threshold(q):
return order[np.searchsorted(cum, q / 100)]
thresholds = [threshold(q) for q in levels]plot_rh_visit_maps.py, lines 77–83
- The first line sorts all 3,600 bins, with the busiest bin first.
- The second line adds up the time, one bin at a time. This running total is the black curve.
threshold(q)finds the bin where the running total reachesqpercent. The share in that bin is the cut value.- The result is three cut values, one each for 50 %, 75 % and 95 %.
- The curve shows that 50 % of the time falls in only 14 % of the bins.
6Colour each bin by its band
- This picture is only for teaching. The real plot does not draw it.
- Each bin gets a colour from its share:
- dark: above the 50 % cut
- medium: between the 75 % and 50 % cuts
- light: between the 95 % and 75 % cuts
- white: below the 95 % cut
- The shapes are blocky because each bin is a square.
- The dark bins are in several places. Together they hold 50 % of the time.
7Draw smooth contour lines at the cut values
periodic_contour(ax, d["cell"], p, True, levels=thresholds + [p.max()], colors=colors, alpha=0.85)
periodic_contour(ax, d["cell"], p, False, levels=thresholds, colors="k", linewidths=0.6)plot_rh_visit_maps.py, lines 85–86
- The first line fills the space between the cut values with the three colours.
- The second line draws a black line at each cut value.
- Matplotlib puts each line between two bin centres by linear interpolation. This makes the lines smooth instead of blocky.
- Each band holds the same bins as in Step 6. Only the edges change.
8Put the square back on the slanted cell, repeated 3 × 3
def periodic_contour(ax, cell, values, filled, **kw):
"""contour(f) of a fractional-grid array at bin centres, on one 3x3 periodic tiling of the cell."""
centres = (np.arange(3 * N_BINS) + 0.5) / N_BINS - 1
u, v = np.meshgrid(centres, centres, indexing="ij")
x = u * cell[0, 0] + v * cell[1, 0]
y = u * cell[0, 1] + v * cell[1, 1]
draw = ax.contourf if filled else ax.contour
return draw(x, y, np.tile(values, (3, 3)), zorder=2 if filled else 3, **kw)plot_rh_visit_maps.py, lines 45–52
np.tile(values, (3, 3))copies the square 3 times across and 3 times up.centresruns from −1 to 2, so the copies sit next to each other.- The
xandylines change each point from(u, v)back to real(x, y)in Å. This makes the square slanted again. - The lines continue across the cell edges because the code draws all 9 copies in one call.
- The code then adds the cell outline and the Al1, Al2 and Al3 sites.
One sentence to remember: the 50 % region is the set of busiest bins that hold half of the time, so it can be in several places.
How this page is written: ASD-STE100
The request
“can you visualise each step by step in a easier way along with the code responsible for that? use ASD-STE100. I have ADHD.”
What ASD-STE100 is
- ASD-STE100 is Simplified Technical English.
- The aerospace and defence industry made it for maintenance manuals.
- Its goal is text that a reader cannot misread.
- It removes two problems: words with more than one meaning, and sentences with more than one structure.
How it is used here
- Each step has one picture, the code that does the step, and a few short sentences.
- The text uses a light form of the standard for explanations. All the sentence rules apply. The word rules are a guide only, so the text does not read like a robot.
- This helps a reader with ADHD: one idea per line, a clear order, and no hidden steps.
The rules, with examples
| Rule | Written like this | Not like this |
|---|---|---|
| One action per sentence | Sort the bins. Add up the time. | Sort the bins and then add up the time, which gives the running total that we use for the cuts. |
| Short sentences (≤ 20 words for steps) | It counts the dots in each bin. | The histogram routine is then applied over the fractional coordinates to obtain per-bin occupation counts. |
| Active voice | The code divides the square into 60 × 60 bins. | The square is divided into 60 × 60 bins. |
| Verb, not noun | The first line blurs the counts. | Gaussian smoothing is performed on the counts. |
| No phrasal verbs | The code adds the cell outline. | The code throws in the cell outline. |
| No semicolons | The cell is slanted. A square is easier to divide into bins. | The cell is slanted; a square is easier to bin. |
| Lists for 3 or more items | Dark / medium / light / white as a list (Step 6). | All four colour rules in one long sentence. |
| One name for one thing | Always “bin”. | “bin”, then “cell”, then “pixel” for the same square. |
| Keep hedges as they are | “about 1 bin”, “zero or few frames”. | Turning “about” or “few” into an exact claim the code does not make. |
The “not like this” column shows typical alternatives, written for comparison.