<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://mcox3406.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mcox3406.github.io/" rel="alternate" type="text/html" hreflang="en-US" /><updated>2026-10-02T20:34:05+00:00</updated><id>https://mcox3406.github.io/feed.xml</id><title type="html">Matthew Cox</title><subtitle>PhD candidate in chemical engineering at MIT working on machine learning and LLMs for molecular design and discovery.</subtitle><author><name>Matthew Cox</name><email>mcox340@mit.edu</email></author><entry><title type="html">McCabe-Thiele Method in Python</title><link href="https://mcox3406.github.io/blog/2024/mccabe-thiele-method-in-python/" rel="alternate" type="text/html" title="McCabe-Thiele Method in Python" /><published>2024-05-26T00:00:00+00:00</published><updated>2024-05-26T00:00:00+00:00</updated><id>https://mcox3406.github.io/blog/2024/mccabe-thiele-method-in-python</id><content type="html" xml:base="https://mcox3406.github.io/blog/2024/mccabe-thiele-method-in-python/"><![CDATA[<h2 id="introduction">Introduction</h2>
<p>This post gives a brief overview of the McCabe-Thiele method for binary distillation and a demonstration of how to implement it in Python. I’m making this primarily due to my experiences both as a student and TA for ChE 62 (Separation Processes) at Caltech; I was surprised to find that there are few resources available online that provide a clean, simple, step-by-step guide to implementing the McCabe-Thiele method in Python.</p>

<p>I’ll assume that readers are generally familiar with the McCabe-Thiele method. If you’re not, I recommend reading the <a href="https://en.wikipedia.org/wiki/McCabe–Thiele_method">Wikipedia page for the McCabe-Thiele method</a> before proceeding. Alternatively, for much more detail, see the chapter entitled “Distillation of Binary Mixtures” in any edition of <em>Separation Process Principles</em> by Seader, Henley, and Roper.</p>

<h2 id="problem-statement">Problem Statement</h2>
<p>A continuous, steady-state distillation column with a total condenser and partial reboiler is separating 100 kmol/h of a 55 mol% methanol, 45 mol% water feed at 1 atm. We desire a distillate product that is 90 mol% methanol and a bottoms product that is 5 mol% methanol. Determine the plate on which the feed should be introduced and the total number of equilibrium stages required. Assume constant molar overflow.</p>

<h2 id="relevant-equations-for-the-mccabe-thiele-method">Relevant Equations for the McCabe-Thiele Method</h2>
<p>We’ll get the vapor-liquid equilibrium (VLE) data for the binary mixture from experimental data (we could also use an equation of state model to simulate the data, but that’s beyond the scope of this post). Next, the rectifying line and stripping line are constructed using the following equations since we are assuming constant molar overflow:</p>

<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left right" columnspacing="0em 1em"><mtr><mtd class ="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mi>y</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mfrac><mi>R</mi><mrow><mi>R</mi><mo>+</mo><mn>1</mn></mrow></mfrac><mo fence="true">)</mo></mrow><mi>x</mi><mo>+</mo><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mrow><mi>R</mi><mo>+</mo><mn>1</mn></mrow></mfrac><mo fence="true">)</mo></mrow><msub><mi>x</mi><mi>D</mi></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mtext>(rectifying)</mtext><mrow></mrow></mrow></mstyle></mtd><mtd class ="mtr-glue"></mtd><mtd class ="mml-eqn-num"></mtd></mtr><mtr><mtd class ="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mi>y</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mfrac><mrow><msub><mi>V</mi><mi>B</mi></msub><mo>+</mo><mn>1</mn></mrow><msub><mi>V</mi><mi>B</mi></msub></mfrac><mo fence="true">)</mo></mrow><mi>x</mi><mo>−</mo><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><msub><mi>V</mi><mi>B</mi></msub></mfrac><mo fence="true">)</mo></mrow><msub><mi>x</mi><mi>B</mi></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mtext>(stripping)</mtext><mrow></mrow></mrow></mstyle></mtd><mtd class ="mtr-glue"></mtd><mtd class ="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
y &amp;= \left(\frac{R}{R + 1}\right) x + \left(\frac{1}{R + 1}\right)x_D &amp;\text{(rectifying)} \htmlId{eq:rectifyingline}{\tag{1}} \\
y &amp;= \left(\frac{V_B + 1}{V_B}\right) x - \left(\frac{1}{V_B}\right)x_B &amp;\text{(stripping)} \htmlId{eq:strippingline}{\tag{2}}
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:5.1001em;vertical-align:-2.3em;"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.8em;"><span style="top:-4.8em;"><span class="pstrut" style="height:3.45em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span></span></span><span style="top:-2.1em;"><span class="pstrut" style="height:3.45em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.3em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.8em;"><span style="top:-4.8em;"><span class="pstrut" style="height:3.45em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3603em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0077em;">R</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0278em;">D</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.1em;"><span class="pstrut" style="height:3.45em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3603em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.2222em;">V</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.2222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.2222em;">V</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.2222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.836em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.2222em;">V</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.2222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.836em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.3em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:1em;"></span><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.8em;"><span style="top:-4.8em;"><span class="pstrut" style="height:3.45em;"></span><span class="mord"><span class="mord text"><span class="mord">(rectifying)</span></span><span class="enclosing" id="eq:rectifyingline"></span></span></span><span style="top:-2.1em;"><span class="pstrut" style="height:3.45em;"></span><span class="mord"><span class="mord text"><span class="mord">(stripping)</span></span><span class="enclosing" id="eq:strippingline"></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.3em;"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.8em;"><span style="top:-4.8em;"><span class="pstrut" style="height:3.45em;"></span><span><span class="mord text"><span class="mord">(</span><span class="mord"><span class="mord">1</span></span><span class="mord">)</span></span></span></span><span style="top:-2.1em;"><span class="pstrut" style="height:3.45em;"></span><span><span class="mord text"><span class="mord">(</span><span class="mord"><span class="mord">2</span></span><span class="mord">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.3em;"><span></span></span></span></span></span></span></span></span>

<p>where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">y</span></span></span></span> are the mole fractions of the light component in the liquid and vapor phases, respectively; the reflux ratio <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo>=</mo><mi>L</mi><mi mathvariant="normal">/</mi><mi>D</mi></mrow><annotation encoding="application/x-tex">R=L/D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.0077em;">R</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">L</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.0278em;">D</span></span></span></span>; the boilup ratio <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>V</mi><mi>B</mi></msub><mo>=</mo><mover accent="true"><mi>V</mi><mo stretchy="true">‾</mo></mover><mi mathvariant="normal">/</mi><mi>B</mi></mrow><annotation encoding="application/x-tex">V_B=\overline{V}/B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.2222em;">V</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.2222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.1333em;vertical-align:-0.25em;"></span><span class="mord overline"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8833em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.2222em;">V</span></span></span><span style="top:-3.8033em;"><span class="pstrut" style="height:3em;"></span><span class="overline-line" style="border-bottom-width:0.04em;"></span></span></span></span></span></span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.0502em;">B</span></span></span></span>; <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>D</mi></msub></mrow><annotation encoding="application/x-tex">x_D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5806em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0278em;">D</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>B</mi></msub></mrow><annotation encoding="application/x-tex">x_B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5806em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>) and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>y</mi><mi>D</mi></msub></mrow><annotation encoding="application/x-tex">y_D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0278em;">D</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>y</mi><mi>B</mi></msub></mrow><annotation encoding="application/x-tex">y_B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0502em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>) are the mole fractions of the light component in the distillate (bottoms); and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>L</mi></mrow><annotation encoding="application/x-tex">L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal">L</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>V</mi></mrow><annotation encoding="application/x-tex">V</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.2222em;">V</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.0278em;">D</span></span></span></span>, and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.0502em;">B</span></span></span></span> are the liquid, vapor, distillate, and bottoms flow rates, respectively, where an overline represents that the flow rate is in the stripping section. Note: This notation is consistent with <em>Separation Process Principles, 4e</em>.</p>

<h2 id="python-implementation">Python Implementation</h2>
<p>We begin by loading in VLE data for methanol and water from the file <a href="/assets/posts/mccabe-thiele/methanol_water_vle_data.csv"><code class="language-plaintext highlighter-rouge">methanol_water_vle_data.csv</code></a>. This data was adapted from <em>Vapor-Liquid Equilibrium Data Collection</em> by J. Gmehling and U. Onken, 1977, Dechema, Frankfurt, Germany, vol. 1, p. 60. We’ll then plot the data to visualize the VLE curve and plot the 1:1 line (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">y</span></span></span></span> = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span>) for reference. Additionally, we’ll plot the distillate, bottoms, and feed compositions on the plot.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># import necessary libraries
</span><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">from</span> <span class="n">scipy.optimize</span> <span class="kn">import</span> <span class="n">fsolve</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="n">plt</span><span class="p">.</span><span class="n">style</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="sh">'</span><span class="s">ggplot</span><span class="sh">'</span><span class="p">)</span>

<span class="c1"># load data
</span><span class="n">data</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="nf">read_csv</span><span class="p">(</span><span class="sh">'</span><span class="s">methanol_water_vle_data.csv</span><span class="sh">'</span><span class="p">)</span>
<span class="n">x_methanol</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="sh">'</span><span class="s">x_methanol</span><span class="sh">'</span><span class="p">]</span>
<span class="n">y_methanol</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="sh">'</span><span class="s">y_methanol</span><span class="sh">'</span><span class="p">]</span>

<span class="c1"># set up plot
</span><span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplots</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="n">x_methanol</span><span class="p">,</span> <span class="n">y_methanol</span><span class="p">,</span> <span class="sh">'</span><span class="s">o-</span><span class="sh">'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">blue</span><span class="sh">'</span><span class="p">,</span> <span class="n">markersize</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="sh">'</span><span class="s">k</span><span class="sh">'</span><span class="p">)</span>  <span class="c1"># y = x
</span>
<span class="c1"># constants for operating lines
</span><span class="n">R</span><span class="p">,</span> <span class="n">x_D</span> <span class="o">=</span> <span class="mf">1.25</span><span class="p">,</span> <span class="mf">0.90</span>  <span class="c1"># reflux ratio and distillate composition
</span><span class="n">B</span><span class="p">,</span> <span class="n">x_B</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">0.05</span>  <span class="c1"># boilup ratio and bottoms composition
</span><span class="n">z</span> <span class="o">=</span> <span class="mf">0.55</span>  <span class="c1"># feed composition
</span>
<span class="c1"># plot distillate, bottoms, and feed compositions
</span><span class="n">points</span> <span class="o">=</span> <span class="p">[</span><span class="n">x_D</span><span class="p">,</span> <span class="n">x_B</span><span class="p">,</span> <span class="n">z</span><span class="p">]</span>
<span class="n">labels</span> <span class="o">=</span> <span class="p">[</span><span class="sa">r</span><span class="sh">'</span><span class="s">$x_D$</span><span class="sh">'</span><span class="p">,</span> <span class="sa">r</span><span class="sh">'</span><span class="s">$x_B$</span><span class="sh">'</span><span class="p">,</span> <span class="sa">r</span><span class="sh">'</span><span class="s">$z$</span><span class="sh">'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">point</span><span class="p">,</span> <span class="n">label</span> <span class="ow">in</span> <span class="nf">zip</span><span class="p">(</span><span class="n">points</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
    <span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">([</span><span class="n">point</span><span class="p">,</span> <span class="n">point</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">point</span><span class="p">],</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">k</span><span class="sh">'</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="sh">'</span><span class="s">--</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>At this point, our plot should look like Figure 1 below. The VLE data is plotted in blue, the 1:1 line is in black, and the distillate, bottoms, and feed compositions are shown as dashed lines.</p>

<figure>
  <img src="/assets/posts/mccabe-thiele/methanolwater_vle.png" alt="methanol water VLE data" width="600" />
  <figcaption>Figure 1: Methanol-water VLE data with given stream compositions and 1:1 line.</figcaption>
</figure>

<p>Next, we can add our operating lines to the plot; luckily, we have all the information we need to directly use Equations <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow href="#eq:rectifyingline"><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\href{#eq:rectifyingline}{(1)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><a href="#eq:rectifyingline"><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span></a></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow href="#eq:strippingline"><mo stretchy="false">(</mo><mn>2</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\href{#eq:strippingline}{(2)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><a href="#eq:strippingline"><span class="mopen">(</span><span class="mord">2</span><span class="mclose">)</span></a></span></span></span>. We can find the intersection of the rectifying and stripping lines numerically using <code class="language-plaintext highlighter-rouge">scipy.optimize.fsolve</code>. This will allow us to create a cleaner plot by only plotting the rectifying and stripping lines up to the intersection point. Moreover, this will allow us to plot the q-line, as the q-line will pass through the intersection point and the 1:1 line.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># operating line functions
</span><span class="k">def</span> <span class="nf">top_line</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="k">return</span> <span class="n">R</span> <span class="o">/</span> <span class="p">(</span><span class="n">R</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">x_D</span> <span class="o">/</span> <span class="p">(</span><span class="n">R</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">bottom_line</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="nf">return </span><span class="p">(</span><span class="n">B</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="n">B</span> <span class="o">*</span> <span class="n">x</span> <span class="o">-</span> <span class="n">x_B</span> <span class="o">/</span> <span class="n">B</span>

<span class="c1"># finding intersection of operating lines
</span><span class="n">intersection_x</span> <span class="o">=</span> <span class="nf">fsolve</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="nf">top_line</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">-</span> <span class="nf">bottom_line</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="mf">0.5</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">intersection_y</span> <span class="o">=</span> <span class="nf">top_line</span><span class="p">(</span><span class="n">intersection_x</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="n">intersection_x</span><span class="p">,</span> <span class="n">intersection_y</span><span class="p">,</span> <span class="sh">'</span><span class="s">o</span><span class="sh">'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">dodgerblue</span><span class="sh">'</span><span class="p">,</span> <span class="n">zorder</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">plot_line_and_markers</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">color</span><span class="p">,</span> <span class="n">label</span><span class="p">,</span> <span class="n">ls</span><span class="o">=</span><span class="sh">'</span><span class="s">-</span><span class="sh">'</span><span class="p">):</span>
    <span class="n">x_vals</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">linspace</span><span class="p">(</span><span class="o">*</span><span class="n">x_range</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">(</span><span class="n">x_vals</span><span class="p">,</span> <span class="nf">function</span><span class="p">(</span><span class="n">x_vals</span><span class="p">),</span> <span class="n">color</span><span class="o">=</span><span class="n">color</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">,</span> <span class="n">ls</span><span class="o">=</span><span class="n">ls</span><span class="p">)</span>

<span class="c1"># plot operating lines
</span><span class="nf">plot_line_and_markers</span><span class="p">((</span><span class="n">intersection_x</span><span class="p">,</span> <span class="n">x_D</span><span class="p">),</span> <span class="n">top_line</span><span class="p">,</span> <span class="sh">'</span><span class="s">dodgerblue</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Rectifying</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">--</span><span class="sh">'</span><span class="p">)</span>
<span class="nf">plot_line_and_markers</span><span class="p">((</span><span class="n">x_B</span><span class="p">,</span> <span class="n">intersection_x</span><span class="p">),</span> <span class="n">bottom_line</span><span class="p">,</span> <span class="sh">'</span><span class="s">dodgerblue</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Stripping</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">-.</span><span class="sh">'</span><span class="p">)</span>

<span class="c1"># q-line
</span><span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">([</span><span class="n">z</span><span class="p">,</span> <span class="n">intersection_x</span><span class="p">],</span> <span class="p">[</span><span class="n">z</span><span class="p">,</span> <span class="n">intersection_y</span><span class="p">],</span> <span class="sh">'</span><span class="s">k--</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>The plot should now look like Figure 2 below.</p>

<figure>
  <img src="/assets/posts/mccabe-thiele/mw_vle_with_ols.png" alt="base of McCabe-Thiele plot" width="600" />
  <figcaption>Figure 2: Base of McCabe-Thiele plot with operating lines and q-line.</figcaption>
</figure>

<p>Now, we can proceed to the stage-stepping algorithm (i.e., the McCabe-Thiele method). We start from the distillate composition and move horizontally to the equilibrium curve to find the liquid composition. We then move vertically to the operating line to find the vapor composition. We repeat this process until we reach the bottoms composition.</p>

<p>This is very easily implemented in Python. To move horizontally, we interpolate on the VLE data using <code class="language-plaintext highlighter-rouge">numpy.interp</code> to find the corresponding <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span>-value for a given <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">y</span></span></span></span>-value on the VLE curve. To move vertically, we decide which operating line to use based on the intersection point we found earlier (e.g., if we are below it, we are in the stripping section and need to be using the stripping section operating line) and find the corresponding <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.0359em;">y</span></span></span></span>-coordinate for a given <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">x</span></span></span></span>-coordinate on the operating line. We also need to account for the fact that we may not reach the bottoms composition exactly, so we add a check to ensure that if we go below the bottoms composition, we move vertically down to the 1:1 line. We do all of this in a while loop until we reach the bottoms composition.</p>

<p>Finally, we plot the stages on the plot. We alternate between horizontal and vertical lines to represent each stage, and we label each stage with a number.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># McCabe-Thiele stage-stepping
</span><span class="n">stage_x</span><span class="p">,</span> <span class="n">stage_y</span> <span class="o">=</span> <span class="p">[</span><span class="n">x_D</span><span class="p">],</span> <span class="p">[</span><span class="n">x_D</span><span class="p">]</span>  <span class="c1"># starting at distillate composition
</span><span class="k">while</span> <span class="n">stage_x</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">x_B</span><span class="p">:</span>
    <span class="n">new_x</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">interp</span><span class="p">(</span><span class="n">stage_y</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">y_methanol</span><span class="p">,</span> <span class="n">x_methanol</span><span class="p">)</span>  <span class="c1"># move horizontally to equilibrium curve
</span>    <span class="n">new_y</span> <span class="o">=</span> <span class="nf">top_line</span><span class="p">(</span><span class="n">new_x</span><span class="p">)</span> <span class="k">if</span> <span class="n">new_x</span> <span class="o">&gt;</span> <span class="n">intersection_x</span> <span class="k">else</span> <span class="nf">bottom_line</span><span class="p">(</span><span class="n">new_x</span><span class="p">)</span>  <span class="c1"># move vertically to operating line
</span>
    <span class="k">if</span> <span class="n">new_x</span> <span class="o">&lt;</span> <span class="n">x_B</span><span class="p">:</span>
        <span class="n">new_y</span> <span class="o">=</span> <span class="n">new_x</span>

    <span class="n">stage_x</span><span class="p">.</span><span class="nf">extend</span><span class="p">([</span><span class="n">new_x</span><span class="p">,</span> <span class="n">new_x</span><span class="p">])</span>
    <span class="n">stage_y</span><span class="p">.</span><span class="nf">extend</span><span class="p">([</span><span class="n">stage_y</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">new_y</span><span class="p">])</span>

<span class="c1"># plot stages
</span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nf">len</span><span class="p">(</span><span class="n">stage_x</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">):</span>
    <span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">([</span><span class="n">stage_x</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">stage_x</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]],</span> <span class="p">[</span><span class="n">stage_y</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">stage_y</span><span class="p">[</span><span class="n">i</span><span class="p">]],</span>
            <span class="sh">'</span><span class="s">k-</span><span class="sh">'</span><span class="p">,</span> <span class="n">markersize</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>  <span class="c1"># horizontal
</span>    <span class="n">ax</span><span class="p">.</span><span class="nf">plot</span><span class="p">([</span><span class="n">stage_x</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span> <span class="n">stage_x</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]],</span> <span class="p">[</span><span class="n">stage_y</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">stage_y</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]],</span>
            <span class="sh">'</span><span class="s">k-</span><span class="sh">'</span><span class="p">,</span> <span class="n">markersize</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>  <span class="c1"># vertical
</span>    <span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="nf">len</span><span class="p">(</span><span class="n">stage_x</span><span class="p">)</span> <span class="o">-</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">i</span> <span class="o">!=</span> <span class="nf">len</span><span class="p">(</span><span class="n">stage_x</span><span class="p">)</span> <span class="o">-</span> <span class="mi">3</span><span class="p">:</span>
            <span class="n">ax</span><span class="p">.</span><span class="nf">annotate</span><span class="p">(</span><span class="nf">str</span><span class="p">(</span><span class="n">i</span><span class="o">//</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="n">stage_x</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span> <span class="n">stage_y</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]),</span> <span class="n">fontsize</span><span class="o">=</span><span class="mi">12</span><span class="p">,</span>
                        <span class="n">textcoords</span><span class="o">=</span><span class="sh">"</span><span class="s">offset points</span><span class="sh">"</span><span class="p">,</span> <span class="n">xytext</span><span class="o">=</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="n">ha</span><span class="o">=</span><span class="sh">'</span><span class="s">center</span><span class="sh">'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">red</span><span class="sh">'</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">ax</span><span class="p">.</span><span class="nf">annotate</span><span class="p">(</span><span class="sh">'</span><span class="s">R</span><span class="sh">'</span><span class="p">,</span> <span class="p">(</span><span class="n">stage_x</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span> <span class="n">stage_y</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]),</span> <span class="n">fontsize</span><span class="o">=</span><span class="mi">12</span><span class="p">,</span>
                        <span class="n">textcoords</span><span class="o">=</span><span class="sh">"</span><span class="s">offset points</span><span class="sh">"</span><span class="p">,</span> <span class="n">xytext</span><span class="o">=</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="n">ha</span><span class="o">=</span><span class="sh">'</span><span class="s">center</span><span class="sh">'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="sh">'</span><span class="s">red</span><span class="sh">'</span><span class="p">)</span>

<span class="c1"># plotting settings
</span><span class="n">ax</span><span class="p">.</span><span class="nf">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>

<span class="c1"># adding some ticks and labels
</span><span class="n">current_ticks</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="n">ax</span><span class="p">.</span><span class="nf">get_xticks</span><span class="p">())</span>
<span class="n">current_labels</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="n">ax</span><span class="p">.</span><span class="nf">get_xticklabels</span><span class="p">())</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xticks</span><span class="p">(</span><span class="n">current_ticks</span> <span class="o">+</span> <span class="n">points</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xticklabels</span><span class="p">(</span><span class="n">current_labels</span> <span class="o">+</span> <span class="n">labels</span><span class="p">)</span>

<span class="n">ax</span><span class="p">.</span><span class="nf">legend</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="sh">'</span><span class="s">Operating Lines</span><span class="sh">'</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">facecolor</span><span class="o">=</span><span class="sh">'</span><span class="s">whitesmoke</span><span class="sh">'</span><span class="p">,</span>
          <span class="n">edgecolor</span><span class="o">=</span><span class="sh">'</span><span class="s">black</span><span class="sh">'</span><span class="p">,</span> <span class="n">framealpha</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_xlabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">$x_\text{MeOH}$</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_ylabel</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">$y_\text{MeOH}$</span><span class="sh">'</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="nf">set_title</span><span class="p">(</span><span class="sh">'</span><span class="s">McCabe-Thiele Diagram for Methanol-Water System</span><span class="sh">'</span><span class="p">,</span> <span class="n">fontsize</span><span class="o">=</span><span class="mi">12</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span>
</code></pre></div></div>

<p>The final plot should look like Figure 3 below.</p>

<figure>
  <img src="/assets/posts/mccabe-thiele/final_mccabe_thiele_plot.png" alt="final McCabe-Thiele plot" width="600" />
  <figcaption>Figure 3: McCabe-Thiele plot for methanol-water system with stages labeled.</figcaption>
</figure>

<p>The <a href="/assets/posts/mccabe-thiele/mccabe_thiele.ipynb">notebook</a> and <a href="/assets/posts/mccabe-thiele/methanol_water_vle_data.csv">VLE data</a> behind this post are available for download.</p>]]></content><author><name>Matthew Cox</name><email>mcox340@mit.edu</email></author><category term="separations" /><category term="python" /><summary type="html"><![CDATA[A step-by-step implementation of stage counting for binary distillation in Python]]></summary></entry></feed>