Skip to content

Instantly share code, notes, and snippets.

@kenwebb
Created August 8, 2025 20:45
Show Gist options
  • Save kenwebb/7c98bbda3541598f5aca9c128f856689 to your computer and use it in GitHub Desktop.
Save kenwebb/7c98bbda3541598f5aca9c128f856689 to your computer and use it in GitHub Desktop.
Decision Trees
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Fri Aug 08 2025 16:44:41 GMT-0400 (Eastern Daylight Time)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: Decision Trees
Description:
Url: http://www.primordion.com/Xholon/gwt/
InternalName:
Keywords:
My Notes
--------
2025 August 8
### References
(1) https://en.wikipedia.org/wiki/Decision_tree
A decision tree is a decision support recursive partitioning structure that uses a tree-like model of decisions and their possible consequences,
including chance event outcomes, resource costs, and utility.
It is one way to display an algorithm that only contains conditional control statements.
Decision trees are commonly used in operations research, specifically in decision analysis,
to help identify a strategy most likely to reach a goal,
but are also a popular tool in machine learning.
A decision tree is a flowchart-like structure in which each internal node represents a test on an attribute (e.g. whether a coin flip comes up heads or tails),
each branch represents the outcome of the test,
and each leaf node represents a class label (decision taken after computing all attributes).
The paths from root to leaf represent classification rules.
In decision analysis, a decision tree and the closely related influence diagram are used as a visual and analytical decision support tool,
where the expected values (or expected utility) of competing alternatives are calculated.
A decision tree consists of three types of nodes:
Decision nodes – typically represented by squares
Chance nodes – typically represented by circles
End nodes – typically represented by triangles
Decision trees are commonly used in operations research and operations management.
If, in practice, decisions have to be taken online with no recall under incomplete knowledge,
a decision tree should be paralleled by a probability model as a best choice model or online selection model algorithm.
Another use of decision trees is as a descriptive means for calculating conditional probabilities.
(2) AI
(3) https://github.com/ts-graphviz/ts-graphviz
(4) https://ts-graphviz.github.io
https://ts-graphviz.github.io/ts-graphviz/
https://ts-graphviz.github.io/docs/ts-graphviz/guides/using-ast
My JS code should be able to readily walk through the generatted AST, to convert it into Xholon XML format.
]]></Notes>
<markdown><![CDATA[
AI
% ollama run llama3
>>> Create an example of a decision tree.
Here is an example of a decision tree:
**Decision Tree Example: Predicting Whether a Customer Will Buy a Product**
The goal of this decision tree is to predict whether a customer will buy a product based on their demographic information and purchase history.
**Root Node:** Is the customer's age 25 or older?
* **Yes**: Go to the next node
* **No**: Customer is unlikely to buy (Prediction: No)
**Next Node:** Has the customer made a purchase in the past year?
* **Yes**: Go to the next node
* **No**: Customer has not purchased recently, so they are unlikely to buy (Prediction: No)
**Next Node:** Does the customer have a higher income ($50,000 or more)?
* **Yes**: Go to the next node
* **No**: Customer's lower income makes it less likely they will buy (Prediction: No)
**Next Node:** Is the product a luxury item?
* **Yes**: Customer with high income and interest in luxury items is very likely to buy (Prediction: Yes)
* **No**: If customer has low income or no interest in luxury items, they are unlikely to buy (Prediction: No)
This decision tree uses a combination of demographic information (age, income) and purchase history (whether the customer has made a purchase recently) to predict whether a
customer will buy a product. The tree starts at the root node and branches out based on the answers to each question until it reaches a leaf node with a prediction.
Note that this is just one example of how a decision tree can be used, and the specific nodes and outcomes may vary depending on the problem being solved!
>>> What structured format can I use to display this decision tree?
There are several structured formats you can use to display a decision tree. Here are a few popular ones:
1. **ASCII Art**: This is a simple, text-based representation of the decision tree using characters like `/`, `\`, and `|` to create a tree-like structure.
```plain
+---------------+
| Is age 25+? |
+---------------+
|
| Yes
v
+---------------+ +---------------+
| Has purchased | | No purchase |
| in past year?| +---------------+
+---------------+ |
| |
| Yes | Customer unlikely
v | to buy (Prediction: No)
+-----------------+ +-----------------+
| Income > $50k? | | No purchase, low |
| | | income (Prediction: No)|
+-----------------+ |
| |
| Yes | Customer likely to
v | buy (Prediction: Yes)
+---------------+
| Luxury item? |
+---------------+
| Yes | No
| Very likely | Unlikely
+---------------+-----------------+
```
2. **Graphviz**: This is a powerful tool for creating visualizations of graphs and trees. You can use Graphviz to create a decision tree diagram that looks like this:
```graphviz
digraph decision_tree {
node[shape=box, style=filled];
"Is age 25+?" [label="Is age 25+?", shape=box];
"Has purchased in past year?" [label="Has purchased in past year?", shape=box];
"Income > $50k?" [label="Income > $50k?", shape=box];
"Luxury item?" [label="Luxury item?", shape=box];
"Is age 25+?" -> "Yes" [label="Yes"];
"Is age 25+?" -> "No" [label="No"];
"Yes" -> "Has purchased in past year?" [label="Yes"];
"Yes" -> "Income > $50k?" [label="Yes"];
"Has purchased in past year?" -> "Yes" [label="Yes"];
"Has purchased in past year?" -> "No" [label="No"];
"Income > $50k?" -> "Yes" [label="Yes"];
"Income > $50k?" -> "No" [label="No"];
"Luxury item?" -> "Yes" [label="Very likely"];
"Luxury item?" -> "No" [label="Unlikely"];
node[shape=box, style=filled];
}
```
This code generates a PNG image of the decision tree. You can customize the appearance of the diagram by using various options and settings.
3. **HTML/CSS**: You can also use HTML and CSS to create an interactive decision tree that users can navigate through. For example:
```html
<div class="decision-tree">
<h2>Decision Tree</h2>
<ul>
<li><a href="#yes" data-next-node="Has purchased in past year?">Is age 25+?</a></li>
<li><a href="#no" data-next-node="Customer unlikely to buy (Prediction: No)">No</a></li>
</ul>
<div id="yes">
<h2>Yes</h2>
<ul>
<li><a href="#has-purchased" data-next-node="Income > $50k?">Has purchased in past year?</a></li>
<li><a href="#no-income" data-next-node="Customer unlikely to buy (Prediction: No)">No purchase, low income (Prediction: No)</a></li>
</ul>
</div>
<!-- ... -->
</div>
```
In this example, the HTML code creates a nested list structure that represents the decision tree. The CSS styles the list items and adds visual effects to make it more
interactive.
These are just a few examples of structured formats you can use to display a decision tree. You can choose the format that best suits your needs and preferences!
>>> Create a decision tree in graphviz dot format, representing the path of a photon as it passes through the atmosphere from the upper atmosphere to the surface or back out to space or some other outcome.
Here is a decision tree in Graphviz Dot format that represents the path of a photon as it passes through the atmosphere:
```dot
digraph photon_path {
node[shape=box, style=filled];
start[label="Upper Atmosphere"];
scatter[label="Scattered by Air Molecules"];
absorb[label="Absorbed by Ozone Layer"];
transmit[label="Transmitted through Clear Sky"];
cloud[label="Encountered Cloud"];
reflected[label="Reflected by Water Droplets"];
absorbed_cloud[label="Absorbed by Clouds"];
surface[label="Reached Surface"];
backscatter[label="Backscattered by Atmosphere"];
space[label="Escaped to Space"];
start -> scatter [label="Initially Traveling Through"];
scatter -> transmit [label="Scattered"];
transmit -> cloud [label="Encountered Cloud"];
cloud -> reflected [label="Reflected"];
reflected -> surface [label="Reached Surface"];
surface -> backscatter [label="Backscattered by Surface"];
backscatter -> space [label="Escaped to Space"];
start -> absorb [label="Absorbed by Ozone Layer"];
absorb -> end[label="Absorbed by Atmosphere"];
transmit -> absorb [label="Absorbed by Ozone Layer"];
cloud -> absorbed_cloud [label="Absorbed by Clouds"];
reflected -> absorbed_cloud [label="Absorbed by Clouds"];
node[shape=box, style=filled];
}
```
Here's a brief explanation of the nodes and edges:
* `start`: The photon starts its journey in the upper atmosphere.
* `scatter`: The photon is scattered by air molecules, changing direction.
* `absorb`: The photon is absorbed by the ozone layer.
* `transmit`: The photon travels through clear sky without being absorbed or scattered.
* `cloud`: The photon encounters a cloud.
* `reflected`: The photon is reflected by water droplets in the cloud.
* `surface`: The photon reaches the surface of the Earth.
* `backscatter`: The photon is backscattered by the atmosphere, possibly due to interactions with aerosols or clouds.
* `space`: The photon escapes into space.
The edges represent the possible paths a photon can take as it passes through the atmosphere. For example:
* A photon that starts in the upper atmosphere may be scattered and continue traveling through clear sky (transmit).
* If the photon encounters a cloud, it may be reflected or absorbed by the cloud particles.
* If the photon reaches the surface, it may be backscattered by the atmosphere or absorbed by the surface.
Note that this is a simplified model and there are many factors that can affect the path of a photon as it passes through the atmosphere.
>>> Add probabilities for each arrow.
Here is the updated decision tree with probabilities added to each arrow:
```dot
digraph photon_path {
node[shape=box, style=filled];
start[label="Upper Atmosphere"];
scatter[label="Scattered by Air Molecules"];
absorb[label="Absorbed by Ozone Layer"];
transmit[label="Transmitted through Clear Sky"];
cloud[label="Encountered Cloud"];
reflected[label="Reflected by Water Droplets"];
absorbed_cloud[label="Absorbed by Clouds"];
surface[label="Reached Surface"];
backscatter[label="Backscattered by Atmosphere"];
space[label="Escaped to Space"];
start -> scatter [label="Initially Traveling Through", labeldistance=1.5, weight=0.7];
scatter -> transmit [label="Scattered", labeldistance=1.2, weight=0.8];
transmit -> cloud [label="Encountered Cloud", labeldistance=1.4, weight=0.3];
cloud -> reflected [label="Reflected", labeldistance=1.3, weight=0.6];
reflected -> surface [label="Reached Surface", labeldistance=1.2, weight=0.8];
surface -> backscatter [label="Backscattered by Surface", labeldistance=1.4, weight=0.7];
backscatter -> space [label="Escaped to Space", labeldistance=1.5, weight=0.9];
start -> absorb [label="Absorbed by Ozone Layer", labeldistance=1.6, weight=0.2];
absorb -> end[label="Absorbed by Atmosphere", labeldistance=1.7, weight=1.0];
transmit -> absorb [label="Absorbed by Ozone Layer", labeldistance=1.8, weight=0.1];
cloud -> absorbed_cloud [label="Absorbed by Clouds", labeldistance=1.5, weight=0.4];
reflected -> absorbed_cloud [label="Absorbed by Clouds", labeldistance=1.3, weight=0.3];
node[shape=box, style=filled];
}
```
In this updated decision tree, each arrow has a probability value associated with it, represented by the `weight` attribute. The weights are numbers between 0 and 1 that indicate
the likelihood of transitioning from one state to another.
Here's a brief explanation of the probabilities:
* The photon initially traveling through the upper atmosphere (start -> scatter) has a 70% chance of being scattered.
* After scattering, the photon has an 80% chance of being transmitted through clear sky.
* When encountering a cloud, the photon has a 30% chance of being reflected and a 60% chance of being absorbed by the clouds.
* The surface has a 7% chance of backscattering the photon, which then escapes to space with a 9% chance.
Note that these probabilities are simplifications and might not reflect the actual values in real-world atmospheric conditions.
KSW what it says about "weight" is incorrect, but it may be correctly using it to represent probabilities ?
>>> Write this out as JSON instead of graphviz.
Here is the decision tree represented as JSON:
```
{
"nodes": [
{
"name": "start",
"label": "Upper Atmosphere"
},
{
"name": "scatter",
"label": "Scattered by Air Molecules"
},
{
"name": "absorb",
"label": "Absorbed by Ozone Layer"
},
{
"name": "transmit",
"label": "Transmitted through Clear Sky"
},
{
"name": "cloud",
"label": "Encountered Cloud"
},
{
"name": "reflected",
"label": "Reflected by Water Droplets"
},
{
"name": "absorbed_cloud",
"label": "Absorbed by Clouds"
},
{
"name": "surface",
"label": "Reached Surface"
},
{
"name": "backscatter",
"label": "Backscattered by Atmosphere"
},
{
"name": "space",
"label": "Escaped to Space"
}
],
"edges": [
{
"from": "start",
"to": "scatter",
"probability": 0.7
},
{
"from": "scatter",
"to": "transmit",
"probability": 0.8
},
{
"from": "transmit",
"to": "cloud",
"probability": 0.3
},
{
"from": "cloud",
"to": "reflected",
"probability": 0.6
},
{
"from": "reflected",
"to": "surface",
"probability": 0.8
},
{
"from": "surface",
"to": "backscatter",
"probability": 0.7
},
{
"from": "backscatter",
"to": "space",
"probability": 0.9
},
{
"from": "start",
"to": "absorb",
"probability": 0.2
},
{
"from": "transmit",
"to": "absorb",
"probability": 0.1
},
{
"from": "cloud",
"to": "absorbed_cloud",
"probability": 0.4
},
{
"from": "reflected",
"to": "absorbed_cloud",
"probability": 0.3
}
]
}
```
In this JSON representation, each node is represented as an object with a `name` and `label` property. The edges are represented as objects with `from`, `to`, and `probability`
properties.
Note that you can use libraries like `json` or `JSON.stringify()` to convert the JSON string back into a JavaScript object, if needed.
>>> Include the label in each edge.
Here is the updated JSON representation with the label included in each edge:
```
{
"nodes": [
{
"name": "start",
"label": "Upper Atmosphere"
},
{
"name": "scatter",
"label": "Scattered by Air Molecules"
},
{
"name": "absorb",
"label": "Absorbed by Ozone Layer"
},
{
"name": "transmit",
"label": "Transmitted through Clear Sky"
},
{
"name": "cloud",
"label": "Encountered Cloud"
},
{
"name": "reflected",
"label": "Reflected by Water Droplets"
},
{
"name": "absorbed_cloud",
"label": "Absorbed by Clouds"
},
{
"name": "surface",
"label": "Reached Surface"
},
{
"name": "backscatter",
"label": "Backscattered by Atmosphere"
},
{
"name": "space",
"label": "Escaped to Space"
}
],
"edges": [
{
"from": "start",
"to": "scatter",
"label": "Initially Traveling Through",
"probability": 0.7
},
{
"from": "scatter",
"to": "transmit",
"label": "Scattered",
"probability": 0.8
},
{
"from": "transmit",
"to": "cloud",
"label": "Encountered Cloud",
"probability": 0.3
},
{
"from": "cloud",
"to": "reflected",
"label": "Reflected",
"probability": 0.6
},
{
"from": "reflected",
"to": "surface",
"label": "Reached Surface",
"probability": 0.8
},
{
"from": "surface",
"to": "backscatter",
"label": "Backscattered by Surface",
"probability": 0.7
},
{
"from": "backscatter",
"to": "space",
"label": "Escaped to Space",
"probability": 0.9
},
{
"from": "start",
"to": "absorb",
"label": "Absorbed by Ozone Layer",
"probability": 0.2
},
{
"from": "transmit",
"to": "absorb",
"label": "Absorbed by Ozone Layer",
"probability": 0.1
},
{
"from": "cloud",
"to": "absorbed_cloud",
"label": "Absorbed by Clouds",
"probability": 0.4
},
{
"from": "reflected",
"to": "absorbed_cloud",
"label": "Absorbed by Clouds",
"probability": 0.3
}
]
}
```
Now each edge has a `label` property that includes the text label for the edge, in addition to the `from`, `to`, and `probability` properties.
]]></markdown>
<_-.XholonClass>
<!-- domain objects -->
<PhysicalSystem/>
<Block/>
<Brick/>
<!-- quantities -->
<Height superClass="Quantity"/>
</_-.XholonClass>
<xholonClassDetails>
<Block>
<port name="height" connector="Height"/>
</Block>
</xholonClassDetails>
<PhysicalSystem>
<Block>
<Height>0.1 m</Height>
</Block>
<Brick multiplicity="2"/>
</PhysicalSystem>
<Blockbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var a = 123;
var b = 456;
var c = a * b;
if (console) {
console.log(c);
}
//# sourceURL=Blockbehavior.js
]]></Blockbehavior>
<Heightbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var myHeight, testing;
var beh = {
postConfigure: function() {
testing = Math.floor(Math.random() * 10);
myHeight = this.cnode.parent();
},
act: function() {
myHeight.println(this.toString());
},
toString: function() {
return "testing:" + testing;
}
}
//# sourceURL=Heightbehavior.js
]]></Heightbehavior>
<Brickbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
$wnd.xh.Brickbehavior = function Brickbehavior() {}
$wnd.xh.Brickbehavior.prototype.postConfigure = function() {
this.brick = this.cnode.parent();
this.iam = " red brick";
};
$wnd.xh.Brickbehavior.prototype.act = function() {
this.brick.println("I am a" + this.iam);
};
//# sourceURL=Brickbehavior.js
]]></Brickbehavior>
<Brickbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
console.log("I'm another brick behavior");
]]></Brickbehavior>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Block</title>
<rect id="PhysicalSystem/Block" fill="#98FB98" height="50" width="50" x="25" y="0"/>
<g>
<title>Height</title>
<rect id="PhysicalSystem/Block/Height" fill="#6AB06A" height="50" width="10" x="80" y="0"/>
</g>
</g>
</svg>
<svg width="959pt" height="653pt"
viewBox="0.00 0.00 958.50 653.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 649)">
<title>photon_path</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-649 954.5,-649 954.5,4 -4,4"/>
<!-- start -->
<g id="node1" class="node">
<title>start</title>
<polygon fill="lightgrey" stroke="black" points="717.5,-645 565.5,-645 565.5,-609 717.5,-609 717.5,-645"/>
<text text-anchor="middle" x="641.5" y="-623.3" font-family="Times,serif" font-size="14.00">Upper Atmosphere</text>
</g>
<!-- scatter -->
<g id="node2" class="node">
<title>scatter</title>
<polygon fill="lightgrey" stroke="black" points="643.5,-558 433.5,-558 433.5,-522 643.5,-522 643.5,-558"/>
<text text-anchor="middle" x="538.5" y="-536.3" font-family="Times,serif" font-size="14.00">Scattered by Air Molecules</text>
</g>
<!-- start&#45;&gt;scatter -->
<g id="edge1" class="edge">
<title>start&#45;&gt;scatter</title>
<path fill="none" stroke="black" d="M565.32,-611.83C555.24,-606.82 546.12,-600.08 539.5,-591 534.8,-584.56 533.35,-576.31 533.41,-568.38"/>
<polygon fill="black" stroke="black" points="536.91,-568.56 534.22,-558.31 529.93,-568 536.91,-568.56"/>
<text text-anchor="middle" x="635.5" y="-579.8" font-family="Times,serif" font-size="14.00">Initially Traveling Through</text>
</g>
<!-- absorb -->
<g id="node3" class="node">
<title>absorb</title>
<polygon fill="lightgrey" stroke="black" points="736.5,-384 536.5,-384 536.5,-348 736.5,-348 736.5,-384"/>
<text text-anchor="middle" x="636.5" y="-362.3" font-family="Times,serif" font-size="14.00">Absorbed by Ozone Layer</text>
</g>
<!-- start&#45;&gt;absorb -->
<g id="edge8" class="edge">
<title>start&#45;&gt;absorb</title>
<path fill="none" stroke="black" d="M711.63,-608.97C719.43,-604.35 726.39,-598.47 731.5,-591 778.93,-521.67 779.55,-470.9 731.5,-402 728.3,-397.4 724.42,-393.41 720.08,-389.94"/>
<polygon fill="black" stroke="black" points="722.05,-387.04 711.83,-384.24 718.07,-392.8 722.05,-387.04"/>
<text text-anchor="middle" x="858.5" y="-492.8" font-family="Times,serif" font-size="14.00">Absorbed by Ozone Layer</text>
</g>
<!-- transmit -->
<g id="node4" class="node">
<title>transmit</title>
<polygon fill="lightgrey" stroke="black" points="658,-471 419,-471 419,-435 658,-435 658,-471"/>
<text text-anchor="middle" x="538.5" y="-449.3" font-family="Times,serif" font-size="14.00">Transmitted through Clear Sky</text>
</g>
<!-- scatter&#45;&gt;transmit -->
<g id="edge2" class="edge">
<title>scatter&#45;&gt;transmit</title>
<path fill="none" stroke="black" d="M538.5,-521.8C538.5,-510.16 538.5,-494.55 538.5,-481.24"/>
<polygon fill="black" stroke="black" points="542,-481.18 538.5,-471.18 535,-481.18 542,-481.18"/>
<text text-anchor="middle" x="573.5" y="-492.8" font-family="Times,serif" font-size="14.00">Scattered</text>
</g>
<!-- end -->
<g id="node11" class="node">
<title>end</title>
<polygon fill="lightgrey" stroke="black" points="663.5,-297 609.5,-297 609.5,-261 663.5,-261 663.5,-297"/>
<text text-anchor="middle" x="636.5" y="-275.3" font-family="Times,serif" font-size="14.00">end</text>
</g>
<!-- absorb&#45;&gt;end -->
<g id="edge9" class="edge">
<title>absorb&#45;&gt;end</title>
<path fill="none" stroke="black" d="M636.5,-347.8C636.5,-336.16 636.5,-320.55 636.5,-307.24"/>
<polygon fill="black" stroke="black" points="640,-307.18 636.5,-297.18 633,-307.18 640,-307.18"/>
<text text-anchor="middle" x="727" y="-318.8" font-family="Times,serif" font-size="14.00">Absorbed by Atmosphere</text>
</g>
<!-- transmit&#45;&gt;absorb -->
<g id="edge10" class="edge">
<title>transmit&#45;&gt;absorb</title>
<path fill="none" stroke="black" d="M537.58,-434.98C537.89,-424.41 540,-411.14 547.5,-402 551.51,-397.11 556.29,-392.91 561.53,-389.29"/>
<polygon fill="black" stroke="black" points="563.38,-392.26 570.1,-384.06 559.74,-386.28 563.38,-392.26"/>
<text text-anchor="middle" x="639.5" y="-405.8" font-family="Times,serif" font-size="14.00">Absorbed by Ozone Layer</text>
</g>
<!-- cloud -->
<g id="node5" class="node">
<title>cloud</title>
<polygon fill="lightgrey" stroke="black" points="462.5,-384 308.5,-384 308.5,-348 462.5,-348 462.5,-384"/>
<text text-anchor="middle" x="385.5" y="-362.3" font-family="Times,serif" font-size="14.00">Encountered Cloud</text>
</g>
<!-- transmit&#45;&gt;cloud -->
<g id="edge3" class="edge">
<title>transmit&#45;&gt;cloud</title>
<path fill="none" stroke="black" d="M439.2,-434.99C420.43,-430.04 404.47,-424.03 397.5,-417 391.58,-411.03 388.39,-402.68 386.72,-394.51"/>
<polygon fill="black" stroke="black" points="390.17,-393.89 385.34,-384.46 383.23,-394.84 390.17,-393.89"/>
<text text-anchor="middle" x="466.5" y="-405.8" font-family="Times,serif" font-size="14.00">Encountered Cloud</text>
</g>
<!-- reflected -->
<g id="node6" class="node">
<title>reflected</title>
<polygon fill="lightgrey" stroke="black" points="368.5,-297 150.5,-297 150.5,-261 368.5,-261 368.5,-297"/>
<text text-anchor="middle" x="259.5" y="-275.3" font-family="Times,serif" font-size="14.00">Reflected by Water Droplets</text>
</g>
<!-- cloud&#45;&gt;reflected -->
<g id="edge4" class="edge">
<title>cloud&#45;&gt;reflected</title>
<path fill="none" stroke="black" d="M360,-347.8C340.79,-334.84 314.26,-316.94 293.28,-302.79"/>
<polygon fill="black" stroke="black" points="295.21,-299.87 284.96,-297.18 291.29,-305.67 295.21,-299.87"/>
<text text-anchor="middle" x="363" y="-318.8" font-family="Times,serif" font-size="14.00">Reflected</text>
</g>
<!-- absorbed_cloud -->
<g id="node7" class="node">
<title>absorbed_cloud</title>
<polygon fill="lightgrey" stroke="black" points="429,-210 270,-210 270,-174 429,-174 429,-210"/>
<text text-anchor="middle" x="349.5" y="-188.3" font-family="Times,serif" font-size="14.00">Absorbed by Clouds</text>
</g>
<!-- cloud&#45;&gt;absorbed_cloud -->
<g id="edge11" class="edge">
<title>cloud&#45;&gt;absorbed_cloud</title>
<path fill="none" stroke="black" d="M393.97,-347.79C406.06,-320.59 424.58,-266.78 403.5,-228 401.19,-223.75 398.11,-219.93 394.59,-216.52"/>
<polygon fill="black" stroke="black" points="396.79,-213.8 386.86,-210.1 392.32,-219.18 396.79,-213.8"/>
<text text-anchor="middle" x="484" y="-275.3" font-family="Times,serif" font-size="14.00">Absorbed by Clouds</text>
</g>
<!-- reflected&#45;&gt;absorbed_cloud -->
<g id="edge12" class="edge">
<title>reflected&#45;&gt;absorbed_cloud</title>
<path fill="none" stroke="black" d="M255.37,-260.79C253.89,-250.41 253.95,-237.41 260.5,-228 263.7,-223.4 267.61,-219.41 271.97,-215.94"/>
<polygon fill="black" stroke="black" points="274.01,-218.78 280.28,-210.24 270.05,-213.01 274.01,-218.78"/>
<text text-anchor="middle" x="332" y="-231.8" font-family="Times,serif" font-size="14.00">Absorbed by Clouds</text>
</g>
<!-- surface -->
<g id="node8" class="node">
<title>surface</title>
<polygon fill="lightgrey" stroke="black" points="184,-210 47,-210 47,-174 184,-174 184,-210"/>
<text text-anchor="middle" x="115.5" y="-188.3" font-family="Times,serif" font-size="14.00">Reached Surface</text>
</g>
<!-- reflected&#45;&gt;surface -->
<g id="edge5" class="edge">
<title>reflected&#45;&gt;surface</title>
<path fill="none" stroke="black" d="M155.37,-260.95C145.84,-256.28 136.97,-250.4 129.5,-243 123.46,-237.02 119.98,-228.67 117.98,-220.51"/>
<polygon fill="black" stroke="black" points="121.38,-219.67 116.16,-210.45 114.49,-220.92 121.38,-219.67"/>
<text text-anchor="middle" x="190" y="-231.8" font-family="Times,serif" font-size="14.00">Reached Surface</text>
</g>
<!-- backscatter -->
<g id="node9" class="node">
<title>backscatter</title>
<polygon fill="lightgrey" stroke="black" points="231,-123 0,-123 0,-87 231,-87 231,-123"/>
<text text-anchor="middle" x="115.5" y="-101.3" font-family="Times,serif" font-size="14.00">Backscattered by Atmosphere</text>
</g>
<!-- surface&#45;&gt;backscatter -->
<g id="edge6" class="edge">
<title>surface&#45;&gt;backscatter</title>
<path fill="none" stroke="black" d="M115.5,-173.8C115.5,-162.16 115.5,-146.55 115.5,-133.24"/>
<polygon fill="black" stroke="black" points="119,-133.18 115.5,-123.18 112,-133.18 119,-133.18"/>
<text text-anchor="middle" x="207.5" y="-144.8" font-family="Times,serif" font-size="14.00">Backscattered by Surface</text>
</g>
<!-- space -->
<g id="node10" class="node">
<title>space</title>
<polygon fill="lightgrey" stroke="black" points="187,-36 44,-36 44,0 187,0 187,-36"/>
<text text-anchor="middle" x="115.5" y="-14.3" font-family="Times,serif" font-size="14.00">Escaped to Space</text>
</g>
<!-- backscatter&#45;&gt;space -->
<g id="edge7" class="edge">
<title>backscatter&#45;&gt;space</title>
<path fill="none" stroke="black" d="M115.5,-86.8C115.5,-75.16 115.5,-59.55 115.5,-46.24"/>
<polygon fill="black" stroke="black" points="119,-46.18 115.5,-36.18 112,-46.18 119,-46.18"/>
<text text-anchor="middle" x="179" y="-57.8" font-family="Times,serif" font-size="14.00">Escaped to Space</text>
</g>
</g>
</svg>
<svg width="1070pt" height="653pt"
viewBox="0.00 0.00 1069.50 653.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 649)">
<title>photon_path</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-649 1065.5,-649 1065.5,4 -4,4"/>
<!-- start -->
<g id="node1" class="node">
<title>start</title>
<polygon fill="lightgrey" stroke="black" points="790.5,-645 638.5,-645 638.5,-609 790.5,-609 790.5,-645"/>
<text text-anchor="middle" x="714.5" y="-623.3" font-family="Times,serif" font-size="14.00">Upper Atmosphere</text>
</g>
<!-- scatter -->
<g id="node2" class="node">
<title>scatter</title>
<polygon fill="lightgrey" stroke="black" points="702.5,-558 492.5,-558 492.5,-522 702.5,-522 702.5,-558"/>
<text text-anchor="middle" x="597.5" y="-536.3" font-family="Times,serif" font-size="14.00">Scattered by Air Molecules</text>
</g>
<!-- start&#45;&gt;scatter -->
<g id="edge1" class="edge">
<title>start&#45;&gt;scatter</title>
<path fill="none" stroke="black" d="M638.33,-617.63C622.87,-612.32 608.35,-603.99 598.5,-591 593.68,-584.65 592.19,-576.43 592.26,-568.49"/>
<polygon fill="black" stroke="black" points="595.76,-568.66 593.1,-558.4 588.78,-568.08 595.76,-568.66"/>
<text text-anchor="middle" x="708" y="-579.8" font-family="Times,serif" font-size="14.00">Initially Traveling Through 0.7</text>
</g>
<!-- absorb -->
<g id="node3" class="node">
<title>absorb</title>
<polygon fill="lightgrey" stroke="black" points="858.5,-384 658.5,-384 658.5,-348 858.5,-348 858.5,-384"/>
<text text-anchor="middle" x="758.5" y="-362.3" font-family="Times,serif" font-size="14.00">Absorbed by Ozone Layer</text>
</g>
<!-- start&#45;&gt;absorb -->
<g id="edge8" class="edge">
<title>start&#45;&gt;absorb</title>
<path fill="none" stroke="black" d="M790.55,-612.56C801.12,-607.48 810.68,-600.52 817.5,-591 866.42,-522.71 859.07,-474.99 817.5,-402 815.05,-397.7 811.84,-393.87 808.18,-390.48"/>
<polygon fill="black" stroke="black" points="810.16,-387.58 800.14,-384.11 805.81,-393.06 810.16,-387.58"/>
<text text-anchor="middle" x="956" y="-492.8" font-family="Times,serif" font-size="14.00">Absorbed by Ozone Layer 0.2</text>
</g>
<!-- transmit -->
<g id="node4" class="node">
<title>transmit</title>
<polygon fill="lightgrey" stroke="black" points="717,-471 478,-471 478,-435 717,-435 717,-471"/>
<text text-anchor="middle" x="597.5" y="-449.3" font-family="Times,serif" font-size="14.00">Transmitted through Clear Sky</text>
</g>
<!-- scatter&#45;&gt;transmit -->
<g id="edge2" class="edge">
<title>scatter&#45;&gt;transmit</title>
<path fill="none" stroke="black" d="M597.5,-521.8C597.5,-510.16 597.5,-494.55 597.5,-481.24"/>
<polygon fill="black" stroke="black" points="601,-481.18 597.5,-471.18 594,-481.18 601,-481.18"/>
<text text-anchor="middle" x="646" y="-492.8" font-family="Times,serif" font-size="14.00">Scattered 0.8</text>
</g>
<!-- end -->
<g id="node11" class="node">
<title>end</title>
<polygon fill="lightgrey" stroke="black" points="785.5,-297 731.5,-297 731.5,-261 785.5,-261 785.5,-297"/>
<text text-anchor="middle" x="758.5" y="-275.3" font-family="Times,serif" font-size="14.00">end</text>
</g>
<!-- absorb&#45;&gt;end -->
<g id="edge9" class="edge">
<title>absorb&#45;&gt;end</title>
<path fill="none" stroke="black" d="M758.5,-347.8C758.5,-336.16 758.5,-320.55 758.5,-307.24"/>
<polygon fill="black" stroke="black" points="762,-307.18 758.5,-297.18 755,-307.18 762,-307.18"/>
<text text-anchor="middle" x="862.5" y="-318.8" font-family="Times,serif" font-size="14.00">Absorbed by Atmosphere 1.0</text>
</g>
<!-- transmit&#45;&gt;absorb -->
<g id="edge10" class="edge">
<title>transmit&#45;&gt;absorb</title>
<path fill="none" stroke="black" d="M596.13,-434.59C596.26,-423.85 598.35,-410.56 606.5,-402 613.49,-394.66 629.39,-388.62 648.39,-383.75"/>
<polygon fill="black" stroke="black" points="649.35,-387.12 658.26,-381.38 647.71,-380.31 649.35,-387.12"/>
<text text-anchor="middle" x="712" y="-405.8" font-family="Times,serif" font-size="14.00">Absorbed by Ozone Layer 0.1</text>
</g>
<!-- cloud -->
<g id="node5" class="node">
<title>cloud</title>
<polygon fill="lightgrey" stroke="black" points="494.5,-384 340.5,-384 340.5,-348 494.5,-348 494.5,-384"/>
<text text-anchor="middle" x="417.5" y="-362.3" font-family="Times,serif" font-size="14.00">Encountered Cloud</text>
</g>
<!-- transmit&#45;&gt;cloud -->
<g id="edge3" class="edge">
<title>transmit&#45;&gt;cloud</title>
<path fill="none" stroke="black" d="M477.6,-436.21C455.97,-431.25 437.68,-424.94 429.5,-417 423.31,-410.99 420.08,-402.39 418.46,-394.01"/>
<polygon fill="black" stroke="black" points="421.93,-393.56 417.19,-384.09 414.99,-394.45 421.93,-393.56"/>
<text text-anchor="middle" x="512" y="-405.8" font-family="Times,serif" font-size="14.00">Encountered Cloud 0.3</text>
</g>
<!-- reflected -->
<g id="node6" class="node">
<title>reflected</title>
<polygon fill="lightgrey" stroke="black" points="395.5,-297 177.5,-297 177.5,-261 395.5,-261 395.5,-297"/>
<text text-anchor="middle" x="286.5" y="-275.3" font-family="Times,serif" font-size="14.00">Reflected by Water Droplets</text>
</g>
<!-- cloud&#45;&gt;reflected -->
<g id="edge4" class="edge">
<title>cloud&#45;&gt;reflected</title>
<path fill="none" stroke="black" d="M391.13,-347.91C382.34,-342.22 372.5,-335.84 363.5,-330 349.81,-321.12 334.76,-311.35 321.62,-302.81"/>
<polygon fill="black" stroke="black" points="323.16,-299.64 312.87,-297.13 319.35,-305.51 323.16,-299.64"/>
<text text-anchor="middle" x="410.5" y="-318.8" font-family="Times,serif" font-size="14.00">Reflected 0.6</text>
</g>
<!-- absorbed_cloud -->
<g id="node7" class="node">
<title>absorbed_cloud</title>
<polygon fill="lightgrey" stroke="black" points="458,-210 299,-210 299,-174 458,-174 458,-210"/>
<text text-anchor="middle" x="378.5" y="-188.3" font-family="Times,serif" font-size="14.00">Absorbed by Clouds</text>
</g>
<!-- cloud&#45;&gt;absorbed_cloud -->
<g id="edge11" class="edge">
<title>cloud&#45;&gt;absorbed_cloud</title>
<path fill="none" stroke="black" d="M443.9,-347.65C449.4,-342.66 454.45,-336.72 457.5,-330 476.23,-288.72 482.23,-266 457.5,-228 454.56,-223.48 450.88,-219.54 446.74,-216.1"/>
<polygon fill="black" stroke="black" points="448.45,-213.03 438.27,-210.1 444.41,-218.74 448.45,-213.03"/>
<text text-anchor="middle" x="558.5" y="-275.3" font-family="Times,serif" font-size="14.00">Absorbed by Clouds 0.4</text>
</g>
<!-- reflected&#45;&gt;absorbed_cloud -->
<g id="edge12" class="edge">
<title>reflected&#45;&gt;absorbed_cloud</title>
<path fill="none" stroke="black" d="M282.34,-260.77C280.86,-250.38 280.92,-237.38 287.5,-228 290.78,-223.32 294.78,-219.27 299.25,-215.76"/>
<polygon fill="black" stroke="black" points="301.43,-218.51 307.74,-210.01 297.5,-212.72 301.43,-218.51"/>
<text text-anchor="middle" x="372.5" y="-231.8" font-family="Times,serif" font-size="14.00">Absorbed by Clouds 0.3</text>
</g>
<!-- surface -->
<g id="node8" class="node">
<title>surface</title>
<polygon fill="lightgrey" stroke="black" points="184,-210 47,-210 47,-174 184,-174 184,-210"/>
<text text-anchor="middle" x="115.5" y="-188.3" font-family="Times,serif" font-size="14.00">Reached Surface</text>
</g>
<!-- reflected&#45;&gt;surface -->
<g id="edge5" class="edge">
<title>reflected&#45;&gt;surface</title>
<path fill="none" stroke="black" d="M177.41,-262.01C155.98,-256.98 137.61,-250.68 129.5,-243 123.17,-237 119.63,-228.41 117.67,-220.02"/>
<polygon fill="black" stroke="black" points="121.11,-219.37 115.98,-210.1 114.21,-220.55 121.11,-219.37"/>
<text text-anchor="middle" x="203.5" y="-231.8" font-family="Times,serif" font-size="14.00">Reached Surface 0.8</text>
</g>
<!-- backscatter -->
<g id="node9" class="node">
<title>backscatter</title>
<polygon fill="lightgrey" stroke="black" points="231,-123 0,-123 0,-87 231,-87 231,-123"/>
<text text-anchor="middle" x="115.5" y="-101.3" font-family="Times,serif" font-size="14.00">Backscattered by Atmosphere</text>
</g>
<!-- surface&#45;&gt;backscatter -->
<g id="edge6" class="edge">
<title>surface&#45;&gt;backscatter</title>
<path fill="none" stroke="black" d="M115.5,-173.8C115.5,-162.16 115.5,-146.55 115.5,-133.24"/>
<polygon fill="black" stroke="black" points="119,-133.18 115.5,-123.18 112,-133.18 119,-133.18"/>
<text text-anchor="middle" x="221" y="-144.8" font-family="Times,serif" font-size="14.00">Backscattered by Surface 0.7</text>
</g>
<!-- space -->
<g id="node10" class="node">
<title>space</title>
<polygon fill="lightgrey" stroke="black" points="187,-36 44,-36 44,0 187,0 187,-36"/>
<text text-anchor="middle" x="115.5" y="-14.3" font-family="Times,serif" font-size="14.00">Escaped to Space</text>
</g>
<!-- backscatter&#45;&gt;space -->
<g id="edge7" class="edge">
<title>backscatter&#45;&gt;space</title>
<path fill="none" stroke="black" d="M115.5,-86.8C115.5,-75.16 115.5,-59.55 115.5,-46.24"/>
<polygon fill="black" stroke="black" points="119,-46.18 115.5,-36.18 112,-46.18 119,-46.18"/>
<text text-anchor="middle" x="192.5" y="-57.8" font-family="Times,serif" font-size="14.00">Escaped to Space 0.9</text>
</g>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment