From Dashboards to Risk Prediction: DHIS2 Interoperability with Power BI and Shiny for Python

Health Data Lab

Every month, health facilities report antenatal visits, vaccine doses and service data into DHIS2. That routine data is one of the most valuable assets a health system has, but only if it reaches the people who plan services in a form they can act on. This is the story of two applications built on the same DHIS2 source: a Power BI dashboard that shows what has happened, and a Shiny for Python application that adds a first look at where problems may arise next.

Watch both tours Open the Shiny app Code

For education and demonstration only, with DHIS2 demo data. See the disclaimer at the end.

Why routine data needs to become insight

DHIS2 is used by ministries of health in many countries, and it is excellent at collecting and aggregating data. But a district health team preparing a supervision plan does not need a data export; it needs answers. Which chiefdoms are furthest from their immunisation target? Where do women start antenatal care but not finish it? Which reports are missing? And, increasingly: which facilities are likely to struggle next quarter, so that support arrives before the gap widens?

Answering those questions means moving data out of DHIS2 and into tools built for analysis. That is what interoperability means in practice: DHIS2 exposes its data through a documented Web API, and other tools can read it reliably, securely and repeatably. This project uses that API twice.

The first milestone: DHIS2 and Power BI

A few months ago I connected DHIS2 to Microsoft Power BI, using the public DHIS2 demo playground (Sierra Leone demo database). Power Query calls the DHIS2 Web API directly: one function sends each request with its authorisation header, and another turns the api/analytics response into a table of indicator values by chiefdom and month. Server address, organisation unit and period are report parameters, so the same file can point at another DHIS2 instance. No export files, no copy-and-paste: a refresh pulls the latest data.

The semantic model then does what a programme analyst would do by hand. Coverage is computed from numerators and annualised populations, the same way DHIS2 does it, so figures stay correct when districts or months are combined. Dropout, reporting rates, colour shading against targets, and even written findings and recommended actions are DAX measures that update with every filter.

The Power BI Overview page: six indicators against target, coverage by month, written findings and Penta 3 coverage by district (frame from the Power BI tour)

Figure 1: The Power BI Overview page: six indicators against target, coverage by month, written findings and Penta 3 coverage by district (frame from the Power BI tour)

For the twelve months to Sep 2026, the dashboard shows 102.3% ANC 1 coverage but only 41.2% ANC 4 coverage: 151,211 women (59.7%) started antenatal care and did not reach four visits. Penta 3 coverage is 27.6% against a 90% target, and 12,822 children received Penta 1 but not Penta 3 (17.1% dropout, above the 10% limit WHO uses to flag a problem).

The Districts page in Power BI Desktop: a scorecard for every chiefdom, shaded against target, with the chiefdoms where most children missed Penta 3

Figure 2: The Districts page in Power BI Desktop: a scorecard for every chiefdom, shaded against target, with the chiefdoms where most children missed Penta 3

The Districts page turns this into a list of places, and the Actions page into next steps: where to trace defaulters first, which districts report below target, and which chiefdoms show coverage above 100%, a sign that the population estimate needs checking before anyone uses the number.

The Power BI Actions page: recommended actions, districts plotted by coverage and dropout, reporting rates, and chiefdoms whose denominators need checking

Figure 3: The Power BI Actions page: recommended actions, districts plotted by coverage and dropout, reporting rates, and chiefdoms whose denominators need checking

This is descriptive analytics: an accurate, shared picture of performance that stakeholders can filter, discuss and act on.

The next milestone: Shiny for Python

Power BI answers the descriptive question well. But two things pushed me further. First, the analysis I wanted next, a statistical model at facility level, belongs in a programming language. Second, I wanted to see whether an open-source stack could deliver the same dashboard experience, so that teams without Power BI licences, or who want to customise every detail, have an option.

So I rebuilt the dashboard with Shiny for Python and a React interface (through the shinyreact package). A small Python client sends the same requests to the DHIS2 Web API as Power Query does, and a Python module re-implements each DAX measure. Automated tests confirm that the two applications agree, figure for figure: 102.3%, 41.2%, 59.7%, 27.6%, 17.1% and 83.3% on the headline cards, down to the scorecard's Total row.

The same Overview in Shiny for Python. Same DHIS2 data and the same numbers; each card adds a 12-month trend, and the sidebar is plum so the two applications are easy to tell apart

Figure 4: The same Overview in Shiny for Python. Same DHIS2 data and the same numbers; each card adds a 12-month trend, and the sidebar is plum so the two applications are easy to tell apart

The Shiny Districts page: the same scorecard with a Total row that follows the filters, plus sorting and search

Figure 5: The Shiny Districts page: the same scorecard with a Total row that follows the filters, plus sorting and search

The Shiny version also pulls the same indicators for each of the 1,166 health facilities in the demo database, not just the 152 chiefdoms. That facility-level data is what makes the next step possible.

Introducing predictive analytics

The new Risk forecast page asks a forward-looking question for every facility: how likely is it that next quarter this facility will fall behind? "Falling behind" is defined with the dashboard's own thresholds, for two outcomes:

OutcomeDefinition (next 3 months)Facilities scored
Low vaccination coveragePenta 3 coverage below 70%: more than 20 points under the 90% target, the scorecard's red band226
ANC dropoutMore than 50% of women who start antenatal care (ANC 1) do not reach a fourth visit (ANC 4)990

Only facilities that report Penta doses can be scored for coverage (226 of them), and only facilities with at least 10 ANC 1 visits in the last quarter for dropout (990).

The model is a logistic regression, a well-understood statistical method that estimates the probability of a yes-or-no outcome. Its inputs are each facility's recent DHIS2 history: coverage or dropout over the last three and six months, reporting completeness, the size of the population served, and the level in its district. The output is a risk between 0% and 100%, shown in three bands: high (60% or more), medium (35 to 60%) and low. Because the model is a weighted sum of named factors, every estimate can be explained: the app lists the factors that raise each facility's risk the most.

The Risk forecast page: a map of facility risk and a ranked list with the main reasons, here for low Penta 3 coverage

Figure 6: The Risk forecast page: a map of facility risk and a ranked list with the main reasons, here for low Penta 3 coverage

Every estimate comes with its reasons. Here, very low recent Penta 3 coverage drives a high estimated risk

Figure 7: Every estimate comes with its reasons. Here, very low recent Penta 3 coverage drives a high estimated risk

Is it any good? A model is only useful if it is tested honestly. I trained it on quarters that ended before Jul 2026, then checked its estimates against what actually happened in Jul 2026 to Sep 2026 at facilities it had not seen in that period. I compared it with the simplest possible rule, "same as last quarter":

Test quarter: Jul 2026 to Sep 2026Low Penta 3 coverageHigh ANC dropout
Facilities tested225971
How many actually fell behind (base rate)28%64%
Ranking accuracy (AUC), model0.820.85
Ranking accuracy (AUC), "same as last quarter"0.790.86
Correct calls, model vs simple rule78% vs 72%76% vs 79%
Of the 10% rated riskiest, how many did fall behind18 of 2294 of 97

For vaccination coverage, the model ranks facilities better than the simple rule. For ANC dropout it does about as well, not better: a facility's recent dropout already carries most of the signal, and the model's contribution there is a probability and an explanation rather than better ranking. The app states this on the page, and shows a calibration chart so users can see whether "70% risk" really means about 70%. AUC (area under the curve) is the chance that a facility which did fall behind was rated riskier than one that did not: 0.5 is guessing, 1.0 is perfect.

The model card on the Risk forecast page: what the model uses, how it was tested, an honest verdict against the simple rule, and calibration

Figure 8: The model card on the Risk forecast page: what the model uses, how it was tested, an honest verdict against the simple rule, and calibration

Using the latest data (Jul 2026 to Sep 2026), the app estimates risk for the following quarter. For coverage, 23 facilities have a high estimated risk; summed, the probabilities suggest that about 66 of the 226 facilities may fall below 70%. These are estimates, a prompt to look more closely, not findings.

System architecture and workflow

One DHIS2 source, two applicationsDHIS2play.im.dhis2.org · v2.42.6Sierra Leone demo dataWeb API (HTTPS):analytics · organisationUnitssystem/infoDHIS2 + POWER BI · descriptive: what has happenedPower Query (M)DHIS2Get, AnalyticsTableparameters: server, orgunit, periods152 chiefdoms × 12 monthsSemantic modelDAX measures:coverage, dropout,reporting rate, shading,findings, actionsPower BI reportOverview · DistrictsActions · Connectionslicers, scorecards,written findingsDHIS2 + SHINY FOR PYTHON · descriptive + predictivePython clienthttpx: the same requests152 chiefdoms and1,166 facilities× 12 months+ district boundariespandas + numpythe same measures,checked against Power BIlogistic regression perfacility, time-split testShiny + React appthe four report pages+ Risk forecast:probabilities, reasons,model cardPeopleprogramme managers,M&E officers, DHMTs:interpret, verify,prioritise, follow upSame indicator catalogue, same denominators, same formulas in both: the Shiny app reproduces every Power BI figure.
Figure 9: System architecture. Both applications read the same DHIS2 Web API endpoints and indicator catalogue; the Shiny application adds facility-level data and the risk model. People interpret and act on the results.

Both applications use the same DHIS2 endpoints and the same indicator catalogue: ANC 1 and ANC 4 visits, BCG, Penta 1, Penta 3 and measles doses, and two reporting rates, with expected pregnancies and the population under one year as denominators. Credentials stay on the server side: report parameters in Power BI, environment variables in the Shiny app, never in the browser. The Shiny app starts instantly from a saved snapshot, pulls live data in the background, and refreshes on demand.

1 ExtractDHIS2 Web APImonthly analytics,numerators + populations2 Processannualised targets,coverage, dropout,reporting rates3 VisualiseKPIs, trends,scorecards, maps,findings4 Modelfacility features,logistic regression,test on unseen quarter5 Interpretobserved vs estimated,reasons per facility,known limitationsSteps 4 and 5: Shiny for Python only6 Human follow-up (outside the apps)verify the data, supportive supervision, defaulter tracing, decisions on resources
Figure 10: From DHIS2 to decisions. Extraction, processing and visualisation are shared; modelling and interpretation of estimates are added in Shiny for Python. Decisions happen outside the tools, with people.

Comparing the two approaches

Descriptive analyticsWhat has happened, and where?• Penta 3 coverage 27.6% against a 90% target• 12,822 children started Penta but missed dose 3• 151,211 women left ANC before 4 visits• Lowest district, chiefdom scorecardsPower BI and Shiny · observed DHIS2 dataPredictive analyticsWhere might problems arise next?• Probability of Penta 3 coverage below 70%• 23 facilities at high risk (60% or more)• Reasons shown for every estimate• Tested on a quarter it had not seenShiny only · model estimatesadds
Figure 11: Descriptive and predictive analytics answer different questions. Observed figures on the left; model estimates on the right.
DHIS2 + Power BIDHIS2 + Shiny for Python + risk model
PurposeUnderstand performance: what has happened, and whereEverything on the left, plus: where might problems arise next?
DataDHIS2 analytics by chiefdom and monthThe same, plus every health facility
AnalyticsDescriptive: coverage, dropout, reporting, targets, rule-based findingsDescriptive (identical figures) and predictive: logistic regression per facility
OutputsKPI cards, trends, scorecards, recommended actions, data-quality flagsThe same, plus risk probabilities, risk bands, reasons, a map and a model card
StrengthsFast to build, familiar to many organisations, strong sharing and governance in the Power BI serviceOpen source, fully customisable, the model and the dashboard in one place, testable code
Use casesMonthly reviews, performance reporting, district and partner meetingsPlanning supportive supervision, prioritising follow-up visits, exploring early warning

The two are not competitors. Power BI gives stakeholders a trusted picture of what has happened. Shiny for Python shows how the same data, once it flows freely from DHIS2, can also support questions about the future. Together they show the point of interoperability: one source of truth, and the right tool for each question.

What this could mean for public health decisions

Used responsibly, tools like these can help health teams to:

Throughout, it matters to keep three kinds of information apart, and the application does so:

Observedwhat DHIS2 data show, such as Penta 3 coverage of 27.6%.
Estimatedwhat the model suggests, such as an estimated risk of 82% that Koidu Under Five Clinic's Penta 3 coverage falls below 70% next quarter.
Follow-upwhat people may decide to do, such as checking the facility's data and visiting it. The tools inform this step; they do not take it.

Lessons learned and what comes next

Watch both tours

DHIS2 + Power BI: a one-minute tour
DHIS2 + Shiny for Python: a two-minute tour, including the risk forecast

Conclusion

Routine health data becomes valuable when it reaches decision-makers as clear, trustworthy insight. Connecting DHIS2 to Power BI showed what has happened, across districts and chiefdoms. Rebuilding the dashboard in Shiny for Python, and adding a carefully tested risk model, showed how the same interoperable data can also help ask where problems may arise next, and where to look first.

I'd like to hear from DHIS2 implementers, M&E officers and programme managers: which indicators would you want a risk estimate for, and how would you want it presented? Explore the code, watch the tours, and share your feedback. You may also like Pulse, an earlier population-health dashboard built with the same tools.

Watch both tours Open the Shiny app Code

For education and demonstration only, with DHIS2 demo data. See the disclaimer at the end.

Educational-use disclaimer. This project is intended for educational, demonstration and technical learning purposes. It illustrates how DHIS2 can be connected to Power BI and Shiny for Python to support public health data analysis, policy planning and resource allocation.
  • The data come from the public DHIS2 demo playground (Sierra Leone demo database). They and every output derived from them must not be read as verified evidence of the current performance of any real health facility, chiefdom or district.
  • The predictive model demonstrates one possible analytical approach. It is not a validated clinical or operational decision-making system, and its estimates are not judgements on any facility or health worker.
  • Its estimates depend on data quality, the suitability of the selected variables, the model's assumptions and how it is validated. Here it was checked on a single quarter of demo data.
  • Any real-world deployment would require further validation, appropriate governance and data protection, and interpretation by qualified public health stakeholders.