<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Software | Carlos Mendez</title><link>https://carlos-mendez.org/software/</link><atom:link href="https://carlos-mendez.org/software/index.xml" rel="self" type="application/rss+xml"/><description>Software</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><copyright>© 2018–2026 Carlos Mendez. All rights reserved.</copyright><image><url>https://carlos-mendez.org/media/icon_huedfae549300b4ca5d201a9bd09a3ecd5_79625_512x512_fill_lanczos_center_3.png</url><title>Software</title><link>https://carlos-mendez.org/software/</link></image><item><title>scspill</title><link>https://carlos-mendez.org/software/scspill/</link><pubDate>Tue, 28 Jul 2026 00:00:00 +0000</pubDate><guid>https://carlos-mendez.org/software/scspill/</guid><description>&lt;p>&lt;strong>Synthetic control when the treatment leaks — the effect on the treated unit &lt;em>and&lt;/em> the spillover received by every donor.&lt;/strong>&lt;/p>
&lt;p>&lt;code>scspill&lt;/code> is a Python package of synthetic control models that drop SUTVA on the donor pool. The treatment is allowed to reach the controls, and every model reports two estimands: the effect on the treated unit, purged of the contamination, and the spillover effect received by each donor — something classical synthetic control cannot express at all. The model available today, &lt;code>sar&lt;/code>, routes spillovers through spatial weights you supply, scaled by a single intensity ρ that is &lt;strong>estimated rather than assumed&lt;/strong>; it fits unconstrained horseshoe-shrunk synthetic weights, so donors may be dropped, enter negatively, or extrapolate, and it returns full Bayesian uncertainty for both estimands. At ρ = 0 it collapses exactly to the Bayesian horseshoe synthetic control. The estimator architecture follows &lt;a href="https://github.com/jgreathouse9/mlsynth" target="_blank" rel="noopener">mlsynth&lt;/a> — a pydantic config in, a standardized results object out — and the &lt;code>method&lt;/code> names match its &lt;code>SPILLSYNTH&lt;/code> dispatcher, so the two libraries compose naturally.&lt;/p>
&lt;h3 id="-get-startedhttpsquarcs-labgithubioscspillget-startedhtml">🚀 &lt;a href="https://quarcs-lab.github.io/scspill/get-started.html" target="_blank" rel="noopener">Get started&lt;/a>&lt;/h3>
&lt;p>Fit a model on California&amp;rsquo;s Proposition 99 in about ten lines: the &lt;strong>ATT with a 95% credible interval&lt;/strong>, the spillover intensity ρ, the year-by-year spillover received by every donor, MCMC diagnostics, and counterfactual plots.&lt;/p>
&lt;p>&lt;a href="https://colab.research.google.com/github/quarcs-lab/scspill/blob/main/notebooks/california.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h3 id="-modelshttpsquarcs-labgithubioscspillmodels">🧬 &lt;a href="https://quarcs-lab.github.io/scspill/models/" target="_blank" rel="noopener">Models&lt;/a>&lt;/h3>
&lt;p>One model ships today: &lt;a href="https://quarcs-lab.github.io/scspill/models/sar.html" target="_blank" rel="noopener">&lt;code>sar&lt;/code>&lt;/a>, the Bayesian spatial-autoregressive spillover SCM of &lt;a href="https://doi.org/10.1093/ectj/utag006" target="_blank" rel="noopener">Sakaguchi &amp;amp; Tagawa (2026)&lt;/a>. Three further spillover-aware models are on the &lt;a href="https://quarcs-lab.github.io/scspill/models/#planned" target="_blank" rel="noopener">roadmap&lt;/a> — Cao &amp;amp; Dowd, the inclusive SCM of Di Stefano &amp;amp; Mellace, and the partial-interference SCG of Grossi et al. They are &lt;strong>not implemented&lt;/strong>, and &lt;code>SCSPILLConfig&lt;/code> rejects their names rather than falling back silently.&lt;/p>
&lt;h3 id="-validationhttpsquarcs-labgithubioscspillarticlesvalidationhtml">🧪 &lt;a href="https://quarcs-lab.github.io/scspill/articles/validation.html" target="_blank" rel="noopener">Validation&lt;/a>&lt;/h3>
&lt;p>Evidence that the &lt;code>sar&lt;/code> sampler is correct: the &lt;strong>Geweke (2004) joint distribution test&lt;/strong>, prior-sensitivity grids, prior predictive checks, and cross-validation against the authors&amp;rsquo; frozen R credible intervals.&lt;/p>
&lt;h2 id="whats-inside">What&amp;rsquo;s inside&lt;/h2>
&lt;p>&lt;strong>&lt;code>scspill&lt;/code>&lt;/strong> — the model layer. &lt;code>SCSPILL(config).fit()&lt;/code> returns the ATT and its credible interval, the counterfactual path, the ρ posterior, a time-by-donor spillover panel, and MCMC diagnostics.&lt;/p>
&lt;p>&lt;strong>&lt;code>scspill.validation&lt;/code>&lt;/strong> — &lt;code>sar&lt;/code>&amp;rsquo;s sampler validation: the Geweke joint distribution test, prior-sensitivity grids, and prior predictive checks.&lt;/p>
&lt;p>&lt;strong>&lt;code>scspill.simulate&lt;/code>&lt;/strong> — &lt;code>sar&lt;/code>&amp;rsquo;s &lt;a href="https://quarcs-lab.github.io/scspill/articles/simulation-study.html" target="_blank" rel="noopener">Monte Carlo engine&lt;/a>: a rook-lattice SAR data-generating process and the SCM / BSCM / SCSPILL comparison behind Tables 1–2 of the paper.&lt;/p>
&lt;p>&lt;strong>&lt;code>scspill.data&lt;/code>&lt;/strong> — the bundled spillover panels below. They are model-agnostic, so any model added later can use them unchanged.&lt;/p>
&lt;p>&lt;strong>&lt;code>sar&lt;/code> is validated, not just implemented&lt;/strong> — it is cross-validated against the authors&amp;rsquo; R replication package: the California and Sudan posteriors against the frozen R credible intervals, the Monte Carlo grid against the paper&amp;rsquo;s frozen tables, and the prior predictive statistics to three decimals. The defaults are &lt;em>paper-correct&lt;/em>: several documented bugs of the reference implementation are fixed, each with an escape hatch or a benchmark quantifying the difference — see the &lt;a href="https://quarcs-lab.github.io/scspill/models/sar.html" target="_blank" rel="noopener">&lt;code>sar&lt;/code> model page&lt;/a>.&lt;/p>
&lt;h2 id="bundled-case-studies">Bundled case studies&lt;/h2>
&lt;p>&lt;code>scspill.data&lt;/code> ships two ready-to-estimate &lt;a href="https://quarcs-lab.github.io/scspill/articles/datasets.html" target="_blank" rel="noopener">datasets&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>California&lt;/strong> — Proposition 99, 39 states (1970–2000): per-capita cigarette sales with rook-contiguity weights, via &lt;code>scspill.data.load_california()&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Sudan&lt;/strong> — the 2011 secession, 34 African countries (2000–2015): GDP per capita with trade-network weights, via &lt;code>scspill.data.load_sudan()&lt;/code>. Worked through in the &lt;a href="https://quarcs-lab.github.io/scspill/sudan.html" target="_blank" rel="noopener">Sudan case study&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;p>Install the latest release from PyPI (the core install is pure NumPy/SciPy; the &lt;code>numba&lt;/code> extra adds JIT-compiled samplers):&lt;/p>
&lt;pre>&lt;code class="language-bash">pip install scspill # NumPy/SciPy sampler backend
pip install &amp;quot;scspill[numba]&amp;quot; # + JIT-compiled samplers (~10x faster)
pip install &amp;quot;scspill @ git+https://github.com/quarcs-lab/scspill.git&amp;quot; # latest
&lt;/code>&lt;/pre>
&lt;p>Requires Python 3.10+.&lt;/p>
&lt;h2 id="at-a-glance">At a glance&lt;/h2>
&lt;p>Load a bundled case study, fit the sampler, and read off both estimands:&lt;/p>
&lt;pre>&lt;code class="language-python">from scspill import SCSPILL
from scspill.data import load_california
panel = load_california() # Prop 99 panel + rook-contiguity weights
result = SCSPILL(
{**panel.config_kwargs(), &amp;quot;m_iter&amp;quot;: 20_000, &amp;quot;burn&amp;quot;: 10_000, &amp;quot;seed&amp;quot;: 42}
).fit()
result.att, result.att_ci # treatment effect on California + 95% CrI
result.rho_hat, result.rho_ci # spillover intensity posterior
result.spillover_panel[&amp;quot;Nevada&amp;quot;] # the effect received by Nevada, per year
result.diagnostics() # ESS / R-hat / MCSE per chain
result.plot(kind=&amp;quot;panel&amp;quot;) # counterfactual | effect | top spillovers
&lt;/code>&lt;/pre>
&lt;p>Head to &lt;a href="https://quarcs-lab.github.io/scspill/get-started.html" target="_blank" rel="noopener">Get started&lt;/a>, &lt;a href="https://quarcs-lab.github.io/scspill/models/" target="_blank" rel="noopener">Models&lt;/a> and &lt;a href="https://quarcs-lab.github.io/scspill/articles/validation.html" target="_blank" rel="noopener">Validation&lt;/a> to see the estimators in action.&lt;/p>
&lt;h2 id="built-on">Built on&lt;/h2>
&lt;p>&lt;code>scspill&lt;/code> keeps its dependencies deliberately light — the modern Python scientific stack, and nothing else:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://numpy.org" target="_blank" rel="noopener">NumPy&lt;/a>&lt;/strong> and &lt;strong>&lt;a href="https://scipy.org" target="_blank" rel="noopener">SciPy&lt;/a>&lt;/strong> — the sampler backend&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://pandas.pydata.org" target="_blank" rel="noopener">pandas&lt;/a>&lt;/strong> — panels and the spillover tables&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://docs.pydantic.dev" target="_blank" rel="noopener">pydantic&lt;/a>&lt;/strong> — the validated estimator configuration&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://matplotlib.org" target="_blank" rel="noopener">matplotlib&lt;/a>&lt;/strong> — the diagnostic and counterfactual figures&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://numba.pydata.org" target="_blank" rel="noopener">numba&lt;/a>&lt;/strong> — optional JIT-compiled samplers&lt;/li>
&lt;/ul>
&lt;h2 id="acknowledgement">Acknowledgement&lt;/h2>
&lt;p>&lt;code>scspill&lt;/code> is authored by Carlos Mendez, Shosei Sakaguchi and Hayato Tagawa. The Python package is written and maintained by Carlos Mendez; the &lt;code>sar&lt;/code> model and its original R/C++ implementation are the work of Shosei Sakaguchi and Hayato Tagawa. Their &lt;a href="https://doi.org/10.5281/zenodo.19066186" target="_blank" rel="noopener">replication package&lt;/a> is MIT-licensed, its copyright notice is retained in the library&amp;rsquo;s &lt;code>LICENSE&lt;/code>, and every release of &lt;code>scspill&lt;/code> is cross-validated against its frozen results. The estimator architecture follows Jared Greathouse&amp;rsquo;s &lt;a href="https://github.com/jgreathouse9/mlsynth" target="_blank" rel="noopener">mlsynth&lt;/a>; the documentation stack follows the QuaRCS Lab&amp;rsquo;s &lt;a href="https://github.com/quarcs-lab/geometrics" target="_blank" rel="noopener">geometrics&lt;/a> package.&lt;/p>
&lt;p>If you use &lt;code>scspill&lt;/code>, please cite the software (machine-readable metadata lives in &lt;a href="https://github.com/quarcs-lab/scspill/blob/main/CITATION.cff" target="_blank" rel="noopener">&lt;code>CITATION.cff&lt;/code>&lt;/a>):&lt;/p>
&lt;blockquote>
&lt;p>Mendez, C., Sakaguchi, S., &amp;amp; Tagawa, H. (2026). &lt;em>Synthetic Control Models with Spillovers in Python&lt;/em> (version 0.2.1). &lt;a href="https://github.com/quarcs-lab/scspill" target="_blank" rel="noopener">https://github.com/quarcs-lab/scspill&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>Released under the MIT license.&lt;/p></description></item><item><title>geometrics</title><link>https://carlos-mendez.org/software/geometrics/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate><guid>https://carlos-mendez.org/software/geometrics/</guid><description>&lt;p>&lt;strong>Regional growth, convergence, and inequality — spatially, in Python.&lt;/strong>&lt;/p>
&lt;p>&lt;code>geometrics&lt;/code> builds on the &lt;a href="https://pysal.org/" target="_blank" rel="noopener">PySAL&lt;/a> family and wraps the standard analyses of the regional-convergence literature into easy-to-apply functions that return interactive &lt;a href="https://plotly.com/python/" target="_blank" rel="noopener">Plotly&lt;/a> figures, publication-quality &lt;a href="https://posit-dev.github.io/great-tables/" target="_blank" rel="noopener">Great Tables&lt;/a>, and tidy DataFrames. It pairs an &lt;strong>Explore / Analyze / Learn&lt;/strong> workflow with a built-in &lt;strong>teaching layer&lt;/strong> that interprets and explains every result, and &lt;strong>three no-code apps&lt;/strong>. It is built for students, teachers and applied researchers alike.&lt;/p>
&lt;h3 id="-explorehttpsquarcs-labgithubiogeometricsexplorehtml">🗺️ &lt;a href="https://quarcs-lab.github.io/geometrics/explore.html" target="_blank" rel="noopener">Explore&lt;/a>&lt;/h3>
&lt;p>Map and describe your regions: classified and animated choropleths, spatial-weights connectivity, &lt;strong>Moran scatterplots and LISA cluster maps&lt;/strong>, and space-time views.&lt;/p>
&lt;p>&lt;a href="https://geometrics-explore.streamlit.app/" target="_blank" rel="noopener">🚀 Launch app&lt;/a> · &lt;a href="https://colab.research.google.com/github/quarcs-lab/geometrics/blob/main/notebooks/explore.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h3 id="-analyzehttpsquarcs-labgithubiogeometricsanalyzehtml">🧮 &lt;a href="https://quarcs-lab.github.io/geometrics/analyze.html" target="_blank" rel="noopener">Analyze&lt;/a>&lt;/h3>
&lt;p>Estimate the models: &lt;strong>β-, σ- and club convergence&lt;/strong>, spatial econometric models with impacts, Markov and spatial-Markov dynamics, &lt;strong>Gini/Theil inequality&lt;/strong> with spatial decomposition, and GWR / multiscale GWR.&lt;/p>
&lt;p>&lt;a href="https://geometrics-analyze.streamlit.app/" target="_blank" rel="noopener">🚀 Launch app&lt;/a> · &lt;a href="https://colab.research.google.com/github/quarcs-lab/geometrics/blob/main/notebooks/analyze.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h3 id="-learnhttpsquarcs-labgithubiogeometricslearnhtml">📚 &lt;a href="https://quarcs-lab.github.io/geometrics/learn.html" target="_blank" rel="noopener">Learn&lt;/a>&lt;/h3>
&lt;p>See the ideas behind the methods: &lt;strong>11 runnable concept sandboxes&lt;/strong> where you tune a known truth, a &lt;strong>30-topic&lt;/strong> explainer index, and a plain-language reading on every result.&lt;/p>
&lt;p>&lt;a href="https://geometrics-learn.streamlit.app/" target="_blank" rel="noopener">🚀 Launch app&lt;/a> · &lt;a href="https://colab.research.google.com/github/quarcs-lab/geometrics/blob/main/notebooks/learn.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h2 id="try-the-apps-in-your-browser">Try the apps in your browser&lt;/h2>
&lt;p>No install, no code — the three &lt;code>geometrics&lt;/code> apps run the whole workflow in your browser: point-and-click maps and models, sortable tables, and reproducible exports. Each is the no-code companion to a docs case study.&lt;/p>
&lt;p>&lt;a href="https://geometrics-explore.streamlit.app/" target="_blank" rel="noopener">🗺️ Explore app&lt;/a> · &lt;a href="https://geometrics-analyze.streamlit.app/" target="_blank" rel="noopener">🧮 Analyze app&lt;/a> · &lt;a href="https://geometrics-learn.streamlit.app/" target="_blank" rel="noopener">📚 Learn app&lt;/a>&lt;/p>
&lt;h2 id="whats-inside">What&amp;rsquo;s inside&lt;/h2>
&lt;p>&lt;strong>Maps &amp;amp; ESDA&lt;/strong> — classified / animated choropleths, spatial-weights connectivity, Moran scatterplots, LISA cluster maps, and Moran&amp;rsquo;s I over time.&lt;/p>
&lt;p>&lt;strong>Space-time dynamics&lt;/strong> — cross-sectional distribution evolution and entity-by-time heatmaps.&lt;/p>
&lt;p>&lt;strong>Convergence&lt;/strong> — β-convergence with OLS or spatial estimators, σ-convergence, and Phillips–Sul convergence clubs with club maps.&lt;/p>
&lt;p>&lt;strong>Spatial econometrics&lt;/strong> — the &lt;code>spreg&lt;/code> suite, LM diagnostics with model recommendation, and alternative-weights robustness.&lt;/p>
&lt;p>&lt;strong>Distribution dynamics&lt;/strong> — Markov and spatial-Markov transition analysis.&lt;/p>
&lt;p>&lt;strong>Inequality&lt;/strong> — Gini / Theil trends with spatial decomposition, and Theil between/within decomposition.&lt;/p>
&lt;p>&lt;strong>Local models&lt;/strong> — GWR and multiscale GWR with mapped local coefficients.&lt;/p>
&lt;p>&lt;strong>Concept sandboxes&lt;/strong> — 11 teaching functions that simulate data from known data-generating processes.&lt;/p>
&lt;h2 id="bundled-case-studies">Bundled case studies&lt;/h2>
&lt;p>&lt;code>geometrics.data&lt;/code> ships two ready-to-analyze case studies:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>India&lt;/strong> — 520 districts, satellite nighttime lights (1996–2010): &lt;code>gm.data.load_india()&lt;/code>, &lt;code>load_india_states()&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Bolivia&lt;/strong> — PWT-anchored local GDP (2021 PPP US\$, 2012–2022) at three geographic scales: &lt;code>gm.data.load_bolivia()&lt;/code> (112 provinces), &lt;code>load_bolivia_departments()&lt;/code> (9 departments), and &lt;code>load_bolivia_grid()&lt;/code> (1,603 cells).&lt;/li>
&lt;/ul>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;p>Install the latest release from PyPI (the core install covers most workflows; extras add the Markov dynamics, the no-code apps, and PNG export):&lt;/p>
&lt;pre>&lt;code class="language-bash">pip install geometrics # core
pip install &amp;quot;geometrics[dynamics]&amp;quot; # + Markov / spatial Markov (giddy)
pip install &amp;quot;geometrics[streamlit]&amp;quot; # + the three no-code apps
pip install &amp;quot;geometrics[all]&amp;quot; # everything, incl. PNG export
&lt;/code>&lt;/pre>
&lt;p>Requires Python 3.11+.&lt;/p>
&lt;h2 id="at-a-glance">At a glance&lt;/h2>
&lt;p>Load a bundled case study, attach its variable labels, and map it — every figure is an interactive Plotly object:&lt;/p>
&lt;pre>&lt;code class="language-python">import geometrics as gm
# India — 520 districts, satellite nighttime lights (1996–2010)
gdf, df, df_dict = gm.data.load_india()
df = gm.set_labels(df, df_dict, set_panel=True)
# A classified choropleth of nighttime lights in 2010
gm.explore_choropleth_map(df, &amp;quot;ntl_total&amp;quot;, gdf=gdf, period=2010).fig
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Estimate convergence and let it explain itself&lt;/strong> — β- and σ-convergence, each with a plain-language reading:&lt;/p>
&lt;pre>&lt;code class="language-python">beta = gm.analyze_beta_convergence(df, &amp;quot;ntl_total&amp;quot;, model=&amp;quot;ols&amp;quot;)
print(beta.interpret()) # plain-language, associational reading
sigma = gm.analyze_sigma_convergence(df, &amp;quot;ntl_total&amp;quot;)
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Learn as you go&lt;/strong> — concept sandboxes and explainers:&lt;/p>
&lt;pre>&lt;code class="language-python">gm.learn_beta_convergence(convergence_rate=0.02) # a runnable concept sandbox
print(gm.explain(&amp;quot;spatial_autocorrelation&amp;quot;)) # a concept explainer; gm.list_topics() lists all 30
&lt;/code>&lt;/pre>
&lt;p>Head to &lt;a href="https://quarcs-lab.github.io/geometrics/explore.html" target="_blank" rel="noopener">Explore&lt;/a>, &lt;a href="https://quarcs-lab.github.io/geometrics/analyze.html" target="_blank" rel="noopener">Analyze&lt;/a> and &lt;a href="https://quarcs-lab.github.io/geometrics/learn.html" target="_blank" rel="noopener">Learn&lt;/a> to see every function in action.&lt;/p>
&lt;h2 id="built-on">Built on&lt;/h2>
&lt;p>&lt;code>geometrics&lt;/code> stands on the &lt;a href="https://pysal.org/" target="_blank" rel="noopener">PySAL&lt;/a> spatial-analysis ecosystem and the modern Python data stack:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://pysal.org/" target="_blank" rel="noopener">PySAL&lt;/a>&lt;/strong> — &lt;code>libpysal&lt;/code> (weights), &lt;code>esda&lt;/code> (Moran&amp;rsquo;s I / LISA), &lt;code>giddy&lt;/code> (distribution dynamics), &lt;code>inequality&lt;/code> (Gini / Theil), &lt;code>mapclassify&lt;/code> (choropleth classification), &lt;code>spreg&lt;/code> (spatial regression), and &lt;code>mgwr&lt;/code> (multiscale GWR)&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://geopandas.org/" target="_blank" rel="noopener">geopandas&lt;/a>&lt;/strong> — geospatial dataframes&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://plotly.com/python/" target="_blank" rel="noopener">Plotly&lt;/a>&lt;/strong> — interactive figures&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://posit-dev.github.io/great-tables/" target="_blank" rel="noopener">Great Tables&lt;/a>&lt;/strong> — publication-quality tables&lt;/li>
&lt;/ul>
&lt;h2 id="acknowledgement">Acknowledgement&lt;/h2>
&lt;p>&lt;code>geometrics&lt;/code> is developed at the &lt;a href="https://quarcs-lab.org" target="_blank" rel="noopener">QuaRCS Lab&lt;/a> (Quantitative Regional and Computational Science) and stands on the shoulders of the &lt;a href="https://pysal.org/" target="_blank" rel="noopener">PySAL&lt;/a> project, geopandas, Plotly and Great Tables. If you use &lt;code>geometrics&lt;/code> in your research, please cite the repository (see &lt;a href="https://github.com/quarcs-lab/geometrics/blob/main/CITATION.cff" target="_blank" rel="noopener">&lt;code>CITATION.cff&lt;/code>&lt;/a>) and the underlying PySAL packages.&lt;/p></description></item><item><title>expdpy</title><link>https://carlos-mendez.org/software/expdpy/</link><pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate><guid>https://carlos-mendez.org/software/expdpy/</guid><description>&lt;p>&lt;strong>Explore, analyze and learn panel data — interactively, in Python.&lt;/strong>&lt;/p>
&lt;p>&lt;code>expdpy&lt;/code> pairs composable functions that return interactive &lt;a href="https://plotly.com/python/" target="_blank" rel="noopener">Plotly&lt;/a> figures and publication-quality &lt;a href="https://posit-dev.github.io/great-tables/" target="_blank" rel="noopener">Great Tables&lt;/a> with &lt;strong>fixest-style econometrics&lt;/strong>, a built-in &lt;strong>teaching layer&lt;/strong> that interprets and explains every result, and &lt;strong>three no-code apps&lt;/strong>. It is built for students, teachers and applied researchers alike.&lt;/p>
&lt;h3 id="-explorehttpscmg777githubioexpdpyexplorehtml">🔍 &lt;a href="https://cmg777.github.io/expdpy/explore.html" target="_blank" rel="noopener">Explore&lt;/a>&lt;/h3>
&lt;p>Describe and visualize your panel: tables, distributions, missing-value maps, time trends, group comparisons, scatter plots, &lt;strong>within/between variation&lt;/strong> and &lt;strong>panel dynamics&lt;/strong>.&lt;/p>
&lt;p>&lt;a href="https://expdpy-explore.streamlit.app/" target="_blank" rel="noopener">🚀 Launch app&lt;/a> · &lt;a href="https://colab.research.google.com/github/cmg777/expdpy/blob/main/notebooks/explore.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h3 id="-analyzehttpscmg777githubioexpdpyanalyzehtml">🧮 &lt;a href="https://cmg777.github.io/expdpy/analyze.html" target="_blank" rel="noopener">Analyze&lt;/a>&lt;/h3>
&lt;p>Estimate models: fixed / random / &lt;strong>correlated random effects&lt;/strong>, FWL, the Hausman test, robust inference, &lt;strong>event-study / DiD&lt;/strong>, &lt;strong>β/σ/club convergence&lt;/strong> and the &lt;strong>Kuznets-waves&lt;/strong> curve.&lt;/p>
&lt;p>&lt;a href="https://expdpy-analyze.streamlit.app/" target="_blank" rel="noopener">🚀 Launch app&lt;/a> · &lt;a href="https://colab.research.google.com/github/cmg777/expdpy/blob/main/notebooks/analyze.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h3 id="-learnhttpscmg777githubioexpdpylearnhtml">📚 &lt;a href="https://cmg777.github.io/expdpy/learn.html" target="_blank" rel="noopener">Learn&lt;/a>&lt;/h3>
&lt;p>See the ideas behind the methods: &lt;strong>9 runnable concept sandboxes&lt;/strong> where you tune a known truth, a &lt;strong>27-topic&lt;/strong> explainer index, and a plain-language reading on every result.&lt;/p>
&lt;p>&lt;a href="https://expdpy-learn.streamlit.app/" target="_blank" rel="noopener">🚀 Launch app&lt;/a> · &lt;a href="https://colab.research.google.com/github/cmg777/expdpy/blob/main/notebooks/learn.ipynb" target="_blank" rel="noopener">▶ Open in Colab&lt;/a>&lt;/p>
&lt;h2 id="try-the-apps-in-your-browser">Try the apps in your browser&lt;/h2>
&lt;p>No install, no code — the three &lt;code>ExPdPy&lt;/code> apps run the whole workflow in your browser: a sample pipeline, point-and-click analysis, sortable tables, and reproducible notebook export. Each is the no-code companion to a docs case study.&lt;/p>
&lt;p>&lt;a href="https://expdpy-explore.streamlit.app/" target="_blank" rel="noopener">🔍 Explore app&lt;/a> · &lt;a href="https://expdpy-analyze.streamlit.app/" target="_blank" rel="noopener">🧮 Analyze app&lt;/a> · &lt;a href="https://expdpy-learn.streamlit.app/" target="_blank" rel="noopener">📚 Learn app&lt;/a>&lt;/p>
&lt;h2 id="whats-inside">What&amp;rsquo;s inside&lt;/h2>
&lt;p>&lt;strong>Explore&lt;/strong> — descriptive / correlation / extreme-observation tables, histograms and bar charts, time and quantile trends, by-group bar / violin / trend views, a missing-value heatmap, scatter plots with an optional LOESS smoother, the within/between (&lt;code>xtsum&lt;/code>) decomposition, per-unit trajectories, panel-structure diagnostics, distribution &amp;amp; transition dynamics, and &lt;code>treat_outliers&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Analyze&lt;/strong> — OLS with &lt;strong>multi-way fixed effects&lt;/strong> and &lt;strong>clustered standard errors&lt;/strong> via &lt;a href="https://github.com/py-econometrics/pyfixest" target="_blank" rel="noopener">pyfixest&lt;/a>; a richer &lt;code>analyze_estimation&lt;/code> (stepwise / multiple-outcome, Newey–West &amp;amp; Driscoll–Kraay SEs); &lt;strong>pooled / between / fixed / random effects&lt;/strong> and the &lt;strong>correlated-random-effects (Mundlak)&lt;/strong> estimator; the &lt;strong>Hausman test&lt;/strong>; post-estimation (fixed-effect plots, predictions, Wald joint tests); &lt;strong>robust inference&lt;/strong> (randomization inference, wild cluster bootstrap); &lt;strong>Frisch–Waugh–Lovell&lt;/strong> and &lt;strong>coefficient&lt;/strong> plots; modern &lt;strong>event-study / staggered difference-in-differences&lt;/strong> (&lt;code>did2s&lt;/code>, Sun–Abraham, LP-DiD, dynamic TWFE); &lt;strong>β-, σ- and club convergence&lt;/strong>; and the &lt;strong>Kuznets-waves&lt;/strong> curve under pooled / between / within estimators.&lt;/p>
&lt;p>&lt;strong>Learn&lt;/strong> — every result speaks plain language: &lt;code>.interpret()&lt;/code> gives an &lt;strong>associational&lt;/strong> reading (never a causal claim unless the design supports it) and &lt;code>.explain()&lt;/code> / &lt;code>explain(topic)&lt;/code> / &lt;code>list_topics()&lt;/code> browse &lt;strong>27&lt;/strong> concept explainers. &lt;strong>Nine concept sandboxes&lt;/strong> simulate data so you can &lt;em>see&lt;/em> and tune a known truth — the first-differences ≈ demeaning ≈ dummies identity, fixed effects, clustering, omitted-variable bias, β/σ/club convergence, and the Kuznets wave.&lt;/p>
&lt;p>&lt;strong>Bundled datasets&lt;/strong> — &lt;code>expdpy.data&lt;/code> ships ready-to-explore panels: &lt;strong>&lt;code>kuznets&lt;/code>&lt;/strong> (the flagship N-shaped Kuznets-curve demo), &lt;code>gapminder&lt;/code>, &lt;strong>&lt;code>staggered_did&lt;/code>&lt;/strong> (event-study / DiD), &lt;strong>&lt;code>productivity&lt;/code>&lt;/strong> and &lt;strong>&lt;code>bolivia112_gdppc&lt;/code>&lt;/strong> (convergence). See the &lt;a href="https://cmg777.github.io/expdpy/explanation/kuznets-dataset.html" target="_blank" rel="noopener">kuznets dataset&lt;/a> page for the data dictionary.&lt;/p>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;p>Install the latest release from PyPI (random effects, CRE and the Hausman test work out of the box; the apps need the &lt;code>streamlit&lt;/code> extra):&lt;/p>
&lt;pre>&lt;code class="language-bash">pip install expdpy
pip install &amp;quot;expdpy[streamlit]&amp;quot; # the no-code ExPdPy apps (Streamlit)
&lt;/code>&lt;/pre>
&lt;p>Using &lt;a href="https://docs.astral.sh/uv/" target="_blank" rel="noopener">uv&lt;/a>:&lt;/p>
&lt;pre>&lt;code class="language-bash">uv pip install expdpy
uv pip install &amp;quot;expdpy[streamlit]&amp;quot;
&lt;/code>&lt;/pre>
&lt;p>For the latest unreleased version, install straight from the &lt;code>main&lt;/code> branch:&lt;/p>
&lt;pre>&lt;code class="language-bash">pip install &amp;quot;git+https://github.com/cmg777/expdpy.git&amp;quot;
&lt;/code>&lt;/pre>
&lt;p>Requires Python 3.10+.&lt;/p>
&lt;h2 id="at-a-glance">At a glance&lt;/h2>
&lt;p>The lead example throughout these docs is the bundled &lt;code>kuznets&lt;/code> panel (80 countries × 2015–2025): a synthetic dataset whose regional inequality traces an &lt;strong>N-shaped Kuznets curve&lt;/strong> in income — rising, falling, then rising again at very high income.&lt;/p>
&lt;pre>&lt;code class="language-python">import expdpy as ex
from expdpy.data import load_kuznets
df = load_kuznets()
# The N-shaped regional Kuznets curve: regional inequality vs (log) GDP per capita
ex.explore_scatter_plot(
df, x=&amp;quot;log_gdp_pc&amp;quot;, y=&amp;quot;gini_regional&amp;quot;, color=&amp;quot;continent&amp;quot;, size=&amp;quot;population&amp;quot;, loess=1
).fig
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Run a regression and let it explain itself&lt;/strong> — two-way fixed effects, clustered standard errors, a plain-language reading, and a coefficient plot:&lt;/p>
&lt;pre>&lt;code class="language-python">res = ex.analyze_regression_table(
df,
dvs=&amp;quot;gini_regional&amp;quot;,
idvs=[&amp;quot;log_gdp_pc&amp;quot;, &amp;quot;log_gdp_pc_sq&amp;quot;, &amp;quot;log_gdp_pc_cu&amp;quot;],
feffects=[&amp;quot;country&amp;quot;, &amp;quot;year&amp;quot;],
clusters=[&amp;quot;country&amp;quot;],
)
print(res.interpret()) # plain-language, associational reading
ex.analyze_coefficient_plot(res) # themed coefficient plot with confidence intervals
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Learn as you go&lt;/strong> — concept sandboxes and explainers:&lt;/p>
&lt;pre>&lt;code class="language-python">ex.learn_first_differences() # first differences ≈ demeaning ≈ dummy variables
print(ex.explain(&amp;quot;fixed_effects&amp;quot;)) # a concept explainer; ex.list_topics() lists all 27
&lt;/code>&lt;/pre>
&lt;p>Head to &lt;a href="https://cmg777.github.io/expdpy/explore.html" target="_blank" rel="noopener">Explore&lt;/a>, &lt;a href="https://cmg777.github.io/expdpy/analyze.html" target="_blank" rel="noopener">Analyze&lt;/a> and &lt;a href="https://cmg777.github.io/expdpy/learn.html" target="_blank" rel="noopener">Learn&lt;/a> to see every function in action, or the &lt;a href="https://cmg777.github.io/expdpy/explanation/kuznets-dataset.html" target="_blank" rel="noopener">kuznets dataset&lt;/a> page for the data dictionary.&lt;/p>
&lt;h2 id="built-on">Built on&lt;/h2>
&lt;p>&lt;code>expdpy&lt;/code> stands on the modern Python data and econometrics stack:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://plotly.com/python/" target="_blank" rel="noopener">Plotly&lt;/a>&lt;/strong> — interactive figures&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://github.com/py-econometrics/pyfixest" target="_blank" rel="noopener">pyfixest&lt;/a>&lt;/strong> — fixed-effects and difference-in-differences estimators&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://posit-dev.github.io/great-tables/" target="_blank" rel="noopener">Great Tables&lt;/a>&lt;/strong> — publication-quality tables&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://bashtage.github.io/linearmodels/" target="_blank" rel="noopener">linearmodels&lt;/a>&lt;/strong> — random / between / correlated random effects and the Hausman test&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://streamlit.io/" target="_blank" rel="noopener">Streamlit&lt;/a>&lt;/strong> — the no-code &lt;code>ExPdPy&lt;/code> apps&lt;/li>
&lt;/ul>
&lt;h2 id="acknowledgement">Acknowledgement&lt;/h2>
&lt;p>expdpy began as a Python port of the excellent &lt;a href="https://github.com/trr266/ExPanDaR" target="_blank" rel="noopener">ExPanDaR&lt;/a> R package by &lt;strong>Joachim Gassen&lt;/strong> and the &lt;strong>TRR 266 Accounting for Transparency&lt;/strong> project, and its foundations remain deeply inspired by that work. Over time, expdpy has grown well beyond the original — fixest-style estimators, event-study / difference-in-differences tools, random- and correlated-random-effects panel models, convergence analysis, and a built-in teaching layer that interprets and explains results — and it will keep evolving.&lt;/p>
&lt;p>We are grateful to the ExPanDaR authors. Please cite the original work when using &lt;code>expdpy&lt;/code> in research (see &lt;a href="https://github.com/cmg777/expdpy/blob/main/CITATION.cff" target="_blank" rel="noopener">&lt;code>CITATION.cff&lt;/code>&lt;/a>).&lt;/p></description></item></channel></rss>