Matplotlib
zLanqing/codex-claude-academic-skills
Low-level plotting library for full customization. An agent skill from zLanqing/codex-claude-academic-skills.
Best practices for creating publication-quality molecular graphics figures in Coot using user-defined colors, ribbons, and molecular representations
$ npx skills add pemsley/coot --skill coot-figure-making -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install pemsley/coot coot-figure-making --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .claude/skills && cp -r skills-src/mcp/docs/skills/figure-making .claude/skills/coot-figure-making && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "coot-figure-making" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-making into .claude/skills/coot-figure-making/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-figure-making", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-makingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add pemsley/coot --skill coot-figure-making -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install pemsley/coot coot-figure-making --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .agents/skills && cp -r skills-src/mcp/docs/skills/figure-making .agents/skills/coot-figure-making && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "coot-figure-making" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-making into .agents/skills/coot-figure-making/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-figure-making", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add pemsley/coot --skill coot-figure-making -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install pemsley/coot coot-figure-making --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/mcp/docs/skills/figure-making .cursor/skills/coot-figure-making && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "coot-figure-making" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-making into .cursor/skills/coot-figure-making/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-figure-making", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/pemsley/coot.git --path mcp/docs/skills/figure-making--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add pemsley/coot --skill coot-figure-making -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install pemsley/coot coot-figure-making --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/mcp/docs/skills/figure-making .gemini/skills/coot-figure-making && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "coot-figure-making" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-making into .gemini/skills/coot-figure-making/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-figure-making", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install pemsley/coot coot-figure-makingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add pemsley/coot --skill coot-figure-making -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .github/skills && cp -r skills-src/mcp/docs/skills/figure-making .github/skills/coot-figure-making && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "coot-figure-making" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-making into .github/skills/coot-figure-making/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-figure-making", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add pemsley/coot --skill coot-figure-making -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install pemsley/coot coot-figure-making --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/mcp/docs/skills/figure-making .opencode/skills/coot-figure-making && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "coot-figure-making" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/figure-making into .opencode/skills/coot-figure-making/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-figure-making", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
coot-figure-makingBest practices for creating publication-quality molecular graphics figures in Coot using user-defined colors, ribbons, and molecular representations
Coot Figure Making is an agent skill from pemsley/coot. Best practices for creating publication-quality molecular graphics figures in Coot using user-defined colors, ribbons, and molecular representations
Its SKILL.md is about 7.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Data & Analytics, covering Data visualization. The repository describes itself as: Software for macromolecular model-building. The licence is GPL-3.0.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 9648092. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python).
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
ebi.ac.ukFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Coot Figure Making loads about 7.3k tokens when it runs. Until then it costs about 42 tokens; SKILL.md has 1,320 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from pemsley/coot at commit 9648092, republished under its GPL-3.0 licence (© pemsley). 1,320 words, ~7,340 tokens.
.claude/skills/coot-figure-making/SKILL.md (or your agent's skills folder).This skill provides guidance for creating publication-quality molecular graphics figures in Coot, with emphasis on custom coloring schemes and ribbon representations.
ALWAYS wrap complex multi-line code in functions when using the MCP interface.
Multi-line code executed directly (without a function wrapper) can corrupt the Python interpreter if any error occurs. Function wrappers provide proper error handling and prevent interpreter crashes.
# Step 1: Define the function with run_python_multiline()
def my_figure_function():
# ... complex code here ...
return result
# Step 2: Call the function with run_python()
my_figure_function()# ❌ BAD - Direct multi-line execution (can crash interpreter)
ss_info = coot.get_header_secondary_structure_info(0)
strands = ss_info['strands']
# ... more code ...
# ✅ GOOD - Function wrapper (safe error handling)
def setup_figure():
ss_info = coot.get_header_secondary_structure_info(0)
strands = ss_info['strands']
# ... more code ...
return "Done"
setup_figure()Coot's user-defined color system allows custom coloring of specific selections. The workflow has strict ordering requirements:
set_user_defined_colours_py()set_user_defined_atom_colour_by_selection_py()def setup_colors():
# Step 1: Define colors (RGB values 0.0-1.0)
blue = [0.3, 0.6, 1.0]
orange = [1.0, 0.5, 0.0]
# Step 2: Set color palette
coot.set_user_defined_colours_py([
(60, blue),
(61, orange)
])
# Step 3: Assign colors to selections (MMDB format)
color_assignments = [
("//A/10-50", 60), # Blue for residues 10-50
("//A/100-150", 61) # Orange for residues 100-150
]
coot.set_user_defined_atom_colour_by_selection_py(imol, color_assignments)
# Step 4: Create representation
# //! @param secondary_structure_usage_flag 0 (USE_HEADER) i.e. use the secondary structure defined in the header (if any),
# // 1 (DONT_USE) or
# // 2 (CALC_SECONDARY_STRUCTURE)
# // the DONT_USE case will give a worm-like backbone representation
# as a rule of thumb, use 2 when there is no HELIX/SHEET records in the input file.
# if the user wants "worm-like" then they will (should) make it clear that that is the case.
coot.add_ribbon_representation_with_user_defined_colours(imol, "My Figure", secondary_structure_usage_flag)
return "Colors applied"The most reliable way to color by secondary structure is to use the annotations in the PDB header.
def color_by_secondary_structure(imol):
# Get secondary structure from PDB header
ss_info = coot.get_header_secondary_structure_info(imol)
strands = ss_info['strands']
helices = ss_info['helices']
# Build MMDB selection strings for strands
strand_selections = []
for strand in strands:
chain = strand['initChainID']
start = strand['initSeqNum']
end = strand['endSeqNum']
selection = f"//{chain}/{start}-{end}"
strand_selections.append(selection)
# Build MMDB selection strings for helices
helix_selections = []
for helix in helices:
chain = helix['initChainID']
start = helix['initSeqNum']
end = helix['endSeqNum']
selection = f"//{chain}/{start}-{end}"
helix_selections.append(selection)
# Define colors
blue = [0.3, 0.6, 1.0] # Beta strands
purple = [0.5, 0.3, 0.5] # Helices
coot.set_user_defined_colours_py([
(60, blue),
(61, purple)
])
# Assign colors
strand_assignments = [(sel, 60) for sel in strand_selections]
helix_assignments = [(sel, 61) for sel in helix_selections]
all_assignments = strand_assignments + helix_assignments
coot.set_user_defined_atom_colour_by_selection_py(imol, all_assignments)
# Create ribbon
coot.add_ribbon_representation_with_user_defined_colours(imol, "Secondary Structure", secondary_structure_usage_flag)
return f"{len(strand_selections)} strands, {len(helix_selections)} helices"Sometimes secondary structure elements aren't annotated in the PDB header. You can add them manually:
def add_missing_helix(imol):
# Get existing colors
ss_info = coot.get_header_secondary_structure_info(imol)
strands = ss_info['strands']
helices = ss_info['helices']
# Build all selections (as before)
strand_selections = [...]
helix_selections = [...]
# Add manually identified helix
helix_selections.append("//A/135-139")
# Reassign ALL colors and recreate ribbon
# (must include ALL selections every time)
coot.set_user_defined_colours_py([...])
all_assignments = strand_assignments + helix_assignments
coot.set_user_defined_atom_colour_by_selection_py(imol, all_assignments)
coot.add_ribbon_representation_with_user_defined_colours(imol, "Updated", secondary_structure_usage_flag)
return "Helix added"When you recreate a ribbon representation, you MUST reassign ALL color selections, not just the new ones.
# ❌ BAD - Only assigns new helix, strands lose their color
coot.set_user_defined_atom_colour_by_selection_py(imol, [("//A/135-139", 61)])
coot.add_ribbon_representation_with_user_defined_colours(imol, "New", secondary_structure_usage_flag)
# ✅ GOOD - Reassigns everything
all_assignments = strand_assignments + helix_assignments + new_helix
coot.set_user_defined_atom_colour_by_selection_py(imol, all_assignments)
coot.add_ribbon_representation_with_user_defined_colours(imol, "New", secondary_structure_usage_flag)To highlight specific residues (like active site residues, ligands, chromophores), extract them to a new molecule:
def highlight_feature(imol, selection, color_rgb, bond_thickness=10.0):
# Extract to new molecule
feature_imol = coot.new_molecule_by_atom_selection(imol, selection)
if not coot.is_valid_model_molecule(feature_imol):
return -1
# Define color
color_index = 62 # Use a different index than strands/helices
coot.set_user_defined_colours_py([(color_index, color_rgb)])
# Assign color
coot.set_user_defined_atom_colour_by_selection_py(feature_imol, [(selection, color_index)])
# Add representation with thick bonds
#
# //! @param secondary_structure_usage_flag 0 (USE_HEADER) i.e. use the secondary structure defined in the header (if any),
# // 1 (DONT_USE) or
# // 2 (CALC_SECONDARY_STRUCTURE)
# // the DONT_USE case will give a worm-like backbone representation
# as a rule of thumb, use 2 when there is no HELIX/SHEET records in the input file.
# if the user wants "worm-like" then they will (should) make it clear that that is the case.
coot.add_molecular_representation_py(
feature_imol,
selection,
"userDefined", # Use user-defined colors
"Bonds"
secondary_structure_usage_flag
)
# Make bonds thicker for emphasis
coot.set_bond_thickness(feature_imol, bond_thickness)
return feature_imol
# Example: Highlight chromophore in orange
highlight_feature(0, "//A/66", [1.0, 0.5, 0.0], 10.0)def setup_view(chain_id, resno, zoom_level=200):
# Center on specific residue
coot.set_go_to_atom_chain_residue_atom_name(chain_id, resno, "CA")
# Set zoom level
# 150-300: Whole molecule overview
# 50-100: Domain level
# 20-50: Residue detail
coot.set_zoom(zoom_level)For ribbon-only figures, hide the bond representation:
# Hide bonds for molecule 0
coot.set_mol_displayed(0, 0)
# Show bonds again if needed
coot.set_mol_displayed(0, 1)This example creates a publication-quality figure showing GFP's beta barrel structure with colored secondary structure and highlighted chromophore.
def make_gfp_figure():
"""
Create a figure showing GFP with:
- Blue beta barrel strands
- Dark pastel helices
- Orange chromophore with thick bonds
"""
imol = 0 # GFP molecule
# Get secondary structure
ss_info = coot.get_header_secondary_structure_info(imol)
strands = ss_info['strands']
helices = ss_info['helices']
# Build strand selections
strand_selections = []
for strand in strands:
sel = f"//{strand['initChainID']}/{strand['initSeqNum']}-{strand['endSeqNum']}"
strand_selections.append(sel)
# Build helix selections
helix_selections = []
for helix in helices:
sel = f"//{helix['initChainID']}/{helix['initSeqNum']}-{helix['endSeqNum']}"
helix_selections.append(sel)
# Add manually identified helix (not in PDB header)
helix_selections.append("//A/135-139")
# Define colors
blue = [0.3, 0.6, 1.0] # Beta strands
dark_pastel = [0.5, 0.3, 0.5] # Helices
orange = [1.0, 0.5, 0.0] # Chromophore
coot.set_user_defined_colours_py([
(60, blue),
(61, dark_pastel),
(62, orange)
])
# Assign colors to secondary structure
strand_assignments = [(sel, 60) for sel in strand_selections]
helix_assignments = [(sel, 61) for sel in helix_selections]
all_assignments = strand_assignments + helix_assignments
coot.set_user_defined_atom_colour_by_selection_py(imol, all_assignments)
# Create ribbon
coot.add_ribbon_representation_with_user_defined_colours(imol, "GFP Barrel", secondary_structure_usage_flag)
# Hide bonds
coot.set_mol_displayed(imol, 0)
# Extract and highlight chromophore
chrom_imol = coot.new_molecule_by_atom_selection(imol, "//A/66")
coot.set_user_defined_atom_colour_by_selection_py(chrom_imol, [("//A/66", 62)])
coot.add_molecular_representation_py(chrom_imol, "//A/66", "userDefined", "Bonds", secondary_structure_usage_flag)
coot.set_bond_thickness(chrom_imol, 10.0)
# Center view
coot.set_go_to_atom_chain_residue_atom_name("A", 100, "CA")
coot.set_zoom(200)
return f"Figure created: {len(strand_selections)} strands, {len(helix_selections)} helices, chromophore"
# To use (must be called with run_python after defining with run_python_multiline):
make_gfp_figure()[0.3, 0.6, 1.0][0.8, 0.2, 0.4] or [0.5, 0.3, 0.5][1.0, 0.5, 0.0][1.0, 0.9, 0.0][0.0, 0.8, 0.8][1.0, 0.0, 1.0][0.2, 0.4, 0.8][0.2, 0.8, 0.4][0.9, 0.5, 0.2][0.6, 0.6, 0.6]Problem: Ribbon is gray after setting colors.
Solution: Make sure you call add_ribbon_representation_with_user_defined_colours() AFTER setting colors.
Problem: Added new colored region, but existing colors turned red/brown.
Solution: When recreating ribbon, reassign ALL color selections, not just new ones.
Problem: Multi-line code causes "Failed to get main module" error.
Solution: Always use function wrappers with run_python_multiline() then call with run_python().
Problem: Extracted feature (ligand, chromophore) doesn't show up.
Solution:
coot.is_valid_model_molecule(feature_imol)add_molecular_representation_py() succeededcoot.set_mol_displayed(feature_imol, 1)For publication-quality figures, especially for journal covers or high-impact visualizations, use these graphics settings:
Set an appropriate background color for your publication medium:
# Light grey (80%) - excellent for print publications
coot.set_background_colour(0.8, 0.8, 0.8)
# Near-white (98%) - for very light backgrounds
coot.set_background_colour(0.98, 0.98, 0.98)
# Medium grey (50%) - good general purpose
coot.set_background_colour(0.5, 0.5, 0.5)
# White - for manuscripts requiring white backgrounds
coot.set_background_colour(1.0, 1.0, 1.0)
# Black - for dark backgrounds (presentations)
coot.set_background_colour(0.0, 0.0, 0.0)Enable outline mode (also called "cel shading" or "toon shading") for a polished, professional look with dark edges around ribbons and bonds:
# Enable outline mode
coot.set_use_outline(1)
# Disable outline mode
coot.set_use_outline(0)
# Query outline state
state = coot.use_outline_state()Enable advanced rendering effects for high-quality figures:
def enable_fancy_graphics():
"""Enable all fancy graphics effects for publication figures"""
# Ambient Occlusion (SSAO) - adds subtle shadows in crevices
# Makes surfaces appear more 3D with depth perception
coot.set_use_ambient_occlusion(1)
# Fancy Lighting - enhanced lighting model
# Provides better shading and highlights
coot.set_use_fancy_lighting(1)
# Depth Blur - depth of field effect
# Blurs distant objects for focus effect
coot.set_use_depth_blur(1)
return "Fancy graphics enabled"
def disable_fancy_graphics():
"""Disable fancy graphics for faster rendering"""
coot.set_use_ambient_occlusion(0)
coot.set_use_fancy_lighting(0)
coot.set_use_depth_blur(0)
return "Fancy graphics disabled"Ambient occlusion can be fine-tuned for different effects:
# Adjust SSAO strength (default: typically around 1.0)
coot.set_ssao_strength(1.5) # Stronger shadows
# Adjust SSAO radius (default: typically around 0.5)
coot.set_ssao_radius(0.7) # Larger shadow radius
# Adjust SSAO bias (default: typically around 0.025)
coot.set_ssao_bias(0.03) # Reduces shadow artifacts
# Set number of samples for SSAO (more = better quality, slower)
coot.set_ssao_kernel_n_samples(32) # Default is often 16
# Set blur size (0, 1, or 2)
coot.set_ssao_blur_size(1) # Smooths out SSAO shadowsCoot provides real-time shadow rendering that adds depth and dimensionality to molecular structures:
# Enable shadows by setting shadow strength (0 = off, higher = darker)
# Recommended range: 0.3-0.7
coot.set_shadow_strength(0.3) # Subtle shadows (recommended)
coot.set_shadow_strength(0.5) # Medium shadows
coot.set_shadow_strength(0.7) # Strong shadows
# Shadow resolution (1-4, higher = sharper shadows)
# 4 is maximum quality
coot.set_shadow_resolution(4) # Maximum resolution - sharpest shadows
# Shadow softness (1-3, higher = softer edges)
# 3 is maximum softness
coot.set_shadow_softness(3) # Maximum softness - smoothest shadow edges
# Shadow box size (default: 66)
# Adjust if shadows are cut off
coot.set_shadow_box_size(66)Recommended shadow settings for publication:
When to use shadows:
Example:
def enable_publication_shadows():
"""Enable subtle, high-quality shadows for publication figures"""
coot.set_shadow_strength(0.3) # Subtle shadows
coot.set_shadow_resolution(4) # Maximum resolution
coot.set_shadow_softness(3) # Maximum softness
return "Publication shadows enabled"
def disable_shadows():
"""Disable shadows"""
coot.set_shadow_strength(0.0)
return "Shadows disabled"# Anti-aliasing - smooths jagged edges
# Note: May need to restart Coot for this to take effect
coot.set_anti_aliasing(1)
# Enable fog for atmospheric depth
coot.set_use_fog(1)
# Perspective projection (more realistic depth)
coot.set_use_perspective_projection(1)def setup_publication_graphics():
"""
Configure Coot for creating publication-quality figures
Optimized for journal covers and high-impact visualizations
"""
# Background: 80% grey (excellent for print)
coot.set_background_colour(0.8, 0.8, 0.8)
# Enable outline mode for polished look
coot.set_use_outline(1)
# Enable all fancy graphics effects
coot.set_use_ambient_occlusion(1)
coot.set_use_fancy_lighting(1)
coot.set_use_depth_blur(1)
# Fine-tune SSAO for publication quality
coot.set_ssao_strength(1.2)
coot.set_ssao_radius(0.6)
coot.set_ssao_kernel_n_samples(32)
coot.set_ssao_blur_size(1)
# Enable subtle, high-quality shadows
coot.set_shadow_strength(0.3)
coot.set_shadow_resolution(4)
coot.set_shadow_softness(3)
return "Publication graphics settings applied"
def setup_presentation_graphics():
"""
Configure Coot for presentation slides (dark background)
"""
# Black background for presentations
coot.set_background_colour(0.0, 0.0, 0.0)
# Enable outline mode
coot.set_use_outline(1)
# Enable fancy graphics
coot.set_use_ambient_occlusion(1)
coot.set_use_fancy_lighting(1)
coot.set_use_depth_blur(1)
# Enable shadows for presentations
coot.set_shadow_strength(0.4) # Slightly stronger for dark backgrounds
coot.set_shadow_resolution(4)
coot.set_shadow_softness(3)
return "Presentation graphics settings applied"Goodsell-style figures use ball-and-stick representations with flat matte shading, outlines, and chain-based colouring. They are not Gaussian/molecular surfaces — the key characteristic is the illustrated, hand-drawn look achieved through specific shader settings.
The Goodsell style is provided by a Curlew extension. Install it once per session:
def install_goodsell_extension():
# List available extensions to confirm it's there
exts = coot.curlew_get_extension_list()
for name, fname in exts:
print(f"{name}: {fname}")
# Install
result = coot.curlew_download_and_install_extension("coot_goodsell_menu.py")
print(f"Install result: {result}") # 1 = success
return result
install_goodsell_extension()This installs two functions into the global namespace:
goodsell_setting() — applies all shader/material settings (uses active atom's molecule)goodsell_colour_scheme(mode) — sets chain colouring + calls goodsell_setting()def apply_goodsell(imol):
# Navigate to a residue in the target molecule to make it active
# (goodsell_colour_scheme uses active_residue_py() to get imol)
coot.set_go_to_atom_chain_residue_atom_name("A", 100, " CA ")
# Choose colour wheel step mode:
# mode 1: step 0.221 — large steps, most distinct colours (best for hexamers etc.)
# mode 2: step 0.09 — medium steps, analogous palette
# mode 3: step 0.04 — small steps, very similar hues
goodsell_colour_scheme(1)
# CRITICAL: restore rotation centre after set_go_to_atom_chain_residue_atom_name
# which moves the view to that atom as a side effect
cx = coot.molecule_centre_internal(imol, 0)
cy = coot.molecule_centre_internal(imol, 1)
cz = coot.molecule_centre_internal(imol, 2)
coot.set_rotation_centre(cx, cy, cz)
coot.graphics_draw()
return "Goodsell applied"
apply_goodsell(3)set_go_to_atom_chain_residue_atom_name() moves the rotation centre to that atom as a side effect. Always restore the rotation centre to the molecule centroid immediately after:
# ❌ BAD - leaves view centred on a random atom
coot.set_go_to_atom_chain_residue_atom_name("A", 100, " CA ")
goodsell_colour_scheme(1)
# ✅ GOOD - restore centre after
coot.set_go_to_atom_chain_residue_atom_name("A", 100, " CA ")
goodsell_colour_scheme(1)
cx = coot.molecule_centre_internal(imol, 0)
cy = coot.molecule_centre_internal(imol, 1)
cz = coot.molecule_centre_internal(imol, 2)
coot.set_rotation_centre(cx, cy, cz)For reference, the extension applies these settings:
coot.set_background_colour(1.0, 1.0, 1.0) # White background
coot.set_bond_smoothness_factor(3) # Smooth bonds
coot.set_model_molecule_representation_style(imol, 1) # Ball-and-stick
coot.set_model_material_diffuse(imol, 0.00, 0.00, 0.00, 1) # Flat/matte
coot.set_model_material_specular(imol, 0.0, 64) # No specular highlights
coot.set_model_material_ambient(imol, 0.5, 0.5, 0.5, 1)
coot.set_use_outline(1) # Dark outlines - essential
coot.set_effects_shader_brightness(1.11) # Base brightness
coot.set_effects_shader_gamma(0.66) # Gamma correction
coot.set_ssao_strength(0.25) # Subtle ambient occlusion
coot.set_use_fancy_lighting(1)The default brightness of 1.11 is a good starting point but often benefits from a small increase:
# Default from goodsell_setting(): 1.11
# Recommended slight increase for a brighter, more vibrant result:
coot.set_effects_shader_brightness(1.22)
coot.graphics_draw()Always nudge brightness up slightly from the default 1.11 — 1.22 has been found to give a better result.
When saving screendumps, do not specify a directory — write to the current working directory only:
# ✅ CORRECT - filename only
coot.screendump_tga("6v2f_goodsell.tga")
# ❌ WRONG - do not specify a path
coot.screendump_tga("/tmp/6v2f_goodsell.tga")def make_goodsell_figure(imol, anchor_chain, anchor_resno, zoom=350):
"""
Apply Goodsell style to imol and save a screendump.
anchor_chain/resno: any residue in imol (used to set active atom).
"""
# 1. Ensure bond representation is visible
coot.set_mol_displayed(imol, 1)
# 2. Navigate to set active atom (required by goodsell_colour_scheme)
coot.set_go_to_atom_chain_residue_atom_name(anchor_chain, anchor_resno, " CA ")
# 3. Apply Goodsell colouring and shader settings
goodsell_colour_scheme(1) # mode 1 = most distinct chain colours
# 4. Nudge brightness above the default 1.11
coot.set_effects_shader_brightness(1.22)
# 5. Restore rotation centre to molecule centroid
cx = coot.molecule_centre_internal(imol, 0)
cy = coot.molecule_centre_internal(imol, 1)
cz = coot.molecule_centre_internal(imol, 2)
coot.set_rotation_centre(cx, cy, cz)
# 6. Set zoom
coot.set_zoom(zoom)
coot.graphics_draw()
# 7. Save screendump - filename only, no directory
coot.screendump_tga("goodsell_figure.tga")
return "Goodsell figure saved"
make_goodsell_figure(3, "A", 100, zoom=350)Following these practices ensures reliable, publication-quality molecular graphics figures in Coot.
The following new content has been added to the figure-making skill based on today's session visualizing the 1ej6 reovirus core assembly.
Key Topics Covered:
Critical Best Practice:
# ALWAYS set molecular symmetry coloring for structures with symmetry
coot.set_gaussian_surface_chain_colour_mode(2)
coot.gaussian_surface(imol)Correct URL Format:
1ej6-assembly1 NOT 1ej6_assembly-1.cif.gz extensionhttps://www.ebi.ac.uk/pdbe/static/entry/download/Complete example code provided for downloading, decompressing, and loading assemblies.
Publication-Quality SSAO Settings:
CRITICAL Discovery: Outline and Depth Blur Are Mutually Exclusive
Optimized settings for Gaussian surface figures:
Reorganized into three categories:
These updates came from successfully:
The result: A beautiful visualization of icosahedral viral symmetry with 5 colors showing the distribution of 5 unique chain types across 300 chains in the biological assembly.
© pemsley, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in mcp/docs/skills/figure-making of pemsley/coot.
Open the folder on GitHubat commit 9648092
Coot Figure Making next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Coot Figure Making this skillpemsley/coot | 168 | — | ~7.3k | Automated safety check: Pass | GPL-3.0 | |
| MatplotlibzLanqing/codex-claude-academic-skills | 4.7k | 17 repos | ~2.9k | Automated safety check: Pass | MIT | |
| Chart Visualizationbytedance/deer-flow | 84k | 2 repos | ~840 | Automated safety check: Pass | MIT | |
| Scientific Visualizationmims-harvard/OptimusKG | 146 | 19 repos | ~6.3k | Automated safety check: Pass | MIT | |
| SeabornzLanqing/codex-claude-academic-skills | 4.7k | 15 repos | ~4.9k | Automated safety check: Pass | BSD-3-Clause | |
| Plot From DataTrae1ounG/paper-plot-skills | 869 | 1 repos | ~583 | Automated safety check: Pass | None |
zLanqing/codex-claude-academic-skills
Low-level plotting library for full customization. An agent skill from zLanqing/codex-claude-academic-skills.
bytedance/deer-flow
Picks a suitable chart type from 26 options for your data, maps the data to that chart's parameters and generates a chart image through a JavaScript script.
mims-harvard/OptimusKG
Create publication figures with matplotlib/seaborn/plotly. An agent skill from mims-harvard/OptimusKG.
zLanqing/codex-claude-academic-skills
Statistical visualization with pandas integration. An agent skill from zLanqing/codex-claude-academic-skills.
Trae1ounG/paper-plot-skills
Generate publication-quality matplotlib figures by selecting a pre-built paper style and substituting user data.
ChenLiu-1996/figures4papers
Covers publication-ready matplotlib figures for academic papers, slides, and reports—bars, trends, scatter, heatmaps, and multi-panel layouts—with this…
pemsley/coot
Create interactive inline Chart.js graphs directly in the chat from live Coot data.
pemsley/coot
RDKit molecular manipulation and visualization within Coot's Python environment.
pemsley/coot
Best practices for protein structure refinement and validation in Coot.
pemsley/coot
API documentation to be loaded at startup - when starting a Coot session, immediately call getfunctiondescriptions() with the functions listed in this skill.
pemsley/coot
Best Practices for Model-Building Tools and Refinement. An agent skill from pemsley/coot.
pemsley/coot
Comprehensive structure validation combining model-to-map analysis and unmodeled density detection
Categories
Best practices for creating publication-quality molecular graphics figures in Coot using user-defined colors, ribbons, and molecular representations. Coot Figure Making is an agent skill from pemsley/coot.
Coot Figure Making fits situations like: tasks that involve Data visualization.
Run `npx skills add pemsley/coot --skill coot-figure-making -a claude-code`. Or copy the skill folder (mcp/docs/skills/figure-making in pemsley/coot) into .claude/skills/coot-figure-making in your project. Claude Code loads it when a task matches its description.
Run `npx skills add pemsley/coot --skill coot-figure-making -a codex`. Or copy the skill folder (mcp/docs/skills/figure-making in pemsley/coot) into .agents/skills/coot-figure-making in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add pemsley/coot --skill coot-figure-making -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/coot-figure-making, .gemini/skills/coot-figure-making, .github/skills/coot-figure-making and .opencode/skills/coot-figure-making in your project.
SKILL.md names no scripts, command-line tools or credentials: Coot Figure Making is instructions for the agent only. Our summary lists: Python 3.
SKILL.md names 1 domain. In commands or code: ebi.ac.uk; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Coot Figure Making is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.3k tokens (SKILL.md is roughly 29k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Coot Figure Making: Matplotlib (zLanqing/codex-claude-academic-skills, 4.7k stars), Chart Visualization (bytedance/deer-flow, 84k stars), Scientific Visualization (mims-harvard/OptimusKG, 146 stars) and Seaborn (zLanqing/codex-claude-academic-skills, 4.7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
pemsley (a GitHub user) maintains it in pemsley/coot, which has 168 GitHub stars. The repository holds 11 skills in this directory. The repository was last updated on October 8, 2026.
Source: pemsley/coot on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.