<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://mtmorgan.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mtmorgan.github.io/" rel="alternate" type="text/html" /><updated>2026-02-06T18:10:49+00:00</updated><id>https://mtmorgan.github.io/feed.xml</id><title type="html">Martin Morgan</title><subtitle>Martin Morgan is an accomplished bioinformatics leader with special expertise in R. Martin originally trained as a biologist interested in the evolution of plant reproductive morphology.</subtitle><entry><title type="html">Mushrooms</title><link href="https://mtmorgan.github.io/javascript/2025/10/11/mushrooms.html" rel="alternate" type="text/html" title="Mushrooms" /><published>2025-10-11T00:00:00+00:00</published><updated>2025-10-11T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2025/10/11/mushrooms</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2025/10/11/mushrooms.html"><![CDATA[<p><a href="https://mtmorgan.github.io/shorts/mushrooms">https://mtmorgan.github.io/shorts/mushrooms</a></p>

<p>Mushrooms are pretty amazing. Ancient. Weird. Scary. We walked around
on a couple of days taking pictures of mushrooms. I took the
geographical locations of each photo, and used these to display a
simple scatter plot. Clicking on a point reveals the mushroom at that
location. Taking the pictures was a fun collaborative activity, and
the pictures reveal many weird and wonderful mushrooms.</p>

<p>This project incorporates <a href="https://p5js.org/">p5.js</a> into <a href="https://svelte.dev">svelte</a> using
<a href="https://p5-svelte.netlify.app/">p5-svelte</a>. It uses some things I learned with [Walk in the woods][woods].</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[https://mtmorgan.github.io/shorts/mushrooms]]></summary></entry><entry><title type="html">Tree Bark</title><link href="https://mtmorgan.github.io/javascript/2025/10/11/treebark.html" rel="alternate" type="text/html" title="Tree Bark" /><published>2025-10-11T00:00:00+00:00</published><updated>2025-10-11T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2025/10/11/treebark</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2025/10/11/treebark.html"><![CDATA[<p><a href="https://mtmorgan.github.io/woods/treebark">https://mtmorgan.github.io/woods/treebark</a></p>

<p><a href="/woods/treebark/">Tree Bark</a> provides a bark-centric view of
<a href="https://www.ontario.ca/page/tree-atlas/ontario-southcentral">The Tree Atlas: South Central Region</a> from the Ontario
Ministry of Natural Resources. This is a great way to learn the trees you might
see during <a href="/woods/">A Walk in the Woods</a>.</p>

<p>The project uses JavaScript and local storage to manage clicks on a “That’s my
tree!” button, as well as the CSS ‘flex’ display to easily switch between
mobile and larger device layouts. Google Gemini did much of the initial work.</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[https://mtmorgan.github.io/woods/treebark]]></summary></entry><entry><title type="html">Uncs</title><link href="https://mtmorgan.github.io/javascript/2025/10/02/uncs.html" rel="alternate" type="text/html" title="Uncs" /><published>2025-10-02T00:00:00+00:00</published><updated>2025-10-02T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2025/10/02/uncs</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2025/10/02/uncs.html"><![CDATA[<p><a href="https://mtmorgan.github.io/uncs">https://mtmorgan.github.io/uncs</a></p>

<p>An ‘unc’ is, apparently, a term used by the younger peoples to refer to older
individuals with unappreciated (by the younger peoples) wisdom. This project
looks at our family ancestry using information compiled by other family members.</p>

<p>I learned quite a bit about the <a href="https://svelte.dev">svelte</a> framework, data encryption
using sodium (with <em>R</em>’s <a href="https://jeroen.r-universe.dev/sodium">sodium</a> and JavaScript’s <a href="https://github.com/jedisct1/libsodium.js">libsodium.js</a>),
and the packages <a href="https://datatables.net/">DataTables.js</a>, <a href="https://graphology.github.io/">graphology</a>, and <a href="https://www.sigmajs.org/">Sigma.js</a>.</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[https://mtmorgan.github.io/uncs]]></summary></entry><entry><title type="html">The Movies</title><link href="https://mtmorgan.github.io/javascript/2025/08/24/the-movies.html" rel="alternate" type="text/html" title="The Movies" /><published>2025-08-24T00:00:00+00:00</published><updated>2025-08-24T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2025/08/24/the-movies</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2025/08/24/the-movies.html"><![CDATA[<p><a href="https://mtmorgan.github.io/movies">https://mtmorgan.github.io/movies</a></p>

<p><a href="/movies/">The Movies</a> started because I wanted to explore WASM (web assembly) to run
more typically server-side applications in the client’s browser. An interesting
example is the <a href="https://sqlite.org/wasm/doc/trunk/index.md">SQLite WASM</a> database. The New York Times came out with a list
of <a href="https://www.nytimes.com/interactive/2025/movies/best-movies-21st-century.html">The 100 Best Movies of the 21st Century</a> as chosen by ‘creators’
(producers, directors, actors, etc.). As we started to watch the movies, it
became hard to remember details and even our reaction, and actually the page
provided by the New York Times is relatively hard to navigate (e.g., no simple
way to find the 34th movie, the display jumping around as the page renders,
etc.).</p>

<p>So we start with a simple table, then add links to reviews and where-to-watch.
Then provide information on directors, writers, and actors of each movie from
<a href="[TMDB]: https://www.themoviedb.org/">The Movie Database</a> (TMDB), and finally write our own notes on the movies
that we’ve seen.</p>

<p>It turns out to be a relatively complicated project, and a good way to level up
my JavaScript skills. It has also been a great way to be amazed by the bold new
age of AI-assisted coding.</p>

<!-- prettier-ignore -->]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[https://mtmorgan.github.io/movies]]></summary></entry><entry><title type="html">Day Lilies</title><link href="https://mtmorgan.github.io/javascript/2025/07/20/lilies.html" rel="alternate" type="text/html" title="Day Lilies" /><published>2025-07-20T00:00:00+00:00</published><updated>2025-07-20T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2025/07/20/lilies</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2025/07/20/lilies.html"><![CDATA[<p><a href="https://mtmorgan.github.io/lilies">https://mtmorgan.github.io/lilies</a></p>

<p><a href="/lilies/">Day Lilies</a> is a light-weight example summarizing the
flowering phenology of a small patch of day lilies in our front yard,
using the <a href="https://datatables.net/">DataTables</a> and <a href="https://plotly.com/javascript/">Plotly.js</a> libraries.</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[https://mtmorgan.github.io/lilies]]></summary></entry><entry><title type="html">A Walk in the Woods</title><link href="https://mtmorgan.github.io/javascript/2024/12/11/walk-in-the-woods.html" rel="alternate" type="text/html" title="A Walk in the Woods" /><published>2024-12-11T00:00:00+00:00</published><updated>2024-12-11T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2024/12/11/walk-in-the-woods</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2024/12/11/walk-in-the-woods.html"><![CDATA[<p><a href="https://mtmorgan.github.io/woods">https://mtmorgan.github.io/woods</a></p>

<p><a href="/woods/">A Walk in the Woods</a> continues my JavaScript exploration. It
uses <a href="https://p5js.org">p5</a> to load and display images of tree trunks taken while
while walking through the woods on our propoerty near Caledon East,
Ontario.</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[https://mtmorgan.github.io/woods]]></summary></entry><entry><title type="html">Orbital</title><link href="https://mtmorgan.github.io/javascript/2024/11/24/orbital.html" rel="alternate" type="text/html" title="Orbital" /><published>2024-11-24T00:00:00+00:00</published><updated>2024-11-24T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2024/11/24/orbital</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2024/11/24/orbital.html"><![CDATA[<!-- mathjax, see https://stackoverflow.com/a/11093303/547331 -->
<script id="MathJax-script" async="" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

<p>(updated 2024-12-30)</p>

<p>This continues my exploration of JavaScript.</p>

<h2 id="motivation">Motivation</h2>

<p>Samantha Harvey says her book <em><a href="https://thebookerprizes.com/the-booker-library/books/orbital">Orbital</a></em> tries to be a space
<em>pastoral</em>, describing the relationships of six space station
astronauts during the sixteen orbits of a single earth day. There is
no threatening destruction or steamy romance, just an encounter
between Earth and its Anthropocene exhabitants.</p>

<p>The frontispiece of <a href="https://thebookerprizes.com/the-booker-library/books/orbital">Orbital</a> shows the orbits of the space station
during this day; it is fun to think about orbits. For instance,
daylight is not restricted to the northern hemisphere!</p>

<figure>
    <img alt="Frontispiece, Orbital" src="/assets/orbital/frontispiece.jpeg" />
    <figcaption>
        Frontispiece,
        <a href="https://thebookerprizes.com/the-booker-library/books/orbital">Orbital</a>,
        Samantha Harvey, 2023.
    </figcaption>
</figure>

<p>A <em>circular</em> orbit is a path where an object (e.g., space station)
moves around a central body (e.g., the earth) in a perfect circle. An
<em>equatorial</em> orbit is an orbit that is directly above the equator.  An
<em>inclined</em> orbit is tilted relative to the equator. The space station
has an inclined orbit, where the inclination is 51.6°. This is the
angle that each orbit crosses the equator.</p>

<p>If the earth were stationary, the space station would always traverse
the globe along a single circumference. But the earth rotates, so each
time the space station completes an orbit, its location over the
ground has changed. The amount of change is the amount that the earth
has rotated during the space station’s orbit. This is why the orbits
are offset in the frontispiece above.</p>

<p>The altitude of a satellite orbit occurs when gravitational force
pulling the satellite toward the earth is balanced by the centripetal
force caused by the speed of the satellite in orbit. Since satellite
mass is a linear term in both the gravitational and centripetal
equations, the actual mass of the satellite does not determine
orbit. Geostationary satellites are much further from the earth
(35,800 km) than the space station (in low earth orbit, about 410
km). Satellites in more distance (e.g., geostationary) orbits move
slower than satellites closer to the earth (e.g., the space station or
StarLink communication satellites) because satellites closer to the
earth have to overcome the stronger force of Earth’s gravity.</p>

<p>There are a <em>lot</em> of satellites (and other objects) in space. Here are
the almost 7,000 Starlink satellites.</p>

<figure>
    <img alt="Starlink orbits" src="/assets/orbital/starlink.png" width="50%" />
    <figcaption>
    <em>Starlink</em> orbits, Decemeber 2024, from
    <a href="https://app.keeptrack.space">KeepTrack.space</a>.
    </figcaption>
</figure>

<h2 id="math">Math</h2>

<p>This answer on the Space Exploration <a href="https://space.stackexchange.com/a/43416">StackExchange</a> provides basic
math required. There are three steps.</p>

<p>The first step is to describe movement on a sphere with an inclined orbit.</p>

<div>
\begin{align}
x &amp;= \cos \omega(t) \\
y &amp;= \sin \omega(t) \cos i \\
z &amp;= \sin \omega(t) \sin i
\end{align}
</div>

<p>where the radius of the orbit is 1, <span>\(\omega = 2 \pi /
T\)</span> is the circumference of the sphere scaled by the orbital
period <span>\(T\)</span>, and <span>\(i\)</span> the inclination of
the orbit. <span>\(t\)</span> is the time since the start of the orbit.</p>

<p>The next step is to translate the three-dimensional coordinates to
two-dimensional latitude and longitude. These equations assume that
the orbit starts at longitude 0.</p>

<div>
\begin{align}
lon &amp;= \arctan2(y, x) \\
lat &amp;= \arcsin(x)
\end{align}
</div>

<p>Incorporate the rotation of the earth by subtracting the scaled
orbital period of the earth; only the longitude is influenced by the
rotating earth.</p>

<div>
\begin{equation}
lon = \arctan2(y, x) - \omega_E(t - t_0)
\end{equation}
</div>

<p><span>\(\omega_E = 2 \pi / T_E\)</span> and <span>\(T_E\)</span> is
the orbital period of the earth.</p>

<p>We use minutes as the unit of time. The orbital period of the space
station <span>\(T\)</span>varies between 90 and 93 minutes; we’ll use
92 minutes. The orbital period of the earth <span>\(T_E\)</span> is
approximately 1436 minutes (23 hours 56 minutes and 4 seconds). The
inclination of the space station orbit is approximately 51.6°.</p>

<p>A more realistic calculation might use <a href="https://en.wikipedia.org/wiki/Two-line_element_set">two-line element set</a>
notation to characterize the location and movement of a satellites at
a particular point in time, coupled with <a href="https://en.wikipedia.org/wiki/Simplified_perturbations_models">simplified perturbation
models</a> to calculate orbital state vectors. <a href="https://github.com/shashwatak/satellite-js">satellites-js</a> or
<a href="https://github.com/thkruz/ootk-core">ootk</a> are two JavaScript implementations.</p>

<h2 id="orbital">Orbital</h2>

<p>The first sketch show a flattened earth, with space station orbits
superimposed. The orbits are described by equations for <span>\(lat,
lon\)</span> from the previous section. The orbits appear offset in
space. But actually the orbits are constant, it is the earth that
rotates under the space station.  The space station dots are equally
spaced in time, but a close observation shows that they are further
apart at the largest latitudes; this is because the projection of the
spherical earth into two dimensions stretches larger latitudes more
than smaller latitudes.</p>

<div id="sketch-projection"></div>

<p>The second sketch shows the rotating earth, inclined 23.5°. The
space station orbit is constant, always intersecting the equator in
the middle of the image. The location of the space station is
described the equations for <span>\(x, y, z\)</span> above. The orbit
is inclined 51.6° from the equator. Space station markers move to
the right in synchrony with the rotating earth; it took me a long time
to figure out how to make this simple transformation in p5!. The
earth’s radius is 6378 km, and the orbit is 400 km above the
earth. Illumination is from the front and left, as would occur
somewhere between the spring (June) solstice and summer (March)
equinox; the image of the earth, from <a href="https://visibleearth.nasa.gov/images/73884/november-blue-marble-next-generation-w-topography-and-bathymetry">NASA</a>, is
generated from November data, so is not quite correct.</p>

<div id="sketch-sphere"></div>

<p>An abstraction has the earth’s equator, orbit, and the location of the
visitor’s internet access. The earth is illuminated from the top so
that ‘daylight is in the northern hemisphere’. The space station orbit
pulses at 92 beats per minute. The axial tilt of the earth is a little
akimbo.</p>

<div id="sketch-orbital"></div>
<script type="module" src="/assets/orbital/orbital.js"></script>

<h2 id="notes">Notes</h2>

<p>The implementation uses <a href="https://p5js.org/">p5</a>; here’s the <a href="https://github.com/mtmorgan/mtmorgan.github.io/blob/main/assets/orbital/orbital.js">JavaScript</a>. I use
‘WEBGL’ mode for 3D rendering. A difference between WEBGL and P2D
rendering is the the WEBGL coordinate system has the center of the
canvas as the origin, versus the top left under P2D. Also objects in
WEBGL are are always centered at 0; locations in the canvas are
determined using operations such as <code class="language-plaintext highlighter-rouge">translate()</code> and <code class="language-plaintext highlighter-rouge">rotateY()</code> to
adjust the relative coordinate system before drawing the
object. <code class="language-plaintext highlighter-rouge">push()</code> and <code class="language-plaintext highlighter-rouge">pop()</code> are used to limit the effects of
<code class="language-plaintext highlighter-rouge">translate()</code> etc., to sepcific shapes.</p>

<p>This post uses MathJax for rendering mathematical equations; see this
helpful <a href="https://stackoverflow.com/a/11093303/547331">StackOverflow</a> post. I used Rodriques’
rotation formula from this <a href="https://stackoverflow.com/a/67468546/547331">StackOverflow</a>
answer to rotate the light source around the Earth.</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Horizon</title><link href="https://mtmorgan.github.io/javascript/2024/11/14/agnes-martin.html" rel="alternate" type="text/html" title="Horizon" /><published>2024-11-14T00:00:00+00:00</published><updated>2024-11-14T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/2024/11/14/agnes-martin</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/2024/11/14/agnes-martin.html"><![CDATA[<p>This continues my exploration of JavaScript.</p>

<h2 id="agnes-martin">Agnes Martin</h2>

<p>I respond to the horizon and vertical structure in Martin’s work. I
interpret the horizon as prarie, and the weft and warp starting with
Martin’s relationship with <a href="https://lenoretawney.org/">Lenore Tawney</a>. Martin’s work is subtle
and poorly captured on the internet. Here is ‘<a href="https://buffaloakg.org/artworks/k19762-tree">The Tree</a> (1965)’
from the Buffalo AKG.</p>

<p><a href="https://buffaloakg.org/artworks/k19762-tree"><img src="https://buffaloakg.org/sites/default/files/styles/fixed_height_medium/public/artwork/K1976_002_o2.jpg" alt="image" /></a></p>

<p>That gray canvas is penciled lines bouncing over a textured
background. Here’s a close-up (trigger warning: please move away from
the art; also, do not lick the art).</p>

<p><img src="/assets/agnes-martin/the-tree-1965-close.jpeg" alt="image" /></p>

<p>I like how this is so structured, but not perfect or
mechanical. Textures bump the line away from straight. Lines end but
not at the canvas. Etc. It is very hard to reconcile the color of the
AKG and iPhone images, and my own direct experience (dirty [with age
or work] ‘white’).</p>

<h2 id="horizon">Horizon</h2>

<p>This first iteration aims to reproduce the basic structure of the
art. I hope to explore texture and more subtle line drawing in a
subsequent post.</p>

<p>I imagine that the lines are drawn as warp and then weft. The practice
is contemplative, so the lines are drawn slowly.</p>

<div id="sketch-agnes-martin"></div>
<script type="module" src="/assets/agnes-martin/agnes-martin.js"></script>

<h2 id="notes">Notes</h2>

<p>The implementation uses <a href="https://p5js.org/">p5</a>. I explore JavaScript classes (<code class="language-plaintext highlighter-rouge">Line</code>
and subclasses <code class="language-plaintext highlighter-rouge">VerticalLine</code>, <code class="language-plaintext highlighter-rouge">HorizontalLine</code>; here’s the
<a href="https://github.com/mtmorgan/mtmorgan.github.io/blob/main/assets/agnes-martin/agnes-martin.js">JavaScript</a>) as well as different ways to represent color. I’m using
‘HSB’ here, where the ‘H’ (hue) is easily interpreted as location on
a color wheel.</p>]]></content><author><name></name></author><category term="javascript" /><summary type="html"><![CDATA[This continues my exploration of JavaScript.]]></summary></entry><entry><title type="html">Bubbles</title><link href="https://mtmorgan.github.io/javascript/population-genetics/2024/10/29/boogie-woogie-bubble.html" rel="alternate" type="text/html" title="Bubbles" /><published>2024-10-29T00:00:00+00:00</published><updated>2024-10-29T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/population-genetics/2024/10/29/boogie-woogie-bubble</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/population-genetics/2024/10/29/boogie-woogie-bubble.html"><![CDATA[<p>(modified 2024-10-30, 2024-11-18, 2024-12-10)</p>

<p>The Buffalo AKG <a href="https://buffaloakg.org/art/exhibitions/electric-op">Electric Op</a> exhibit reminded me of an <a href="/javascript/population-genetics/2024/10/28/boogie-woogie.html">old
folly</a>, and this is a second iteration. Briefly, I am using a simple
population genetics model of genetic drift with infinite alleles as an
excuse to learn a bit more JavaScript, including the <a href="https://p5js.org/">p5</a> library.</p>

<h2 id="bubbles">Bubbles</h2>

<p>The previous iteration used an individual-based simulation to follow a
population of individuals over time. The innovation here is to follow
the small number of segregating alleles, rather than the 1000’s of
individuals in the population. The simulation is both smaller and
faster, so more realistic population sizes can be used. The simulation
may still have some artistic merit…</p>

<div id="sketch-boogie-bubble"></div>
<script src="/assets/p5/libraries/p5.min.js"></script>

<script type="module" src="/assets//boogie-woogie/bubble.js"></script>

<p>The population size N is 2-10 times larger (depending on the width of
the display, as a proxy for processor speed), and the mutation rate
μ 10 times smaller, than in the individual-based simulation. The
number of generations per frame is increased four-fold to 200, and the
frame rate doubled to 24 (200 x 24 = 4800 generations) per second
(available CPU may limit the rate of display; this animation is slow
on mobile devices).  As before, ‘Segregating’ alleles are just the
number of alleles in the population at each generation. ‘Replacements’
summarize how many times a common allele has been replaced by a new
allele.</p>

<h2 id="notes-on-representation">Notes on representation</h2>

<p>Although the figure is ‘mathematical’ and in that sense contrasts with
Mondrian’s carefully composed paintings, it is useful to reflect on
decisions made during development.</p>

<p>The bubble chart representation is much less frenetic than the grid
used in the individual-based simulation (I could have summarized the
individual-based simulations using bubble charts, but then the
connection to Mondrian would be even less clear).</p>

<p>Originally I set the maximum bubble diameter to 1/2 the minimum width
or height of the canvas. This meant that new alleles were centered in
a two-dimensional square on the canvas. The simulation above sets the
maximum diameter to the minimum width or height, so when only a single
allele is present its bubble occupies the entire width or height of
the canvas. A corollary is that new alleles are constrained to a
vertical (if the width of the canvas is smaller than the height, as on
a mobile device) or horizontal (width larger than height, as in a
browser) line. This further simplifies the bubble chart dynamics, with
the eye needing to cope with fewer changes across frames.</p>

<p>The background color was originally white, but switching to black is
easier on the eyes and seems to better contrast, in general, with the
randomly chosen allele colors.</p>

<p>The alleles were originally drawn without an explicit stroke for the
circumference. Drawing the circumference provides a more defined shape
for the eye to perceive. This is particularly important with partially
transparent bubbles, and transparent bubbles are needed to visualize
overlapping alleles.</p>

<h2 id="implementation-notes">Implementation notes</h2>

<p>In addition to <a href="https://p5js.org/">p5</a>, I use <code class="language-plaintext highlighter-rouge">binomial()</code> from <a href="https://stdlib.io/">stdlib</a>.  Here’s the
Boogie Woogie bubble <a href="https://github.com/mtmorgan/mtmorgan.github.io/blob/main/assets/boogie-woogie/bubble.js">JavaScript</a>.</p>

<p>The script is written using p5’s ‘instance’ mode, and as a JavaScript
module. Using instance mode and modules loads only p5 variables into
the global namespace, not stdlib symbols or symbols used in the Boogie
Woogie script. Instance mode involves writing a closure (function)
that is passed to the <code class="language-plaintext highlighter-rouge">p5()</code> constructor. Simulation parameters and
functions are defined (currently) in the closure rather than at the
level of the module, resulting in better encapsulation. The stdlib
symbol <code class="language-plaintext highlighter-rouge">binomial</code> is <code class="language-plaintext highlighter-rouge">import</code>ed into the module, more closely coupling
the import to its use. Modules also allow more careful validation,
flagging a couple of instances where variables were used without <code class="language-plaintext highlighter-rouge">let</code>
or <code class="language-plaintext highlighter-rouge">const</code> declarations. Using p5 instances also allows for more than
one canvas on a page.</p>]]></content><author><name></name></author><category term="javascript" /><category term="population-genetics" /><summary type="html"><![CDATA[(modified 2024-10-30, 2024-11-18, 2024-12-10)]]></summary></entry><entry><title type="html">Boogie Woogie</title><link href="https://mtmorgan.github.io/javascript/population-genetics/2024/10/28/boogie-woogie.html" rel="alternate" type="text/html" title="Boogie Woogie" /><published>2024-10-28T00:00:00+00:00</published><updated>2024-10-28T00:00:00+00:00</updated><id>https://mtmorgan.github.io/javascript/population-genetics/2024/10/28/boogie-woogie</id><content type="html" xml:base="https://mtmorgan.github.io/javascript/population-genetics/2024/10/28/boogie-woogie.html"><![CDATA[<p>(updated 2024-11-14; 2024-11-18)</p>

<p>The Buffalo AKG <a href="https://buffaloakg.org/art/exhibitions/electric-op">Electric Op</a> exhibit reminded me of an old folly
(see also MoMA’s Rafaël Rozendaal <a href="https://www.moma.org/calendar/exhibitions/5774">Light</a>).</p>

<h2 id="piet-mondrian">Piet Mondrian</h2>

<p>A <a href="https://www.moma.org/calendar/exhibitions/470">Piet Mondrian exhibit</a> at MoMA or the National Gallery in
1994-1995 helped me to understand a little bit about modern art;
there’s a <a href="https://assets.moma.org/documents/moma_catalogue_470_300063147.pdf">catalog</a> available. The exhibit was arranged
chronologically, so one could see Mondrian start with pictorial
representations (e.g., <em>The Weavers’ House, Winterswijk</em>, 1899; p. 96
of the catalog), through impressionist (<em>Mollen; Mill in Sunlight</em>,
1908, p. 106) and cubist (<em>Still Life with Gingerpot II</em>, 1912,
p. 130; <em>Tableau No. 2; Composition No. VII</em>, 1913, p. 146) renderings
before landing on the geometrical representations (<em>Composition A;
Composition with Black, Red, Gray, Yellow, and Blue</em>, 1920, p. 197)
that define most of the last 20 years of Mondrian’s life. One of the
last works in the exhibit was <em>Broadway Boogie Woogie</em> (1942-1943,
p. 297) where Mondrian seems to relax his tight structure to introduce
an almost dynamic and playful component; apparently the image is
inspired by traffic and lights on Broadway in New York City, enlivened
by the music of the blues.</p>

<figure>
<a title="Piet Mondrian, Public domain, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Piet_Mondrian,_1942_-_Broadway_Boogie_Woogie.jpg"><img width="512" alt="Piet Mondrian, 1942 - Broadway Boogie Woogie" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Piet_Mondrian%2C_1942_-_Broadway_Boogie_Woogie.jpg/512px-Piet_Mondrian%2C_1942_-_Broadway_Boogie_Woogie.jpg?20160102143308" /></a>
<figcaption>
Piet Mondrian, Broadway Boogie Woogie, 1942-1943.<br />
Retrieved from Wikimedia Commons, 28 October, 2024.
</figcaption>
</figure>

<p>The main theme I took from the exhibit was Mondrian’s desire to
identify universal values that transcend reality. Thus simplifying
representation to primary colors and geometric shapes, and then to
assemble these colors and shapes into aesthetic meaning.</p>

<h2 id="population-genetics">Population Genetics</h2>

<p>Simplified representations are often used in mathematical models, and
in particular in the ‘infinite alleles’ model describing genetic drift
in population genetics. The infinite alleles model imagines a
population of individuals, represented by the alleles at a particular
genetic locus.  Alleles experience mutation to a novel form. The fate
of the allele (whether and how quickly it is lost from the population,
for instance) is determined by purely stochastic processes.</p>

<p>There is a kind of dynamic equilibrium between mutation and drift.
Often a single allele dominates, with a small number of recently
introduced mutations at low frequency. Sometimes the dominant allele
is replaced by a new allele. I imagined representing a population by a
grid of squares, each square colored to indicate the allele. Genetic
drift is visualized by updating the grid to reflect new mutation and
sampling between generations. The dynamics of new alleles reminded me
of flickering lights, and of Mondrian’s final paintings.</p>

<p>I explored simulations of genetic drift while teaching in the 90’s,
and eventually included the art history and simulation in a single
memorable (for me, anyway) lecture in a graduate Population Genetics
course at Washington State University.</p>

<h2 id="boogie-woogie">Boogie Woogie</h2>

<p>It’s easy to simulate the infinite alleles model (literally two lines
of <em>R</em> code, for instance), making it a fun use case for exploring new
programming languages.</p>

<p>Several of the <a href="https://buffaloakg.org/art/exhibitions/electric-op">Electric Op</a> works used the ‘Processing’ programming
language for computer-based visualization. A modern implementation is
in the <a href="https://p5js.org/">p5</a> javascript library. A perfect way for me to learn a bit
more javascript (my use of p5 is very rudimentary)! Here is the
result:</p>

<div class="p5-boogie-woogie-canvas"></div>
<script src="/assets/stdlib-js/random-base-binomial.js"></script>

<script src="/assets/stdlib-js/random-sample.js"></script>

<script src="/assets/p5/libraries/p5.min.js"></script>

<script src="/assets/boogie-woogie/boogie-woogie.js"></script>

<p>The population is represented by a 71 x 71 grid of alleles, so 5041
haploid ‘individuals’ (I started with a rectangle of 5000 individuals,
but then adjusted to match the square format of Mondrian’s
work). Initially all alleles are the same (random) color. Each
generation introduces new mutations (new colors) at rate μ, and
then sampling with replacement the entire population. The display is
updated every 50 generations, at a maximum rate of 12 frames (50 x 12
= 600 generations) per second. Progress is reported in number of
generations scaled by population size (e.g., t / N = 1 indicates 5000
generations). ‘Segregating’ alleles are just the number of alleles in
the population at each generation. ‘Replacements’ summarize how many
times a common allele has been replaced by a new allele.</p>

<p>There is a lot of activity in the display. New alleles flicker on and
off fairly rapidly, perhaps existing for only a few frames. The
display becomes quite animated when a couple of alleles become more
equally frequent. But replacements are pretty rare, maybe once every
10 time units, and with a lot of variability. It’s tempting to feel
that a new mutation that has become frequent will ‘win’, but actually
the chance of winning is just the frequency of the allele in the
population, independent of whether the allele has recently increased
in frequency or is new, etc. Hopefully this provides some
entertainment and maybe a bit of education.</p>

<h2 id="notes">Notes</h2>

<p>See the companion <a href="/javascript/population-genetics/2024/10/29/boogie-woogie-bubble.html">Bubbles</a> post.</p>

<p>In addition to <a href="https://p5js.org/">p5</a>, I use the <a href="https://stdlib.io/">stdlib</a> javascript library (for
binomial random deviates, and to sample the population).  I also
needed to learn how to integrate a p5 canvas into the jekyll static
site generator (adding an ‘assets’ folder to the root of
the site with javascript scripts and libraries, and inserting
<code class="language-plaintext highlighter-rouge">&lt;script&gt;</code> and <code class="language-plaintext highlighter-rouge">&lt;div&gt;</code> tags into the markdown for this page). Here’s
the Boogie Woogie <a href="https://github.com/mtmorgan/mtmorgan.github.io/blob/main/assets/boogie-woogie/boogie-woogie.js">JavaScript</a>.</p>

<p>Population genetics and WSU remind me of Richard Gomulkiewicz, to whom
I dedicate this post.</p>]]></content><author><name></name></author><category term="javascript" /><category term="population-genetics" /><summary type="html"><![CDATA[(updated 2024-11-14; 2024-11-18)]]></summary></entry></feed>