.xvg is the plain-text output written by GROMACS analysis tools (and read by Grace/xmgrace). Knowing its structure explains what this tool does automatically.
Comment & metadata lines
Lines starting with # are comments; lines starting with @ are Grace formatting commands. This tool reads @ title, @ xaxis label, @ yaxis label and @ sN legend to label the plot, and skips everything else, so the raw numeric matrix is all that gets plotted. A line starting with & ends one data set, and a file may hold several: each is plotted as series of its own, against its own first column, under the legend GROMACS and Grace give it (sets are numbered through the file as xmgrace -nxy numbers them, so two columns in two sets are s0 and s1). A row with text in it, an empty cell in a CSV, or a different number of values from most rows is skipped whole and counted in the file summary at the top of the settings, so no value moves into the wrong column. A comma at the end of every row is ignored.
The data block
Below the metadata is a whitespace-separated numeric table: the first column is usually the independent variable (time, distance, reaction coordinate) and each remaining column a data series. Common outputs include RMSD (gmx rms), radius of gyration (gmx gyrate), and PMF/free-energy profiles.
Reproducing in Python
The Python script reads the file with numpy.loadtxt(..., comments=['@', '#', '&']), which is the idiomatic way to read an .xvg: the comments argument makes NumPy skip exactly the metadata lines and set breaks described above, leaving the numeric matrix. A file of several data sets is read set by set instead, the rows between its & lines into an array each, so that each series is drawn from its own rows. For a comma-separated file it also passes delimiter=',' and skips the header row. If the file has skipped rows among the numbers, the script passes loadtxt only the lines that are all numbers, so it reads the same rows as the plot. A running mean is numpy.convolve with a window of equal weights, and a lower panel is a second axes from plt.subplots(2, 1, sharex=True). The script sets the same fonts, sizes, colours, ticks and legend as the preview, which is drawn to match matplotlib 3.11 (the script runs on 3.6 and later).