PyMOL Scripting for Beginners: Automate Repetitive Tasks with Python

PyMOL Scripting for Beginners: Automate Repetitive Tasks with Python

If you’ve typed the same ten PyMOL commands more than twice, you’re ready to script. PyMOL’s scripting environment is Python — which means every Python skill you already have translates directly. This tutorial takes you from your first saved script to a fully automated figure-generation pipeline.

Why scripting transforms your PyMOL workflow

Consider what happens when a reviewer asks you to change the color of one figure panel, regenerate it at higher resolution, and add a distance measurement you didn’t show originally. Without a script, this means reconstructing the scene from memory — reloading the structure, reapplying all the coloring and settings, finding the orientation again, and exporting. With a script, it’s editing three lines and running it again.

Scripting also enables tasks that are simply impossible by hand: generating a consistent figure for every structure in a dataset of 50 proteins, labeling every residue in a selection automatically, or printing a table of pLDDT values for all binding site residues across multiple AlphaFold models. The jump from interactive to scripted PyMOL is one of the highest-leverage skill upgrades available to a structural biologist.

Two scripting approaches: .pml and Python

Simpler — start here
.pml scripts
  • Plain text file of PyMOL commands, one per line
  • Exactly the commands you’d type in the command line
  • Can include Python code inline
  • Run with: @script.pml or pymol -c script.pml
  • Best for: figure generation, scene setup, reproducible workflows
More powerful
.py scripts
  • Full Python scripts using the pymol module
  • Access to all Python libraries (os, glob, pandas, etc.)
  • Run with: pymol -c script.py or imported as a module
  • Required for: batch processing, data extraction, conditional logic
  • Best for: automating analysis across multiple structures
They’re the same environment
A .pml file runs in PyMOL’s command environment, which is Python. You can mix PyMOL commands and Python code freely in a .pml file. The distinction is mostly convention — use .pml for scripts that are primarily PyMOL commands with occasional Python, and .py when the script is primarily Python logic that calls PyMOL functions.

Your first .pml script

Open any text editor — VS Code, Notepad, TextEdit — and save the following as figure1.pml. Every line is a PyMOL command you could type interactively, but saved so you can run the whole sequence in one step.

figure1.pml Color-coded by section
Setup
fetch 4XYZ
as cartoon
hide everything, resn HOH
remove resn HOH
Color
util.cbc
set cartoon_fancy_helices, 1
set cartoon_smooth_loops, 1
Figure
bg_color white
set ray_opaque_background, 1
set ambient, 0.40
set specular, 0.25
orient
Export
png figure1.png, width=1200, height=900, dpi=300, ray=1

Run it two ways:

Option A — run from inside PyMOL
# Type in the PyMOL command line
@/path/to/figure1.pml
Option B — run headless from terminal (no GUI)
# -c flag = command-line mode (no viewer window)
pymol -c figure1.pml

# Output PNG is saved to your working directory

The -c flag is the key to automation — it runs PyMOL without opening any windows, executes the script, saves the output file, and exits. This means you can run PyMOL figure generation as part of any shell script or pipeline without any manual interaction.

Running Python commands in PyMOL

Any Python code can be run directly in the PyMOL command line or embedded in a .pml file. PyMOL commands are available as functions through the cmd module:

PyMOL command line — Python examples
# Python runs directly in the PyMOL command line
print("Hello from Python inside PyMOL")

# PyMOL commands are callable as Python functions via cmd
cmd.fetch("4XYZ")
cmd.color("slate", "chain A")
cmd.show("surface", "chain A")

# Use Python variables in PyMOL commands
structure = "4XYZ"
chain = "A"
cmd.fetch(structure)
cmd.color("blue", f"chain {chain}")

# Python control flow inside PyMOL
for color, chain in [("slate", "A"), ("salmon", "B"), ("palegreen", "C")]:
    cmd.color(color, f"chain {chain}")
cmd. vs plain command — what’s the difference?
In the PyMOL command line, color slate, chain A and cmd.color("slate", "chain A") do exactly the same thing. The cmd. prefix is the Python API version — required inside Python scripts or when using variables. In .pml files you can use either; in .py files you must use cmd..

Iterating over residues and structures

One of the most useful scripting patterns is extracting per-residue data from PyMOL — pLDDT values, RMSD per residue, or atom positions. PyMOL’s iterate command walks every atom matching a selection and runs Python code for each one.

PyMOL command line / .pml script
# Print residue number and pLDDT (B-factor) for each Cα
iterate name CA, print(resi, resn, b)

# Collect pLDDT values into a Python list
stored.plddt = []
iterate (chain A and name CA), stored.plddt.append((resi, b))
print(stored.plddt[:5])   # first 5 entries

# Calculate mean pLDDT of a selection
stored.vals = []
iterate (resi 100-200 and name CA), stored.vals.append(b)
mean_plddt = sum(stored.vals) / len(stored.vals)
print(f"Mean pLDDT: {mean_plddt:.1f}")
What is stored.?
stored is a special PyMOL object designed specifically for passing data between iterate expressions (which run in a restricted scope) and your Python code. Always use stored.list_name = [] before an iterate call, then stored.list_name.append(value) inside it. Any Python variable name works after the dot — stored.plddt, stored.coords, stored.anything.

Batch figure generation

The most powerful application of PyMOL scripting is generating consistent figures for a set of structures automatically. This script fetches a list of PDB IDs, applies identical coloring and settings, and saves one PNG per structure:

batch_figures.py — generate figures for a list of structures
Run with: pymol -c batch_figures.py
# batch_figures.py
from pymol import cmd
import os

# List of PDB IDs to process
structures = ["4XYZ", "5ABC", "6DEF", "7GHI"]
output_dir = "./figures"
os.makedirs(output_dir, exist_ok=True)

# Figure settings — apply once, reuse for every structure
def setup_figure():
    cmd.bg_color("white")
    cmd.set("ray_opaque_background", 1)
    cmd.set("cartoon_fancy_helices", 1)
    cmd.set("ambient", 0.40)
    cmd.set("specular", 0.25)
    cmd.set("light_count", 4)
    cmd.set("antialias", 2)

for pdb_id in structures:
    # Load structure
    cmd.reinitialize()           # fresh state for each structure
    cmd.fetch(pdb_id)
    cmd.as_cartoon()
    cmd.hide("everything", "resn HOH")

    # Color by chain
    cmd.util.cbc()

    # Apply figure settings
    setup_figure()
    cmd.orient()

    # Export
    output_path = f"{output_dir}/{pdb_id}.png"
    cmd.png(output_path, width=1200, height=900, dpi=300, ray=1)
    print(f"Saved: {output_path}")

Run this script and it generates one 300 DPI publication-quality PNG for each structure, all with identical settings, in seconds. The same pattern works for any dataset — AlphaFold models, docking results, MD snapshots — just swap the structure list and loading method.

The cmd API — essential functions

Python functionEquivalent command
cmd.fetch(“4XYZ”)fetch 4XYZ
cmd.load(“file.pdb”, “name”)load file.pdb, name
cmd.select(“sel”, “chain A”)select sel, chain A
cmd.color(“slate”, “chain A”)color slate, chain A
cmd.show(“surface”, “sel”)show surface, sel
cmd.hide(“cartoon”, “sel”)hide cartoon, sel
cmd.set(“ambient”, 0.4)set ambient, 0.4
cmd.spectrum(“b”, “blue_red”)spectrum b, blue_red
cmd.orient()orient
cmd.zoom(“selection”, 5)zoom selection, 5
cmd.png(“file.png”, dpi=300, ray=1)png file.png, dpi=300, ray=1
cmd.save(“session.pse”)save session.pse
cmd.reinitialize()reinitialize
cmd.count_states(“object”)— (Python only)
cmd.get_model(“selection”)— (returns atom data as Python object)

Saving and reusing scripts

Two habits make PyMOL scripts maximally reusable. First, use get_view to capture the current camera orientation and paste the output into your script as a set_view call — this locks the exact angle so the figure looks identical every time it’s generated:

PyMOL command line
# After positioning the structure exactly as you want it:
get_view

# Copy the printed matrix and add to your script:
set_view (\
     0.756, -0.604,  0.249,\
    -0.023,  0.369,  0.929,\
    -0.654, -0.706,  0.271,\
     0.000,  0.000, -85.00,\
    12.543,  8.210, 10.123,\
    65.000, 105.00, -20.00)

Second, use log_open to record an interactive session as a .pml script automatically:

PyMOL command line
# Start recording all commands to a file
log_open my_figure.pml

# ... do your work interactively ...
# load, color, orient, measure — all commands are recorded

# Stop recording
log_close

# The file my_figure.pml now contains your entire session
# Clean it up in a text editor, then it's a reusable script
Build a lab script library
Save your best scripts in a shared folder accessible to everyone in your lab — a pymol_scripts/ directory in your shared drive or a lab GitHub repository. A script for coloring by pLDDT, one for binding site figures, one for multi-structure overlays, one for batch export — a small library of 10–15 well-commented scripts covers 90% of recurring PyMOL tasks for an entire research group. The time investment to write them once pays off every time someone in the lab starts a new project.

PyMOL scripting in one paragraph

PyMOL’s scripting environment is Python — every command you type interactively is a Python function call via the cmd module. Save your figure workflows as .pml files and run them headless with pymol -c script.pml to generate publication figures without opening a GUI. Use iterate with stored to extract per-residue data. Use Python loops to batch-process multiple structures with identical settings. Lock camera orientation with get_view / set_view. Use log_open to automatically capture an interactive session as a script. Every figure you make more than once deserves a script.

Last updated on

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *