mdhewei/bioinfor-claw/plot-survival

Claude Code and agent skill by mdhewei/bioinfor-claw

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Generate publication-quality Kaplan-Meier survival curves from time-to-event data. Supports multiple groups, log-rank test, Wilcoxon test, median survival annotation, confidence intervals, at-risk tables, and flexible stratification by continuous or categorical variables.

Install

npx vskill@latest install mdhewei/bioinfor-claw/plot-survival

SKILL.md

Plot Survival

Purpose

Create professional Kaplan-Meier survival curves for time-to-event data with comprehensive statistical testing and annotations. This skill computes the Kaplan-Meier estimator from raw survival data, performs log-rank and Wilcoxon tests, generates publication-quality plots with confidence intervals, median annotations, at-risk tables, and optional output in PNG and SVG formats.

Use when / Not when

Use when
  • You need to visualize time-to-event data (survival, recurrence-free survival, disease-free survival, etc.)
  • You want to compare survival between groups (treatment vs. control, responder vs. non-responder)
  • You need to test for significant group differences (log-rank or Wilcoxon p-values)
  • You're preparing figures for a publication (high-quality, customizable aesthetics)
  • You want to stratify by continuous variables (e.g., high vs. low expression, split at median)
  • You need confidence intervals and at-risk tables (clinical/biomedical standard)
  • You're reporting median survival and survival probabilities at specific time points
Not when
  • Your data has competing risks (use competing risks packages like cmprsk)
  • You have more than 10-15 groups (plot becomes unreadable; consider binning)
  • You need Cox regression or adjusted curves (use survival R package or lifelines Python)
  • You have hierarchical data with repeated events per individual (use frailty models)
  • Data is left-censored or interval-censored (only right-censoring is supported)
  • You need permutation-based p-values (script uses parametric chi-squared approximation)

Expected inputs / outputs

Inputs
  • CSV/TSV file with columns:
  • Time-to-event (required): numeric, column name specified by --time-col
  • Event status (required): 1 = event occurred, 0 = censored
  • Group (required for multi-group KM): categorical variable name via --group-col
  • (Optional) Continuous variable for median stratification (e.g., gene expression)
Outputs
  • PNG file (default): High-resolution Kaplan-Meier curve with all annotations
  • SVG file (if --output-svg): Scalable vector graphics for editing in Illustrator/Inkscape
  • survival_stats.tsv: Table with group, n, n_events, median_survival, CI_lower, CI_upper, p_value
  • Console output: Summary statistics and test results

Procedure

Step 1: Load and validate data
  1. Read CSV/TSV into pandas DataFrame
  2. Check for required columns: --time-col, --event-col, --group-col
  3. Validate data types: time should be numeric, event should be 0/1
  4. Remove rows with missing values in key columns
  5. Handle median stratification if --split-by-median is set
Step 2: Kaplan-Meier estimation (per group)

For each group:

  1. Sort records by time-to-event
  2. Identify unique event times
  3. At each event time t, compute:
  • d_i = number of events at time t
  • n_i = number at risk at time t
  • S(t) = S(t-1) × (1 - d_i / n_i) [product of conditional survival]
  1. Compute Greenwood's variance:
  • Var(S(t)) = S(t)^2 × sum(d_i / (n_i × (n_i - d_i)))
  1. Compute 95% CI using log-log transformation:
  • α = sqrt(Var(log(-log(S))))
  • CI = exp(-exp(log(-log(S)) ± 1.96 × α))
  1. Identify median survival time (time at which S(t) = 0.5)
Step 3: Statistical testing

Log-rank test:

  1. Compute observed vs. expected events across all event times
  2. O_i = observed events in group i at each time
  3. E_i = expected events = (d_i × n_i) / N, where N = total at risk
  4. Chi-squared statistic: χ² = (O_i - E_i)^2 / E_i, df = n_groups - 1
  5. Compute p-value from chi-squared distribution (Wilson-Hilferty normal approx for small sample)

Wilcoxon (Peto-Wilcoxon) test:

  1. Weight each comparison by number at risk: w_i = n_i (gives more weight to early events)
  2. Otherwise same as log-rank test with weighted statistics
Step 4: Plot generation (matplotlib)
  1. Create figure with specified dimensions and DPI
  2. For each group, plot step function:
  • x = event times, y = S(t)
  • Use "where=post" for step function
  • Color from palette (Set1, tab10, or custom)
  • Linewidth customizable
  1. Add shaded confidence interval bands (fill_between with alpha transparency)
  2. Add censoring tick marks at censored times (scatter plot with marker="|" or "+")
  3. Add vertical dashed lines at median survival times (if --show-median)
  4. Add horizontal line at S(t)=0.5 (if --show-median)
  5. Add at-risk table below x-axis (ax.text for each time point × group, showing n at risk)
  6. Annotate p-value in corner (if --show-pvalue)
  7. Customize labels, legend, colors, fonts, axis limits
Step 5: Output generation
  1. Save figure to PNG at specified DPI (default 300)
  2. Save to SVG if requested
  3. Write survival_stats.tsv with summary statistics per group
  4. Print summary to console

Key execution patterns

bash
# Basic: Two-group KM curve (control vs. treatment)
python scripts/plot_survival.py \
--input survival_data.csv \
--time-col time_months \
--event-col event \
--group-col treatment \
--output survival_plot.png \
--title "Overall Survival by Treatment Group" \
--show-pvalue \
--show-at-risk
# Median stratification for gene expression (high vs. low)
python scripts/plot_survival.py \
--input tcga_data.tsv \
--time-col os_months \
--event-col os_event \
--split-by-median \
--split-col gene_expression_level \
--output gene_expr_survival.png \
--title "Overall Survival by Gene Expression" \
--show-median \
--show-ci
# Multiple groups with custom colors and log-rank test
python scripts/plot_survival.py \
--input clinical_trial.csv \
--time-col time_days \
--event-col event_status \
--group-col dose_group \
--group-order "placebo,low_dose,high_dose" \
--group-colors "#e41a1c,#377eb8,#4daf4a" \
--output dose_response_survival.png \
--test logrank \
--show-pvalue \
--time-unit months \
--fig-width 10 \
--fig-height 7
# Clinical publication-quality figure
python scripts/plot_survival.py \
--input cancer_cohort.tsv \
--time-col efs_months \
--event-col efs_event \
--group-col biomarker_status \
--output publication_figure.png \
--output-svg \
--title "Event-Free Survival by Biomarker Status" \
--xlabel "Months from diagnosis" \
--ylabel "Event-free survival probability" \
--show-at-risk \
--show-median \
--show-ci \
--show-pvalue \
--test both \
--dpi 300 \
--fig-width 9 \
--fig-height 6
# Compare log-rank and Wilcoxon tests
python scripts/plot_survival.py \
--input early_stopping_trial.csv \
--time-col weeks \
--event-col event \
--group-col arm \
--output early_events.png \
--test both \
--show-pvalue \
--pvalue-location top_left
# Stratified analysis (multiple strata)
# Create stratified dataset, then run separately:
python scripts/plot_survival.py \
--input subset_stratum_a.csv \
--time-col time \
--event-col event \
--group-col treatment \
--output survival_stratum_a.png

Parameter decision guide

ParameterValueWhen to useRationale
--time-cole.g., "time_months"Standard; always requiredDifferent datasets use different column names
--event-cole.g., "event_status"Standard; always requiredMust specify which column codes censoring
--group-cole.g., "treatment"Comparing 2+ groupsLeave empty for single-group KM
--split-by-medianTrueHigh-dimensional data (gene expression, biomarkers)Dichotomize continuous variable at median
--split-col"expression_level"Used with --split-by-medianSpecify the continuous variable to split
--show-ciTruePublication figuresStandard in clinical/biomedical publications
--show-at-riskTrueClinical presentationsShows how many subjects at risk at each time
--show-medianTrueWhen median survival meaningfulMost cancer/event-free survival analyses
--show-pvalueTrueComparative studiesReport p-value to show statistical significance
--test"logrank" (default)Most time-to-event dataStandard test for overall group differences
--test"wilcoxon"Early events more relevantMore weight on early time points
--test"both"Robust reportingShow both tests to assess consistency
--time-unit"months"Human-readable labelsAdjust axis label (days, months, years)
--xlim24Focus on early follow-upTruncate x-axis to relevant time window
--dpi300 (default)Publication submissionHigh resolution for print/PDF
--dpi150Slide presentationsAdequate for screens, smaller file size
--fig-width8-10Standard presentation width8 for slides, 9-10 for papers
--fig-height6-7Standard presentation height6 for compact figure, 7 for readability
--palette"Set1" (default)Most applicationsGood color contrast and colorblind-friendly
--palette"tab10"Many groups (5+)More distinct colors than Set1
--palette"custom"Custom brand colorsProvide via --group-colors
--linewidth2.0 (default)Standard line widthIncrease to 3+ for large poster figures
--censoring-marksTrue (default)Publication figuresShows where censoring occurred
--censoring-symbol"+" (default)Standard in clinical papersCan change to "o" or other marker
--pvalue-location"top_right" (default)Most figuresAvoids overlapping survival curves

Failure modes

FailureCauseSolution
Error: No event columnColumn name mismatchCheck exact column name in CSV, use --event-col exact_name
Error: Group has 0 eventsAll subjects censored in a groupScript skips CI for that group; check data
Empty plot (no curves)All times missing or negativeValidate time values are numeric and positive
Identical curves for all groupsNo real group difference in dataCheck grouping variable and data assignment
p-value = NaNInsufficient events for valid testMay occur with <5 total events; report but interpret cautiously
At-risk table overlaps plotToo many time points or groupsReduce --xlim or number of groups
Median survival = infinityMore than 50% censoring in groupScript handles; report as "not reached"
CI band too wideSmall sample size or few eventsNormal; indicates high uncertainty
Censoring marks hide curvesToo many censoring points at same timeReduce marker size or use transparency
Colors not appearingCustom hex codes invalidUse format "#RRGGBB" with capital hex digits
SVG file huge (>50 MB)Very large dataset with many pointsReduce DPI or simplify plot (fewer groups)
Figure cuts off labelsAxis labels too longShorten via --title, use --fig-width 12

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/mdhewei/bioinfor-claw/plot-survival/badge)](https://verified-skill.com/skills/mdhewei/bioinfor-claw/plot-survival)

Something wrong with this skill or its page? Tell us.