From 495ffd45af8012ef38ffe4ea0c65ee5837bdc89b Mon Sep 17 00:00:00 2001 From: Jie Huang Date: Tue, 12 May 2026 20:40:06 +0300 Subject: [PATCH 1/6] add input_plot.xyz to demostrate how to plot with atoms overlayed --- examples/PTCDA_single/input_plot.xyz | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 examples/PTCDA_single/input_plot.xyz diff --git a/examples/PTCDA_single/input_plot.xyz b/examples/PTCDA_single/input_plot.xyz new file mode 100644 index 00000000..aa604099 --- /dev/null +++ b/examples/PTCDA_single/input_plot.xyz @@ -0,0 +1,40 @@ +38 +Same as PTCDA.xyz for demonstration. You may also select a subset of atoms, such as the top layer in a multilayer structure. + 1 7.045637 6.005613 9.947120 +0.15 + 1 9.897932 2.612194 9.943020 +0.15 + 1 8.275515 4.509521 9.942140 +0.15 + 1 12.336543 10.425948 9.938079 +0.15 + 1 10.715512 12.324056 9.934680 +0.15 + 1 5.466648 7.962514 9.914780 +0.15 + 1 13.565891 8.930334 9.897579 +0.15 + 1 15.144142 6.972851 9.869899 +0.15 + 6 8.460736 9.700870 9.961119 0.0 + 6 11.676272 3.889107 9.958080 0.0 + 6 9.391591 8.577521 9.956319 0.0 + 6 12.150413 5.235732 9.956060 0.0 + 6 8.879125 7.226835 9.953480 0.0 + 6 9.803928 6.100850 9.951800 0.0 + 6 11.219312 6.358704 9.945880 0.0 + 6 8.935446 11.048403 9.945498 0.0 + 6 10.806843 8.835349 9.945320 0.0 + 6 12.627057 2.771961 9.945019 0.0 + 6 11.731363 7.709653 9.932579 0.0 + 6 14.500405 4.381420 9.928359 0.0 + 6 10.264659 3.653138 9.924319 0.0 + 6 7.056579 9.446457 9.921079 0.0 + 6 7.456229 7.025884 9.919660 0.0 + 6 10.348140 11.283277 9.917400 0.0 + 6 7.986501 12.165751 9.914699 0.0 + 6 9.355124 4.729154 9.914160 0.0 + 6 6.111767 10.553017 9.908559 0.0 + 6 11.256785 10.206996 9.908120 0.0 + 6 13.555310 5.488973 9.906280 0.0 + 6 6.563246 8.112073 9.905699 0.0 + 6 13.153859 7.910466 9.873319 0.0 + 6 14.047411 6.822740 9.865199 0.0 + 8 14.000075 3.084865 10.031318 -0.2 + 8 6.611246 11.853327 9.959440 -0.2 + 8 15.736978 4.488921 9.837521 -0.2 + 8 12.372576 1.563458 9.825279 -0.2 + 8 4.874570 10.445600 9.820059 -0.2 + 8 8.241626 13.369424 9.801439 -0.2 From c9dd9d24d30843b85306b5b0ef9da78ff74dff9e Mon Sep 17 00:00:00 2001 From: Jie Huang Date: Tue, 12 May 2026 20:41:26 +0300 Subject: [PATCH 2/6] add a line to demostrate how to plot with atoms overlayed --- examples/PTCDA_single/example_ptcda.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/PTCDA_single/example_ptcda.py b/examples/PTCDA_single/example_ptcda.py index 1a97ed0e..d4e19baf 100644 --- a/examples/PTCDA_single/example_ptcda.py +++ b/examples/PTCDA_single/example_ptcda.py @@ -17,6 +17,7 @@ def example_ptcda_single(): generate_elff_point_charges(["--input", "PTCDA.xyz", "--tip", "s"]) relaxed_scan(["--klat", "0.5", "--charge", "-0.10"]) plot_results(["--klat", "0.5", "--charge", "-0.10", "--arange", "0.5", "2.0", "2", "--df"]) + plot_results(["--klat", "0.5", "--charge", "-0.10", "--arange", "0.5", "2.0", "2", "--df", "--atoms", "--atomSize", "0.5"]) if __name__ == "__main__": From 41895021374d51f98c19c9c959286121b27bb145 Mon Sep 17 00:00:00 2001 From: Jie Huang Date: Tue, 12 May 2026 20:42:10 +0300 Subject: [PATCH 3/6] add a line to demostrate how to plot with atoms overlayed --- examples/PTCDA_single/run.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/PTCDA_single/run.sh b/examples/PTCDA_single/run.sh index 6ab3d282..e63876ba 100755 --- a/examples/PTCDA_single/run.sh +++ b/examples/PTCDA_single/run.sh @@ -9,3 +9,6 @@ ppafm-relaxed-scan -k 0.5 -q -0.10 # ======= STEP 3 : Plot the results ppafm-plot-results -k 0.5 -q -0.10 --arange 0.5 2.0 2 --df + +# ======= STEP 4 : Plot the results with atoms overlayed +ppafm-plot-results -k 0.5 -q -0.10 --arange 0.5 2.0 2 --df --atoms --atomSize 0.15 From 35ad1495aabd5c2b9d54dd011a031e4360669ed6 Mon Sep 17 00:00:00 2001 From: Jie Huang Date: Tue, 12 May 2026 20:43:41 +0300 Subject: [PATCH 4/6] add atomSize keyword to fix issue #389 --- ppafm/cli/plot_results.py | 52 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/ppafm/cli/plot_results.py b/ppafm/cli/plot_results.py index a5d68c60..be7f83bf 100644 --- a/ppafm/cli/plot_results.py +++ b/ppafm/cli/plot_results.py @@ -17,27 +17,25 @@ # this makes it run without Xserver (e.g. on supercomputer) # see http://stackoverflow.com/questions/4931376/generating-matplotlib-graphs-without-a-running-x-server -atom_size = 0.15 - - def main(argv=None): # fmt: off parser = common.CLIParser( description="Plot results for a scan with a specified charge, amplitude, and spring constant.Images are saved in folder Q{charge}K{klat}/Amp{Amplitude}." ) parser.add_arguments(["output_format","Amplitude","arange","klat","krange","charge", "qrange", "Vbias", "Vrange", "noPBC", ]) - parser.add_argument( "--iets", action="store", type=float, help="Mass [a.u.]; Bias offset [eV]; Peak width [eV] ", nargs=3, ) - parser.add_argument( "--LCPD_maps", action="store_true", help="Print LCPD maps") - parser.add_argument( "--z0", action="store", type=float, default=0.0, help="Height of the topmost layer of metallic substrate for E to V conversion (Ang)", ) - parser.add_argument( "--V0", action="store", type=float, default=0.0, help="Empirical LCPD maxima shift due to mesoscopic workfunction diference", ) - parser.add_argument( "--df", action="store_true", help="Plot images for dfz ") - parser.add_argument( "--save_df", action="store_true", help="Save frequency shift as df.xsf " ) - parser.add_argument( "--Laplace", action="store_true", help="Plot Laplace-filtered images and save them ", ) - parser.add_argument( "--Fz", action="store_true", help="Plot images for z-component of the (short-range) force acting on the tip in eV/Angstrom") - parser.add_argument( "--pos", action="store_true", help="Save probe particle positions" ) - parser.add_argument( "--atoms", action="store_true", help="Plot atoms to images") - parser.add_argument( "--bonds", action="store_true", help="Plot bonds to images") - parser.add_argument( "--cbar", action="store_true", help="Plot colorbars to images") - parser.add_argument( "--WSxM", action="store_true", help="Save frequency shift into WsXM *.dat files" ) - parser.add_argument( "--bI", action="store_true", help="Plot images for Boltzmann current" ) + parser.add_argument( "--iets", action="store", type=float, help="Mass [a.u.]; Bias offset [eV]; Peak width [eV] ", nargs=3, ) + parser.add_argument( "--LCPD_maps", action="store_true", help="Print LCPD maps") + parser.add_argument( "--z0", action="store", type=float, default=0.0, help="Height of the topmost layer of metallic substrate for E to V conversion (Ang)", ) + parser.add_argument( "--V0", action="store", type=float, default=0.0, help="Empirical LCPD maxima shift due to mesoscopic workfunction diference", ) + parser.add_argument( "--df", action="store_true", help="Plot images for dfz ") + parser.add_argument( "--save_df", action="store_true", help="Save frequency shift as df.xsf " ) + parser.add_argument( "--Laplace", action="store_true", help="Plot Laplace-filtered images and save them ", ) + parser.add_argument( "--Fz", action="store_true", help="Plot images for z-component of the (short-range) force acting on the tip in eV/Angstrom") + parser.add_argument( "--pos", action="store_true", help="Save probe particle positions" ) + parser.add_argument( "--atoms", action="store_true", help="Plot atoms to images") + parser.add_argument( "--atomSize", action="store", type=float, default=0.15, help="Size of atoms in the plot") + parser.add_argument( "--bonds", action="store_true", help="Plot bonds to images") + parser.add_argument( "--cbar", action="store_true", help="Plot colorbars to images") + parser.add_argument( "--WSxM", action="store_true", help="Save frequency shift into WsXM *.dat files" ) + parser.add_argument( "--bI", action="store_true", help="Plot images for Boltzmann current" ) # fmt: on parameters = common.PpafmParameters.from_file("params.ini") @@ -146,7 +144,7 @@ def main(argv=None): extent=extent, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, markersize=2.0, cbar=opt_dict["cbar"], ) @@ -167,7 +165,7 @@ def main(argv=None): extent=extent, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], ) @@ -178,7 +176,7 @@ def main(argv=None): extent=extent, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], ) @@ -189,7 +187,7 @@ def main(argv=None): extent=extent, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], ) @@ -203,7 +201,7 @@ def main(argv=None): extent=extent, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], ) @@ -329,7 +327,7 @@ def main(argv=None): cmap=parameters.colorscale, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], cbar_label="df [Hz]", ) @@ -354,7 +352,7 @@ def main(argv=None): cmap=parameters.colorscale, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], ) @@ -386,7 +384,7 @@ def main(argv=None): cmap=parameters.colorscale_kpfm, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], symmetric_map=True, V0=args.V0, @@ -401,7 +399,7 @@ def main(argv=None): cmap=parameters.colorscale_kpfm, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], symmetric_map=False, cbar_label="V_LCPD [V]", @@ -436,7 +434,7 @@ def main(argv=None): cmap=parameters.colorscale, atoms=atoms, bonds=bonds, - atomSize=atom_size, + atomSize=args.atomSize, cbar=opt_dict["cbar"], cbar_label="Fz [eV/Angstrom]", ) From 9bf5730205e176f208675da6aa164e93930e26f4 Mon Sep 17 00:00:00 2001 From: Jie Huang Date: Tue, 12 May 2026 20:46:50 +0300 Subject: [PATCH 5/6] set default size to 0.15 --- examples/PTCDA_single/example_ptcda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/PTCDA_single/example_ptcda.py b/examples/PTCDA_single/example_ptcda.py index d4e19baf..96bb4a7f 100644 --- a/examples/PTCDA_single/example_ptcda.py +++ b/examples/PTCDA_single/example_ptcda.py @@ -17,7 +17,7 @@ def example_ptcda_single(): generate_elff_point_charges(["--input", "PTCDA.xyz", "--tip", "s"]) relaxed_scan(["--klat", "0.5", "--charge", "-0.10"]) plot_results(["--klat", "0.5", "--charge", "-0.10", "--arange", "0.5", "2.0", "2", "--df"]) - plot_results(["--klat", "0.5", "--charge", "-0.10", "--arange", "0.5", "2.0", "2", "--df", "--atoms", "--atomSize", "0.5"]) + plot_results(["--klat", "0.5", "--charge", "-0.10", "--arange", "0.5", "2.0", "2", "--df", "--atoms", "--atomSize", "0.15"]) if __name__ == "__main__": From dc4cdcf464da5b10a6b32122d11f189bfe657ccd Mon Sep 17 00:00:00 2001 From: Jie Huang Date: Tue, 12 May 2026 20:54:56 +0300 Subject: [PATCH 6/6] formating --- ppafm/cli/plot_results.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ppafm/cli/plot_results.py b/ppafm/cli/plot_results.py index be7f83bf..658c03d3 100644 --- a/ppafm/cli/plot_results.py +++ b/ppafm/cli/plot_results.py @@ -21,21 +21,21 @@ def main(argv=None): # fmt: off parser = common.CLIParser( description="Plot results for a scan with a specified charge, amplitude, and spring constant.Images are saved in folder Q{charge}K{klat}/Amp{Amplitude}." ) parser.add_arguments(["output_format","Amplitude","arange","klat","krange","charge", "qrange", "Vbias", "Vrange", "noPBC", ]) - parser.add_argument( "--iets", action="store", type=float, help="Mass [a.u.]; Bias offset [eV]; Peak width [eV] ", nargs=3, ) - parser.add_argument( "--LCPD_maps", action="store_true", help="Print LCPD maps") - parser.add_argument( "--z0", action="store", type=float, default=0.0, help="Height of the topmost layer of metallic substrate for E to V conversion (Ang)", ) - parser.add_argument( "--V0", action="store", type=float, default=0.0, help="Empirical LCPD maxima shift due to mesoscopic workfunction diference", ) - parser.add_argument( "--df", action="store_true", help="Plot images for dfz ") - parser.add_argument( "--save_df", action="store_true", help="Save frequency shift as df.xsf " ) - parser.add_argument( "--Laplace", action="store_true", help="Plot Laplace-filtered images and save them ", ) - parser.add_argument( "--Fz", action="store_true", help="Plot images for z-component of the (short-range) force acting on the tip in eV/Angstrom") - parser.add_argument( "--pos", action="store_true", help="Save probe particle positions" ) - parser.add_argument( "--atoms", action="store_true", help="Plot atoms to images") - parser.add_argument( "--atomSize", action="store", type=float, default=0.15, help="Size of atoms in the plot") - parser.add_argument( "--bonds", action="store_true", help="Plot bonds to images") - parser.add_argument( "--cbar", action="store_true", help="Plot colorbars to images") - parser.add_argument( "--WSxM", action="store_true", help="Save frequency shift into WsXM *.dat files" ) - parser.add_argument( "--bI", action="store_true", help="Plot images for Boltzmann current" ) + parser.add_argument( "--iets", action="store", type=float, help="Mass [a.u.]; Bias offset [eV]; Peak width [eV] ", nargs=3, ) + parser.add_argument( "--LCPD_maps", action="store_true", help="Print LCPD maps") + parser.add_argument( "--z0", action="store", type=float, default=0.0, help="Height of the topmost layer of metallic substrate for E to V conversion (Ang)", ) + parser.add_argument( "--V0", action="store", type=float, default=0.0, help="Empirical LCPD maxima shift due to mesoscopic workfunction diference", ) + parser.add_argument( "--df", action="store_true", help="Plot images for dfz ") + parser.add_argument( "--save_df", action="store_true", help="Save frequency shift as df.xsf " ) + parser.add_argument( "--Laplace", action="store_true", help="Plot Laplace-filtered images and save them ", ) + parser.add_argument( "--Fz", action="store_true", help="Plot images for z-component of the (short-range) force acting on the tip in eV/Angstrom") + parser.add_argument( "--pos", action="store_true", help="Save probe particle positions" ) + parser.add_argument( "--atoms", action="store_true", help="Plot atoms to images") + parser.add_argument( "--atomSize", action="store", type=float, default=0.15, help="Size of atoms in images") + parser.add_argument( "--bonds", action="store_true", help="Plot bonds to images") + parser.add_argument( "--cbar", action="store_true", help="Plot colorbars to images") + parser.add_argument( "--WSxM", action="store_true", help="Save frequency shift into WsXM *.dat files" ) + parser.add_argument( "--bI", action="store_true", help="Plot images for Boltzmann current" ) # fmt: on parameters = common.PpafmParameters.from_file("params.ini")