Python package for generating NHS England Making Data Count style statistical process control (SPC) outputs.
mdcspc provides a practical Python workflow for analysts who want to create SPC XmR charts, apply consistent special cause detection rules, and generate repeatable outputs from analytical data.
The package is designed around long-format time-series data and supports:
- CSV workflows through the command line
- pandas DataFrame workflows through Python
- optional SQLite workflows for lightweight local database use
- XmR SPC calculations
- special cause detection rules
- SPC chart generation
- summary output files
- configuration-driven analysis
The intended users are NHS analysts and analytical teams who want to use SPC methods consistently without needing to build their own implementation.
SPC charts and detected signals should be treated as prompts for investigation and learning. They do not automatically prove that performance has improved or deteriorated.
If you are new to mdcspc, start with the Quick Start Guide:
README_QUICKSTART.md
The Quick Start Guide covers the first workflow:
- Prepare data
- Install the package
- Generate SPC outputs
- Review charts and summary files
This README provides the full technical reference, including supported workflows, configuration, commands, and advanced usage.
Statistical process control (SPC) is a method for understanding variation in processes over time.
Traditional reporting often compares measures against fixed thresholds, targets, or previous periods. While these approaches can be useful, they may not distinguish between:
- expected variation that is part of the normal process
- unusual variation that may indicate something has changed
The Making Data Count approach promotes the use of SPC methods to support better understanding of variation and improvement conversations.
mdcspc provides a Python implementation of this approach, allowing analysts to create consistent SPC outputs from existing analytical workflows.
The package is designed to support practical analytical use cases including:
- operational reporting
- quality improvement work
- recurring performance monitoring
- analytical pipelines producing multiple SPC charts
The first draft release of mdcspc currently focuses on XmR SPC analysis.
The package supports:
- XmR charts
- centre line calculation
- control limits
- special cause detection
- improvement direction handling
Supported input routes:
- CSV files
- pandas DataFrames
- SQLite queries
Generated outputs include:
- SPC charts as PNG images
- summary CSV files
- analysis results for review and further processing
Settings can be controlled through CSV configuration files.
Configuration supports:
- metric-level settings
- improvement direction
- phase recalculation points
- chart annotations
- target settings
The simplest workflow is usually:
- Prepare data from an existing source
- Save or export the data in a supported format
- Run
mdcspc - Review charts and summaries
Many NHS analytical workflows begin with data stored in:
- Excel workbooks
- reporting systems
- SQL databases
- analytical platforms
For command-line use, data should normally be exported to CSV first.
For more advanced workflows, data can be queried and prepared in Python before being passed to mdcspc as a pandas DataFrame.
Teams producing repeated SPC outputs can use configuration files to create consistent and reproducible workflows.
Examples include:
- standard chart settings
- different improvement directions for different measures
- predefined phase changes
- reusable production workflows
mdcspc helps apply SPC calculations consistently, but it does not replace understanding of SPC principles.
Users should consider:
- what their measure represents
- what improvement means for that measure
- whether detected signals are meaningful in context
mdcspc requires:
- Python 3.10 or later
- pip
- a working Python environment
The package has been developed and tested on Python 3.13.
Using a virtual environment is recommended, particularly when using the package alongside other analytical tools.
If the repository has already been downloaded:
pip install -e .This installs the package in editable mode.
After installation, the command line interface is available:
mdcspc --helpClone the repository:
git clone https://github.com/sa132-imp/mdcspc.gitMove into the project folder:
cd mdcspcInstall:
pip install -e .Run:
mdcspc --helpThe installed command is the recommended way to use the package.
A Python module fallback is also available:
python -m mdcspc.cli --helpDo not use:
python -m src.mdcspc.clias normal package usage. This is only a repository development shortcut.
The overall workflow is:
Input data
|
v
Identify metric series
|
v
Apply configuration settings
|
v
Calculate SPC statistics
|
v
Apply special cause rules
|
v
Generate charts and summary files
The package is designed around long-format analytical data.
Each row represents one observation for a metric at a point in time.
Example:
| Period | Value | MetricName | Group |
|---|---|---|---|
| 2024-01-01 | 9578 | ED_Attends | Organisation A |
| 2024-02-01 | 9396 | ED_Attends | Organisation A |
| 2024-03-01 | 9955 | ED_Attends | Organisation A |
Rows with the same metric and grouping values are analysed as a single SPC series.
mdcspc expects data in long format.
Long format means each measurement is stored as a separate row rather than having separate columns for each month, week, or organisation.
Recommended structure:
| Column | Purpose |
|---|---|
| Period | Date or reporting period |
| Value | Numeric measure being analysed |
| MetricName | Name of the metric |
| Group | Organisation, service, team, or other grouping |
Example:
Period,Value,MetricName,Group
2024-01-01,9578,ED_Attends,Organisation A
2024-02-01,9396,ED_Attends,Organisation A
2024-03-01,9955,ED_Attends,Organisation AThe date or reporting period for the observation.
Examples:
- day
- week
- month
- reporting period
Examples of valid values:
2024-01-01
2024-01
Jan-24
The field should represent when the measurement occurred.
The numeric value being analysed.
Examples:
- counts
- rates
- percentages
- durations
- waiting times
Values must be stored as numbers.
For example:
Correct:
95
or:
0.95
Incorrect:
95%
The name or identifier of the measure.
Examples:
ED_Attends
RTT_18_Week
Patient_Experience
When multiple metrics exist in the same dataset, each metric is treated as a separate SPC series.
The organisation, service, team, site, or other grouping identifier.
Examples:
Trust A
Ward 5
Community Team North
When multiple groups exist, each metric/group combination is analysed separately.
OrgCode is an optional identifier used when data contains formal organisation codes.
It can be used alongside Group:
- OrgCode for formal organisational identifiers
- Group for wider categories such as teams, services, or other groupings
When present, OrgCode can be used as part of the series grouping behaviour.
mdcspc supports multiple series within the same dataset.
A series is identified using recognised grouping columns.
The package currently recognises:
OrgCodeGroupMetricName
These columns are detected automatically when present.
Analytical datasets often contain additional fields that describe the data but should not create separate SPC charts.
Examples:
- source system identifiers
- extraction dates
- notes fields
- metadata columns
mdcspc does not automatically treat every additional column as a grouping variable.
Only recognised grouping columns are used for automatic series detection.
If no recognised grouping columns are present, the package treats the dataset as a single series.
For example:
Month,Value
2024-01,100
2024-02,105
2024-03,102can still be analysed as one SPC chart.
SPC signals can have different interpretations depending on the measure.
For example:
- higher values may represent improvement for one metric
- lower values may represent improvement for another
mdcspc supports three improvement direction settings:
| Direction | Meaning |
|---|---|
higher |
Higher values are considered improvement |
lower |
Lower values are considered improvement |
neutral |
Direction is not automatically interpreted |
When using CSV export:
mdcspc export-csv --input data.csv --out output --direction higherThe direction applies to every series in that CSV.
This works well when the dataset contains one metric or multiple metrics with the same interpretation.
If a dataset contains multiple metrics with different improvement directions, use configuration files.
Example:
| Metric | Direction |
|---|---|
| Patient satisfaction | higher |
| Waiting time | lower |
Configuration files allow each metric to have its own behaviour.
mdcspc currently focuses on XmR charts.
XmR charts contain:
The observed values over time.
The average level of the process.
Expected variation boundaries calculated from the process data.
These help distinguish between:
- normal variation
- unusual variation
The package applies special cause rules based on Making Data Count style SPC interpretation.
Detected signals include:
A single point outside the control limits.
This may indicate something unusual has occurred.
A run of consecutive points consistently above or below the centre line.
A shift may suggest the process has changed.
A sequence of consecutive points consistently increasing or decreasing.
A trend may indicate a sustained movement in the process.
A pattern where two out of three consecutive points are close to a control limit.
This can indicate unusual process behaviour.
SPC signals are not automatic conclusions.
A signal does not mean:
- performance has definitely improved
- performance has definitely worsened
- a specific cause has been identified
Instead, signals should prompt questions such as:
- What changed in the process?
- Was there an intervention?
- Was there a change in demand?
- Did data collection change?
- Does this represent meaningful improvement?
The context of the measure and process remains essential.
SPC limits require enough observations to estimate variation.
By default, mdcspc requires:
10 valid numeric observations
to calculate SPC limits.
Where a series has fewer than 10 valid numeric observations:
- control limits are not calculated
- special cause rules are not applied
- outputs identify the series as having insufficient data
Users should generally aim for at least 15 data points where possible, following Making Data Count recommendations.
mdcspc supports three main input routes:
- CSV files through the command line
- pandas DataFrames through Python
- SQLite queries for lightweight local database workflows
The recommended route depends on where your data already exists.
The CSV workflow is the simplest and most accessible route.
Use this when:
- your data is already available as a spreadsheet
- you can export data from another system
- you want to run SPC analysis from the command line
A typical workflow is:
- Prepare your data
- Save or export it as CSV
- Run
mdcspc export-csv - Review charts and summaries
Example:
mdcspc export-csv --input data.csv --out outputA CSV file should contain:
- one period/date column
- one numeric value column
- optional metric and grouping columns
Recommended structure:
Period,Value,MetricName,Group
2024-01-01,9578,ED_Attends,Organisation A
2024-02-01,9396,ED_Attends,Organisation A
2024-03-01,9955,ED_Attends,Organisation Amdcspc attempts to identify columns automatically.
For more control, columns can be specified manually.
Example:
mdcspc export-csv `
--input data.csv `
--out output `
--index-col Month `
--value-col MeasureWhere:
--index-colspecifies the period/date column--value-colspecifies the numeric measure column
For more advanced analytical workflows, using a pandas DataFrame may be preferable.
This is likely to be the best approach when data has already been:
- extracted from a database
- joined with other datasets
- cleaned
- filtered
- transformed in Python
The general workflow is:
- Query or prepare data using your normal analytical tools
- Create a pandas DataFrame
- Pass the DataFrame to
mdcspc - Generate SPC outputs
This approach avoids unnecessary intermediate files and fits well into reproducible analytical pipelines.
A DataFrame should follow the same long-format structure as CSV input.
import pandas as pd
df = pd.DataFrame(
{
"Period": [
"2024-01-01",
"2024-02-01",
"2024-03-01"
],
"Value": [
9578,
9396,
9955
],
"MetricName": [
"ED_Attends",
"ED_Attends",
"ED_Attends"
],
"Group": [
"Organisation A",
"Organisation A",
"Organisation A"
]
}
)Once your data has been prepared as a pandas DataFrame, pass it to mdcspc using export_spc_from_dataframe.
from mdcspc.exporter_dataframe import export_spc_from_dataframe
summary, results = export_spc_from_dataframe(
df,
working_dir="output",
index_col="Period",
value_col="Value"
)This writes the same style of outputs as the CSV workflow:
output/
|
├── charts/
|
└── spc_summary_from_input.csv
The function returns:
summary— a pandas DataFrame containing the per-series summary resultsresults— the SPC analysis results object
Useful optional arguments include:
| Argument | Purpose |
|---|---|
working_dir |
Output folder |
config_dir |
Optional folder containing configuration files |
value_col |
Name of the numeric value column |
index_col |
Name of the period/date column |
summary_filename |
Name of the summary CSV file |
charts_subdir |
Name of the chart output subfolder |
chart_mode |
Chart mode, such as x_only or xmr |
quiet |
Suppress normal console output |
For example, to use a configuration folder:
summary, results = export_spc_from_dataframe(
df,
working_dir="output",
config_dir="config",
index_col="Period",
value_col="Value"
)SQLite input is available for lightweight local database workflows.
It can be useful for:
- reproducible local extracts
- testing
- small analytical databases
It is not intended to represent the typical NHS enterprise database workflow.
For larger database environments, the recommended approach is usually:
- Query data using existing database tools
- Prepare the dataset
- Pass the resulting CSV or DataFrame to
mdcspc
mdcspc export-sqlite `
--db path/to/data.db `
--query "SELECT Period, Value, MetricName FROM measures" `
--out outputThe query should return data in a structure suitable for SPC analysis.
The main CLI commands are:
| Command | Purpose |
|---|---|
export-csv |
Generate SPC outputs from CSV |
export-sqlite |
Generate SPC outputs from SQLite |
wizard |
Create starter configuration files |
init-config |
Create empty configuration templates |
explain-config |
Explain configuration loading behaviour |
recalc-wizard |
Add phase recalculation settings |
Generates SPC outputs from a CSV file.
Basic usage:
mdcspc export-csv --input data.csv --out outputPath to the input CSV file.
Example:
--input "C:\data\metrics.csv"Folder where outputs will be created.
Example:
--out "C:\outputs\spc"Optional folder containing configuration files.
Example:
--config-dir configConfiguration allows more control over:
- metric settings
- improvement direction
- phases
- targets
- annotations
Sets the improvement direction.
If --direction is not provided, the default is neutral.
Options:
higher
lower
neutral
Example:
--direction lowerMeaning:
higher: increasing values are interpreted as improvementlower: decreasing values are interpreted as improvementneutral: no automatic improvement interpretation
This setting applies to all series in the CSV.
For datasets containing metrics with different directions, use configuration files.
Specifies the period/date column.
Example:
--index-col MonthSpecifies the measure column.
Example:
--value-col NumberControls chart generation mode.
If --chart-mode is not provided, the default is x_only. The default produces the X chart only; use --chart-mode xmr to generate the full XmR chart pair including the moving range chart.
Available options:
xmr
x_only
xmr generates the full XmR chart.
x_only generates only the X chart.
Suppresses normal command output.
Useful for automated workflows.
Example:
--quietGenerates SPC outputs from a SQLite database query.
Example:
mdcspc export-sqlite `
--db data.db `
--query "SELECT Period, Value FROM measures" `
--out outputSQLite support is intended for lightweight local workflows rather than replacing enterprise database connections.
The wizard creates starter configuration files from an input CSV.
Example:
mdcspc wizard `
--input data.csv `
--out-config configThe wizard is optional.
Simple workflows can use:
mdcspc export-csvwithout configuration.
Use the wizard when you need:
- repeatable settings
- multiple metrics
- different directions
- phase changes
- targets
Creates empty configuration templates.
Example:
mdcspc init-config --out configGenerated files include:
metric_config.csvspc_phase_config.csvspc_target_config.csv
These can be edited manually.
Shows where configuration files are loaded from.
Example:
mdcspc explain-configThis is useful when troubleshooting configuration behaviour.
Provides a guided way to add a recalculation point to a metric.
Recalculation points are used when a process has changed and SPC limits need to be recalculated from a defined point.
Examples:
- implementation of a new process
- service redesign
- major change in measurement method
The settings created by this workflow are stored in phase configuration.
Configuration files allow users to control how mdcspc handles individual metrics and analytical workflows.
Configuration is optional.
A simple CSV workflow can generate SPC outputs without any configuration files.
Configuration becomes useful when you need:
- repeatable production workflows
- multiple metrics with different settings
- different improvement directions
- phase recalculation points
- chart annotations
- target information
The recommended workflow is:
- Generate starter configuration
- Review the configuration files
- Edit settings as required
- Rerun the analysis using the configuration
mdcspc uses three main configuration files:
| File | Purpose |
|---|---|
metric_config.csv |
Metric-level settings |
spc_phase_config.csv |
Phase changes and recalculation points |
spc_target_config.csv |
Target settings |
Configuration files are CSV files so they can be edited using:
- Excel
- text editors
- other spreadsheet software
A configuration directory contains the CSV files used during analysis.
Example:
config/
|
├── metric_config.csv
├── spc_phase_config.csv
└── spc_target_config.csv
Pass a configuration directory using:
mdcspc export-csv `
--input data.csv `
--out output `
--config-dir configThere are two main approaches.
The wizard creates starter configuration based on an input dataset.
Example:
mdcspc wizard `
--input data.csv `
--out-config configThis is useful when:
- starting a new analytical workflow
- working with multiple metrics
- wanting a guided setup
Templates can also be created:
mdcspc init-config --out configThis creates blank configuration files that can be edited manually.
This approach may be preferable for experienced users managing larger analytical processes.
The metric configuration file controls metric-level behaviour.
Typical uses include:
- identifying metrics
- setting improvement direction
- controlling metric-specific options
This is particularly useful where different metrics in the same dataset behave differently.
For example:
| Metric | Direction |
|---|---|
| Patient satisfaction | higher |
| Waiting time | lower |
A command-line --direction option applies one setting to all series.
Metric configuration allows more detailed control.
The phase configuration file controls recalculation points and chart annotations.
A phase change is used when the process itself has changed and historical variation may no longer represent the current process.
Examples:
- introduction of a new pathway
- service redesign
- major operational change
- change in data collection method
A phase configuration entry defines where recalculation begins.
The 10-observation minimum applies to the series as a whole, not rigidly to every phase. Shorter phases still receive recalculated limits because phase selection is an analytical judgement. Where a phase contains fewer than 10 valid observations, the output includes a cautionary phase warning while retaining the calculated limits.
Current structure:
OrgCode,Group,MetricName,PhaseStart,Annotation,ShowOnChart,AnnotationPositionFields:
| Field | Purpose |
|---|---|
OrgCode |
Optional organisation identifier |
Group |
Optional grouping identifier |
MetricName |
Metric being affected |
PhaseStart |
Date where the new phase begins |
Annotation |
Text shown on the chart |
ShowOnChart |
Whether annotation is displayed |
AnnotationPosition |
Chart annotation position |
The target configuration file stores target-related information.
Targets can provide additional context alongside SPC analysis.
A target should not be confused with a control limit.
A target represents an externally defined goal or expectation.
Control limits represent expected process variation.
They answer different questions:
| Target | Control limits |
|---|---|
| What level are we aiming for? | What variation does this process normally show? |
| External expectation | Process behaviour |
| Improvement goal | Statistical signal |
When configuration is supplied, it overrides default behaviour.
The general approach is:
- User-provided configuration directory
- Package default configuration resources
- Built-in defaults
This allows:
- local customisation
- reusable team configurations
- consistent analytical workflows
Use:
mdcspc explain-configto understand configuration loading behaviour.
mdcspc generates output files in the folder provided through --out.
A typical output structure is:
output/
|
├── charts/
|
└── spc_summary_from_input.csv
SPC charts are generated as PNG image files.
Charts include:
- plotted observations
- centre line
- control limits
- special cause signals
- optional annotations and targets
Charts are designed for:
- reporting
- review
- discussion
- investigation
The summary CSV file provides structured outputs from the analysis.
They can be used for:
- further analysis
- checking results
- reporting workflows
- automated processing
Summary outputs allow users to work with the analytical results without needing to extract information manually from chart images.
A single dataset can contain multiple metrics.
Example:
Period,Value,MetricName,Group
2024-01-01,100,Admissions,Organisation A
2024-01-01,20,Readmissions,Organisation A
2024-02-01,105,Admissions,Organisation A
2024-02-01,18,Readmissions,Organisation AEach metric/group combination is analysed separately.
The same metric can be analysed across multiple organisations.
OrgCode can be used when organisations have a formal identifier. Group can be used for wider grouping needs such as services, teams, or other categories.
Example:
Period,Value,MetricName,OrgCode,Group
2024-01-01,100,Admissions,ORG001,Organisation A
2024-02-01,105,Admissions,ORG001,Organisation A
2024-01-01,120,Admissions,ORG002,Organisation B
2024-02-01,118,Admissions,ORG002,Organisation BEach organisation/metric combination produces its own SPC series.
Where multiple measures exist:
Example:
| Metric | Direction |
|---|---|
| Patient experience | Higher is better |
| Waiting time | Lower is better |
| Incident count | Context dependent |
Use configuration files when different metrics require different interpretations.
The Python workflow is intended for users who already prepare data programmatically.
Typical pattern:
Data source
|
v
Python preparation
|
v
pandas DataFrame
|
v
mdcspc analysis
|
v
Outputs
This approach is useful when:
- data comes from a database
- complex transformations are required
- analysis forms part of a wider Python pipeline
The repository includes automated tests covering core functionality.
Development installation:
pip install -e .Run tests:
pytestCurrent first draft verification includes:
- CSV workflows
- DataFrame workflows
- SQLite workflows
- CLI commands
- configuration workflows
- plotting behaviour
mdcspc is currently a first draft release.
The package currently provides:
- working XmR SPC analysis
- CLI workflows
- CSV, DataFrame and SQLite inputs
- configuration-driven behaviour
- automated testing
Documentation and features may continue to evolve as the package develops.
This section covers common issues and checks when using mdcspc.
If the terminal reports that mdcspc is not recognised, check:
- the package installation completed successfully
- the terminal is using the correct Python environment
- your virtual environment is activated if you are using one
Check the installation:
mdcspc --helpIf this fails, try:
python -m mdcspc.cli --helpIf the Python module command works but mdcspc does not, the issue is likely related to the Python environment path.
mdcspc attempts to detect the required columns automatically.
If your columns have different names, specify them manually.
Example:
mdcspc export-csv `
--input data.csv `
--out output `
--index-col ReportingMonth `
--value-col MeasureValueCheck that:
- the period column contains dates or date-like values
- the value column contains numeric data
- column names match the options provided
This usually means there is insufficient data.
SPC limits require enough observations to estimate variation.
By default:
- fewer than 10 valid numeric observations → no SPC limits calculated
- missing values do not count towards this minimum
- genuine zero values do count
- special cause rules are not applied
Where possible, use longer time series to provide enough information about the process.
Check that numeric fields contain numbers only.
Correct:
Period,Value
2024-01-01,95Incorrect:
Period,Value
2024-01-01,95%Percentages, rates and durations should be stored as numeric values.
Check whether your dataset contains recognised grouping columns.
mdcspc uses:
OrgCodeGroupMetricName
to identify separate series.
It does not automatically use every column in the dataset as a grouping variable.
If unexpected charts are created, check these fields.
Check that your dataset contains the grouping fields required.
For example:
Period,Value,MetricName,Group
2024-01-01,100,Admissions,Organisation A
2024-01-01,120,Admissions,Organisation Bcreates separate series because the groups differ.
If the dataset only contains:
Period,Value
2024-01-01,100
2024-02-01,120it will be treated as a single series.
Check:
- The correct folder is supplied:
--config-dir config- The CSV files have the expected names:
metric_config.csv
spc_phase_config.csv
spc_target_config.csv
- The configuration values match the metric and grouping values in your data.
Use:
mdcspc explain-configto review configuration behaviour.
Do not use:
--directionfor this situation.
The command-line option applies one direction to all series.
Instead, use metric configuration.
Example:
| Metric | Direction |
|---|---|
| Patient satisfaction | higher |
| Waiting time | lower |
Check:
- the command completed successfully
- the output path is correct
- you have write permission
- you are checking the folder specified by
--out
Relative paths are created from the folder where the command was run.
Example:
--out outputscreates:
current-folder/
└── outputs/
For support queries, provide:
- the command used
- the error message
- sample input data structure
- column names
- configuration files if relevant
Support contact:
england.makingdatacount@nhs.net
When reporting issues, include enough information to reproduce the problem where possible.
For repeatable analytical workflows:
- store input datasets with clear versions
- keep configuration files under version control
- record the package version used
- retain generated outputs where appropriate
- document any phase changes or analytical decisions
A reproducible SPC workflow should make it clear:
- what data was analysed
- what settings were used
- when the analysis was produced
mdcspc is designed as a practical analytical tool, but users should consider:
Signals indicate patterns that may require investigation.
They do not identify causes automatically.
A statistical signal may be caused by:
- genuine process change
- seasonal effects
- data quality issues
- recording changes
- temporary operational events
Analysts should interpret outputs alongside operational knowledge.
Current scope focuses on XmR charts.
Future development may expand functionality, but users should treat the current package as a first draft implementation.
Repository:
https://github.com/sa132-imp/mdcspc
Current release:
0.2.0
Development status:
First draft release
See the repository licence for current licensing information.