home

Isotherms

This image visualizes the behavior of gas isotherms (curves showing pressure-volume relationships at constant temperature), represented by three equations of state, as a function of volume. The equations include the ideal gas law, and two other modified laws accounting for molecular interactions. The x-axis represents the molar volume and the y-axis represents the pressure of the gas.


Isotherms

Download

PNG PDF SVG

Code

isotherms.typ (66 lines)

#import "@preview/cetz:0.5.2": canvas, draw
#import "@preview/cetz-plot:0.1.4": plot

#set page(width: auto, height: auto, margin: 8pt, fill: none)
#set text(size: 12pt)

#let gas-constant = 8.31 // Gas constant
#let temperature = 300 // Temperature
#let B1 = 1000 // First virial coefficient
#let B2 = -1000 // Second virial coefficient

// Pressure functions
#let p0(v) = gas-constant * temperature / v
#let p1(v) = p0(v) + B1 / calc.pow(v, 2)
#let p2(v) = p1(v) + B2 / calc.pow(v, 3)

#canvas({
  let axis-mark = (end: "stealth", fill: black)
  draw.set-style(axes: (
    x: (mark: axis-mark, label: (anchor: "south-east", offset: -0.25)),
    y: (mark: axis-mark, label: (anchor: "north-west", offset: -0.2)),
  ))

  plot.plot(
    size: (8, 7),
    x-label: [$v$ (m³/mol)],
    y-label: [$p$ (Pa)],
    x-min: 0.5,
    x-max: 5.5,
    x-tick-step: 1,
    y-tick-step: 1000,
    axis-style: "left",
    legend: "inner-north-east",
    // Compact legend with a thin border.
    legend-style: (fill: rgb("#cdd3da"), item: (spacing: 0.15), padding: 0.15, stroke: 0.5pt),
    {
      // Plot p0 (ideal gas)
      plot.add(
        style: (stroke: rgb("#0B5FA5") + 1.5pt),
        domain: (0.5, 5.5),
        samples: 100,
        p0,
        label: $p_0 = R T \/ v$,
      )

      // Plot p1 (first virial correction)
      plot.add(
        style: (stroke: rgb("#C2570A") + 1.5pt),
        domain: (0.5, 5.5),
        samples: 100,
        p1,
        label: $p_1 = p_0 + B_1 \/ v^2$,
      )

      // Plot p2 (second virial correction)
      plot.add(
        style: (stroke: rgb("#12793F") + 1.5pt),
        domain: (0.5, 5.5),
        samples: 100,
        p2,
        label: $p_2 = p_1 + B_2 \/ v^3$,
      )
    },
  )
})