tag:blogger.com,1999:blog-91518801694903564012024-03-05T04:52:46.062-08:00Coding RelicRandom musings on software in an embedded world.Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comBlogger338125tag:blogger.com,1999:blog-9151880169490356401.post-7823075752189665392021-07-23T21:01:00.004-07:002021-07-23T21:01:37.386-07:00Kthubernetes<p>Inconceivable: zero hits for "Kthubernetes" ?</p>
<p>Unacceptable. This will not stand.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN0WF2DlSDF5tb4xh4ledOMh1qPql8hBAQiljMs2p_DP3gBvaTNjAnQeIJSWlLA3dVGcKu1Zh2HAET_h8hGtGULl0VKqVGg72OvByZXWFG4ZaNo8pfxAunvoqm5nAKzvn8U19KJId26HzB/s1384/KthubernetesNoHits.png" style="display: block; padding: 1em 0; text-align: center; clear: left; float: left;"><img alt="" border="0" width="400" data-original-height="968" data-original-width="1384" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN0WF2DlSDF5tb4xh4ledOMh1qPql8hBAQiljMs2p_DP3gBvaTNjAnQeIJSWlLA3dVGcKu1Zh2HAET_h8hGtGULl0VKqVGg72OvByZXWFG4ZaNo8pfxAunvoqm5nAKzvn8U19KJId26HzB/s400/KthubernetesNoHits.png"/></a></div>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-87276154641113765162019-11-28T11:25:00.000-08:002019-11-28T11:25:04.790-08:00gdaldem color-relief is my BFF<p>When working with geospatial data and maps, an effective way to communicate in email is to send images highlighting the specific thing one wants to point out. For example, showing areas where the dominant land cover is lichens:</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmWnu-AvRmW6e0kW31m-yXCyR_iwrLKWXbjYay4zTPD52u8aZFC3xmqwKrLXm4IVHVhne6v0D4FKulZ7moTjOGIEZlFU3Uic52puMFMOKaS1igXiEsQ0DcXoACzb5KyN8YBLZkqFizzJU-/s1600/color_lichens.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmWnu-AvRmW6e0kW31m-yXCyR_iwrLKWXbjYay4zTPD52u8aZFC3xmqwKrLXm4IVHVhne6v0D4FKulZ7moTjOGIEZlFU3Uic52puMFMOKaS1igXiEsQ0DcXoACzb5KyN8YBLZkqFizzJU-/s400/color_lichens.jpg" width="400" height="200" data-original-width="1296" data-original-height="648" /></a></div>
<p>gdaldem, though named for its role in processing Digital Elevation Maps, is a useful tool even for things which have nothing to do with elevation. It has a color-relief subcommand intended for color gradients of terrain but which can be used for lots of purposes. It takes a simple text file mapping pixel values in the original to colors in the output. For example, my lichen image above used:</p>
<pre style="margin-left: 3em;">0 black
1 grey
139 grey
140 red
141 grey
209 grey
210 black
211 grey</pre>
<p>This means:</p>
<ul>
<li>pixel value of zero (NoData in the original image) should be colored black.</li>
<li>water is pixel value 210 in the original image, so make it black as well.</li>
<li>the land cover class for lichen in the original image is 140, so color it red.</li>
<li>we set grey for 1 and 139, for 141 and 209, and for 211 because by default, gdaldem color-relief would create a gradient of colors between those specified. We want those areas to be solid grey.</li>
</ul>
<p>The original image was:</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjf86Mz59lX2acQmwOnZ-B8PASl1-cE6p0_5B5ZTzUV5RRUx5Um3h_95d2zzqchvxF4JZFQ43jFHPgHO1pZ37CJ7ebV3wAm8D3QHcQFveFFg-Jw-Qiirao4LphuyHsjQuP77dLi0h5KTIC/s1600/small.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjf86Mz59lX2acQmwOnZ-B8PASl1-cE6p0_5B5ZTzUV5RRUx5Um3h_95d2zzqchvxF4JZFQ43jFHPgHO1pZ37CJ7ebV3wAm8D3QHcQFveFFg-Jw-Qiirao4LphuyHsjQuP77dLi0h5KTIC/s400/small.jpg" width="400" height="200" data-original-width="1600" data-original-height="800" /></a></div>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-340288372760670402019-09-09T14:00:00.000-07:002019-10-01T09:23:50.903-07:00Mini-split Heat Pump Installation<p>We live in a home which was built in 1963, older than we are. The structure has some great attributes and some not-so-great attributes. Among the not-so-great is the lack of air conditioning, and a pair of ancient furnaces with very high gas bills. We set out to do something about this.</p>
<ul>
<li>We wanted to add air conditioning.</li>
<li>We wanted a much more efficient heating system.</li>
<li>The ducts were 50+ years old and clearly leaky, with dirty patches in the insulation at each joint where the duct has been pulling air through for decades. They would not pass current inspections.</li>
</ul>
<p>As essentially none of the existing HVAC would remain, we could consider options which didn't preserve any of it. We decided to go with a ductless mini-split heat pump system.</p>
<p>A <a href="https://en.wikipedia.org/wiki/Heat_pump">heat pump</a> is an idea which has been around for a while. It operates similarly to an air conditioner in that it repeatedly compresses and expands a refrigerant, circulating it in and out of the house while doing so. The difference is that where an air conditioner always compresses the refrigerant outside of the house to release heat, the heat pump can also reverse the process to release heat inside. A heat pump can either heat or cool based on where it allows the refrigerant to expand.</p>
<br/> <br/>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv5eINrjds0fBd3wxQ82WqNN60dPFhnh5fiuZ_SqVrTuP62y927vUQlr05RPLkfDCa6chAh8yLD-caGvGeNzJ4t3T_VgNiWGev3rjMHacZfJLQywuzZNHO0U6huNTtx7gVRwu3avM1_D63/s1600/IMG_20190813_061950.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv5eINrjds0fBd3wxQ82WqNN60dPFhnh5fiuZ_SqVrTuP62y927vUQlr05RPLkfDCa6chAh8yLD-caGvGeNzJ4t3T_VgNiWGev3rjMHacZfJLQywuzZNHO0U6huNTtx7gVRwu3avM1_D63/s320/IMG_20190813_061950.jpg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a>
<p>There are heat pumps which can replace a central furnace and hook up to the existing ducting, but as the ducts were in terrible shape we opted for a mini-split system. There is no central air handling nor air ducts in this system, there are individual units in each room which are connected to a compressor outside.</p>
</div>
<p>In each major room a head unit is mounted high on the wall, and contains refrigerant coils and fans. Air is circulated within the room, not drawn from nor exhausted to the outside.</p>
<br/> <br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSNBt-tKIf-qMK9voOzzlks740Ds928e3gRnYNV_5tqTlwsAQnTaNop6EmDQ9x2wVuvm_XLkPH35nDp0o9e49uavyLwKKb04V7iSqFJ5ElhaFvMrLI7gBiakmprW5CC8yGJVeFEmbU3JxE/s1600/IMG_3638.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSNBt-tKIf-qMK9voOzzlks740Ds928e3gRnYNV_5tqTlwsAQnTaNop6EmDQ9x2wVuvm_XLkPH35nDp0o9e49uavyLwKKb04V7iSqFJ5ElhaFvMrLI7gBiakmprW5CC8yGJVeFEmbU3JxE/s320/IMG_3638.jpg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></div>
<p>The head unit connects to power and two refrigerant lines. This picture was taken during the installation, with the wall open and the two copper refrigerant lines not yet hooked to the head unit.</p>
<p>Note that there is no air duct: air is not moved through the home with a mini-split, only refrigerant. The head unit can cool or heat air drawn from the room, using the refrigerant to pump heat in or out of the house.</p>
<p>I emphasize the lack of ducts because it was a big mental hurdle for us. In a retrofit the heat pump units can go <b>anywhere,</b> placement is not constrained to where ducts currently go.</p>
<br/> <br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMfUSTSQ1howdz6avAP_LgsppFR58tRbmpe0jfv3eFnEpNkTBrXaAoQxADsoZr1_crm0TwaKc0uJNVzOeSJO4JMsv4AqNwQqC9ygPipPfSFbBsdF9yUuqqBiQpNmUrxek3aTuThEd4JN1A/s1600/IMG_20190813_062515.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMfUSTSQ1howdz6avAP_LgsppFR58tRbmpe0jfv3eFnEpNkTBrXaAoQxADsoZr1_crm0TwaKc0uJNVzOeSJO4JMsv4AqNwQqC9ygPipPfSFbBsdF9yUuqqBiQpNmUrxek3aTuThEd4JN1A/s320/IMG_20190813_062515.jpg" width="320" height="240" data-original-width="1600" data-original-height="1200" /></a></div>
<p>The head unit contains a filter in front of the fan, but the activated charcoal portion of the filter covers only a small portion of the area. We have no way to measure the effectiveness of this filter, but we are skeptical as it seems like air can flow around it easily.</p>
<br clear=right /><br clear=left /><hr/><br/>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinh1WOWA2z8mQ81eDuzyLcLfyTvAhwB8iSF_5ZVTNfDRiK-y-Em1tg390WFlCIHFmXjMH4OhVfFPwoiPtt5A-P16vUUnTueEFn1klCFgtjpf61gt3YJC7NJRZf5uPCGi6sLcirIwLLEgzW/s1600/IMG_20190909_093857.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinh1WOWA2z8mQ81eDuzyLcLfyTvAhwB8iSF_5ZVTNfDRiK-y-Em1tg390WFlCIHFmXjMH4OhVfFPwoiPtt5A-P16vUUnTueEFn1klCFgtjpf61gt3YJC7NJRZf5uPCGi6sLcirIwLLEgzW/s320/IMG_20190909_093857.jpg" width="240" height="320" data-original-width="1200" data-original-height="1600" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZvmgsTzQnk_OXyK7tjVW-FRYA2Edm64ToFt8nTOu5bPF0tCFq7dZSYhTuQhYANOYWRTSO2FPwWEbGpuAnDBd4H3HJe_PAN3JUM2YBurs_mTUWQ9aluK3eHm-5h8_gjlczm1FX18yz8DzF/s1600/IMG_20190909_093916.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZvmgsTzQnk_OXyK7tjVW-FRYA2Edm64ToFt8nTOu5bPF0tCFq7dZSYhTuQhYANOYWRTSO2FPwWEbGpuAnDBd4H3HJe_PAN3JUM2YBurs_mTUWQ9aluK3eHm-5h8_gjlczm1FX18yz8DzF/s200/IMG_20190909_093916.jpg" width="200" height="150" data-original-width="1600" data-original-height="1200" /></a>
<p>The refrigerant connections are quite small, half inch diameter copper pipes plus insulation, so they can run between studs in the walls and under the house. They all eventually lead to an outdoor unit, which contains a fan and radiating fins like an air conditioner outdoor unit would.</p>
<p>The outdoor unit is available in a few capacities, rated in British Thermal Units (BTUs) like 20k - 50k. The head units inside the home are also rated in BTUs, from 9k through 24k, and one adds up the rating of the head units to determine the capacity of outdoor unit required.</p>
<p>Our home needed two outdoor units, a larger 50k BTU unit for the upstairs and smaller 20k unit for the lower level.</p>
</div>
<br clear=left /><br clear=right /><hr/><br/>
<div class="separator" style="clear: both;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwhS5prDkNbLt2nFh42hoI7prWchCwU4nsGhFkfFWx5H1mf3tZjUAYJnEl2JYX1VyBpqEv4f0BRDPFK7PyyPIHdvcdTJ63pt7q0fD9229aKnU-h8gNr8ss_YY-2VucyebVvp5c3i9FSfSj/s1600/IMG_20190909_102521.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwhS5prDkNbLt2nFh42hoI7prWchCwU4nsGhFkfFWx5H1mf3tZjUAYJnEl2JYX1VyBpqEv4f0BRDPFK7PyyPIHdvcdTJ63pt7q0fD9229aKnU-h8gNr8ss_YY-2VucyebVvp5c3i9FSfSj/s320/IMG_20190909_102521.jpg" width="121" height="320" data-original-width="604" data-original-height="1600" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpb7u3yCznFARb7QBaT7ALJdW7l3aiQcBJQBrrdKhcrsPfAcSwRsE3XnP7Ibclo1qTR2Tz4vkeQIlLW6DERg7V9I-Fv4kehoPZdJcYZGSTH4fv5x1pndxsYRXv520c-QjDo2bjRpuYoXtu/s1600/IMG_20190909_102514.jpg" imageanchor="1" style="float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpb7u3yCznFARb7QBaT7ALJdW7l3aiQcBJQBrrdKhcrsPfAcSwRsE3XnP7Ibclo1qTR2Tz4vkeQIlLW6DERg7V9I-Fv4kehoPZdJcYZGSTH4fv5x1pndxsYRXv520c-QjDo2bjRpuYoXtu/s320/IMG_20190909_102514.jpg" width="88" height="320" data-original-width="442" data-original-height="1600" /></a>
<p>With a furnace or central air, a single thermostat controls the HVAC. That thermostat might be very sophisticated with multiple room sensors, but there is a single central point where control can be implemented.</p>
<p>With ductless mini-split systems, there is no single point of control. Each head unit implements its own local control, it can implement its own schedule, etc. The system is supplied with a handheld remote control for each head unit. It appears to be infrared, and it is not strongly paired with a given head unit. If you take it into another room and point it at a head unit in that room, it will control the head unit in the new room.</p>
<p>The remote is quite complicated. It can change the mode from heating to cooling to fan (and others). It can program weekly schedules. For some models of head unit, it can configure an occupancy sensor feature to aim the airflow directly at people in the room and turn off if nobody is present. Etc, etc.</p>
</div>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrF52LpwjqE9Wj4VpbVMBw7b-gZwdg8XJcb39_PGZacoRKNVDRSixg5w94zZEkDJE88d0KepWbFJvh0OrRS6LstPd_ZLgnrwwfK-uDzcu1qI5SEOZfMfDE2NbRq6vp7PnjsY62XoDP6G-O/s1600/IMG_20190909_102650.jpg" imageanchor="1" style="float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrF52LpwjqE9Wj4VpbVMBw7b-gZwdg8XJcb39_PGZacoRKNVDRSixg5w94zZEkDJE88d0KepWbFJvh0OrRS6LstPd_ZLgnrwwfK-uDzcu1qI5SEOZfMfDE2NbRq6vp7PnjsY62XoDP6G-O/s200/IMG_20190909_102650.jpg" width="160" height="120" data-original-width="1600" data-original-height="1200" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKC9kOu7CkzTwRXNFNk55EXubIMlkLCZcBaEDgXHfEM8k9zChTHRhBQXe9er_pP7kg5jy_lP_eEHGkXyv0Gn6CFCfQsHT2JJmbUVNVpdS3VK8p9dqKSTuvP6TxS49m3h8rNhIkO8PtzQRD/s1600/IMG_20190909_104553.jpg" imageanchor="1" style="float: right; margin-bottom: 1em; margin-left: 2px;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKC9kOu7CkzTwRXNFNk55EXubIMlkLCZcBaEDgXHfEM8k9zChTHRhBQXe9er_pP7kg5jy_lP_eEHGkXyv0Gn6CFCfQsHT2JJmbUVNVpdS3VK8p9dqKSTuvP6TxS49m3h8rNhIkO8PtzQRD/s200/IMG_20190909_104553.jpg" width="160" height="120" data-original-width="1600" data-original-height="1200" /></a>
<p>We use the remote controls for all but one of the head units. For the last unit, we had reasons to not want to change how the HVAC system is operated and wanted to retain the existing themostat on the wall exactly as it was. Mitsubishi <a href="https://www.amazon.com/Mitsubishi-PAC-US444CN-1-Thermostat-Adapter-Interface/dp/B01MYNBV0A">has an interface to allow this</a>, connecting any 5-wire thermostat to control a single head unit.</p>
</div>
<br clear=left /><br clear=right /><hr/><br/>
<p>A few things we wish we'd known at the start, in case anyone reading this is planning their own heat pump installation:</p>
<ul>
<li>All of the head units attached to a given outdoor unit have to be cooling or heating, not a mixture of both. We got lucky in this: we needed separate outdoor units for each level, and this matches our usage as the lower level doesn't get so warm while the upstairs needs cooling during the summer.</li>
<li>The smaller outdoor units can be attached to the side of the house on a bracket. The larger outdoor units require a concrete pad to be poured. Had we known this we might have chosen to go with three smaller outdoor units and had them all mounted to the side of the house.</li>
</ul>
<p>At the time of this writing we've had the system for five months, through our first summer. It has been great having the option to cool the house on those days which need it. We are just heading into the cooler months, and we're hoping to see a substantial reduction in the energy bill.</p>
<p>We're quite happy with the system. Heat pumps are also an effective means to help with global warming by <a href="https://www.drawdown.org/solutions/buildings-and-cities/heat-pumps">improving efficiency and reducing use of methane, and are #42 on Project Drawdown's list</a>.</p>
<br clear=left /><br clear=right /><hr/><br/>
<p>Our system consists of:</p>
<ul>
<li>3 x MSZ-FH15 15k BTU head units</li>
<li>1 x MSZ-FH12 12k BTU head unit</li>
<li>3 x MSZ-FH06 6k BTU head units</li>
<li>1 x MXZ-8C48 48k BTU outdoor unit</li>
<li>1 x MXZ-2C20 20k BTU outdoor unit</li>
<li>1 x PAC-US444CN thermostat interface</li>
<li>electrical panel work to rearrange breakers and install new 40A and 25A circuits</li>
<li>permits and fees</li>
<li>demo and removal of old ducts and furnace equipment</li>
</ul>
<p>The total cost was $31,665 for equipment and installation, in the SF Bay Area where the cost of living is high. Our gas bill in the winter with the old furnaces was often $400/month, which should decline substantially with an electric heat pump powered by solar panels on the roof.</p>
<p>The system was provided and installed by <a href="https://alternativehvacs.com/">Alternative HVAC Solutions in San Carlos, CA</a>, and we were quite pleased with their work.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-39014145704325446242019-08-12T20:20:00.001-07:002019-08-13T06:01:41.164-07:00LED bulbs for FLOS Fucsia light fixtures<p><img style="clear:right;float:right;margin-bottom:1em;margin-right:1em;" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZU-AvPXHciXnf1PjTwE1Z2YVsarLcLOn_VrxSmNC7VHykXfqagH1C5soig3IEa9c0PGTSuJ85Q5T5uv40h87zVOI4aK3g5EYqKOGNUH1aH_jXA1mQHLlGsTv3h-n3tBwj2H_mUnnkjTYq/s400/FLOS_Fucsia_8.jpg" width="395" height="376" />The home we currently live in had a <a href="https://usa.flos.com/modern-pendant-lights/Fucsia-8">FLOS Fucsia 8</a> light fixture in the dining room when we moved in. The look of the fixture and the gentle chimes it makes when a breeze blows in from outside is quite appealing.</p>
<p>However we decided <b>not</b> to keep the light bulbs it came with, Philips Spotone NR50 25 Watt halogen bulbs. Replacing them with LEDs turned out to be considerably more difficult than we expected, this post is intended to help anyone else with one of these fixtures who is looking for options.</p>
<br clear=left />
<br clear=right />
<img style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5H_pSzR5yATaGr1mIBUuuMp7jrZ7CVe4Lsh1WW2Q23p4tzA1xx8NnWbhW2apF_wbTOcG79FFO1JXLijFESLoiY1J-b1vtm6kotJCPZcthNsSoxGlADWs9_w2WM0AGbFjrueUI6EBJ9cR4/s400/E12_E14_E26.jpg" width="299" height="341" />
<p>The base of the bulbs is one not commonly used in the United States: E14. A "candelabra" bulb is E12, a regular bulb is E26. In this nomenclature the E is for "Edison" and refers to the type of screw in base, and the number is millimeters width. The base of the bulbs used in the FLOS Fucsia line of fixtures are slightly larger than a candelabra bulb.</p>
<p>Though not common in the United States, E14 bulbs are quite common in Europe, which means that most of the E14 bulbs you find are designed for the European voltage of 220V and not the US voltage of 120V. Bulbs which are not dimmable will often work all the way down to 85V, but dimmable bulbs are calibrated for 220V and when powered at 120V they are fully dim or all the way off.</p>
<br clear=left />
<br clear=right />
<p>It took several tries to find dimmable bulbs which work at the US voltage in this fixture:</p>
<ul>
<li>we first bought <a href="https://www.amazon.com/gp/product/B07L4Z63Q1/">non-dimmable bulbs from EBD lighting</a>. These worked, but we missed being able to have a more intimate dinner with the lights turned low.</li>
<li>we unintentionally bought dimmable bulbs for European voltage. These did not work at all at 120V, the light would not turn on.</li>
<li>a bit later, we found the perfect bulbs: <a href="https://www.aamsco.com/light-bulbs/european-specialty/">AAMSCO is a specialty vendor</a> which makes an <a href="http://www.lightbulbmarket.com/product/010154_4-Watt-NR50-Dimmable-2700K-Filament-LED-Light-Bulb">LED version of the E14 NR50 spotlight</a> which is dimmable at 120 volts. It is about 4x as expensive as most LED bulbs, but a perfect fit for this fixture. We felt it was worth splurging. We bought them at lightbulbmarket.com, which offers a box of 10 bulbs at a small discount.</li>
</ul>
<br/><hr/><br/>
<p>This image shows the comparison between the original Philips Spotone halogen bulbs, the non-dimmable EBD Lighting bulbs, and the AAMSCO dimmable bulbs. The EBD bulbs have a notably bluer temperature and are considerably brighter than the other two. The AAMSCO LED bulbs roughly match the temperature and light output of the original halogens.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1tVWiPLZZegAVhX646DezlSvuueDxzS0VMd0Xd_QFrx5REtB8XWQYSBcYfIzun7I-CK3KVLG_spmELIax7NbUCX_wJmeukwknUzMurqMUk2buQrZSvfcF-beBr_YGsCDRid75dxQf4KBK/s1600/Three+LEDs.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1tVWiPLZZegAVhX646DezlSvuueDxzS0VMd0Xd_QFrx5REtB8XWQYSBcYfIzun7I-CK3KVLG_spmELIax7NbUCX_wJmeukwknUzMurqMUk2buQrZSvfcF-beBr_YGsCDRid75dxQf4KBK/s640/Three+LEDs.jpg" width="609" height="510" data-original-width="1218" data-original-height="1020" /></a></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpNlIvlZVklQstTzTpNtVicbdxuGAkG4IcsQvKfMC5K7JrMdn-_-el2X7QTgsxzDAKB8Bkdm8mTSeO4JrLpknNIV85gKt_79dG0XDrVaG1nn4ISmsHexxo0XlzsTfHOJ6Yg6BbkF2997FX/s1600/Three+bulbs+in+hand.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpNlIvlZVklQstTzTpNtVicbdxuGAkG4IcsQvKfMC5K7JrMdn-_-el2X7QTgsxzDAKB8Bkdm8mTSeO4JrLpknNIV85gKt_79dG0XDrVaG1nn4ISmsHexxo0XlzsTfHOJ6Yg6BbkF2997FX/s400/Three+bulbs+in+hand.jpg" width="588" height="802" /></a></div>
<br/><hr/><br/>
<p>The climate change connection: energy savings from LED lights is the <a href="https://www.drawdown.org/solutions/buildings-and-cities/led-lighting-household">#33 solution for global warming</a> on <a href="https://drawdown.org/">Project Drawdown's</a> list.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-82847966916827666332019-07-01T07:00:00.000-07:002019-07-01T07:00:09.449-07:00Discourse.org SSO with gitlab.com<p>A previous post discussed how to set up a <a href="https://discourse.org/">Discourse forum</a> to run as a service within JupyterHub. Though this makes the forum appear within the URL space of the JupyterHub server, it still runs as a completely separate service with its own notion of accounts and identities. We're tackling that in this post, describing how to make Discourse use single sign on (SSO) from gitlab.com, which is also how we set up JupyterHub accounts to work.</p>
<p>The previous post went over creating a JupyterHub service configuration for the Discourse service. We now add a second service, for the SSO server. This example is for <a href="http://tljh.jupyter.org/">The Littlest JupyterHub,</a> where we create a snippet in /opt/tljh/config/jupyterhub_config.d/discourse-service.py.</p>
<pre style="font-family:monospace;font-size:10px;line-height:1.3em;margin-left:2em;">c.JupyterHub.services = [
{
'name': 'forum',
'url': 'http://172.17.0.2:80/',
'api_token': 'no_token',
},
{
'name': 'discourse-sso',
'url': 'http://127.0.0.1:10101',
'command': ['/opt/tljh/user/bin/flask', 'run', '--port=10101'],
'environment': {'FLASK_APP': '/opt/tljh/hub/bin/discourse-sso.py',
'GITLAB_CLIENT_ID': '...',
'GITLAB_CLIENT_SECRET': '...',
'EXTERNAL_BASE_URL': 'https://jupyterhub.example.com',
'DISCOURSE_SECRET': '...',
},
},
]</pre>
<p>Code for the service is at <a href="https://gitlab.com/DentonGentry/discourse-gitlab-sso/tree/master">discourse-gitlab-sso</a>. It provides a Python Flask-based service which:</p>
<ul>
<li>Listens for SSO redirects from discourse, which arrive at discourse_sso() and results in redirecting the browser to gitlab.com for an OAuth request.</li>
<li>gitlab.com redirects the browser to gitlab_oauth_callback() with the OAuth response. Python code sends several followup requests to get a token and fetch information about the user from GitLab.</li>
<li>gitlab_user_to_discourse() maps the information retrieved from gitlab to the format expected by Discourse, and the browser is finally redirected back to Discourse with the SSO information encoded.</li>
</ul>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-958235626595378852019-06-09T16:32:00.000-07:002019-06-09T16:32:04.928-07:00ipywidgets.Text background-color<p><img border="0" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBiyNzIQBjej0JI8SO-myuiD8c5pCt_TwOzD-TRdv8xcWkq1FZVUVI8-9u-8lk9QOdH5zXdnnU8spT6B0VSGSuKM-2M__Tc1rm_Z_cThlXHoKXAWFYdJPqMti-QHLzOP65ihkNnUwOsZSy/s320/ipywidget+Text+styling.png" width="262" height="211" />This took some time to figure out so I'll post it here in hope it helps someone else. To set the color of an ipywidgets Text box using CSS, you need to:</p>
<ul>
<li>add a CSS class name to the Text widget</li>
<li>render an HTML <style> block for an <input> element descendant of that class</li>
<li>Set !important on the background-color, to prevent it being overridden by a later Jupyter-declared style.</li>
</ul>
<p>For my case the Text widget was being included in a VBox, allowing the HTML widget containing the <style> to be included in the list.</p>
<br clear=right />
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 1em;">
data_input_style = "<style>.data_input input { background-color:#D0F0D0 !important; }</style>"
value_entry = ipywidgets.Text(value='')
value_entry.add_class('data_input')
children = [
...
ipywidgets.HTML(data_input_style),
value_entry,
...
]
ipywidgets.VBox(children=children, ...)</pre>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-76490704268906370082019-06-05T06:00:00.000-07:002019-06-05T06:00:06.057-07:00Discourse as a JupyterHub Service<p><a href="https://jupyterhub.readthedocs.io/en/stable/index.html">JupyterHub</a> is a system for managing cloud-hosted Jupyter Notebooks, allowing users to log in and spawning a notebook or Jupyterlab instance for them. JupyterHub has a notion of <a href="https://jupyterhub.readthedocs.io/en/stable/reference/services.html#hub-authentication-and-services">Services, separate processes either started by or at least managed by JupyterHub</a> alongside the notebook instances. All JupyterHub Services appear at https://jupyterhub.example.com/services/name_of_service.</p>
<p><img border="0" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilan_UVEEt2VFgW7imWsgjE2Iswat7JHVmY3gDhfPwEb6bC_3znBtehZEfiql2clOycRmHU4JhCgB3doJiOQoQdDkHDzl4wwyFfTo1z8Yo_ERyxts9I-jV1Qud-PuPyTmv28KTregntVvr/s400/discourse_docker_proxy.png" width="387" height="183"/><a href="https://www.discourse.org/">Discourse</a> is a software package for a discussion forum, and quite nice compared to a number of the alternatives. Discourse is distributed as a Docker container, and strongly recommends using that container not trying to install it any other way. When running by itself on a server, Discourse uses <a href="https://windsock.io/the-docker-proxy/">docker-proxy</a> to forward HTTP and HTTPS connections from the external IP address through to the container. In order to run Discourse on the same server as JupyterHub, we need to remove the docker-proxy and let it be handled by handled by JupyterHub's front-end <a href="https://traefik.io/">Traefik reverse proxy,</a> which is already bound to ports 80 and 443 on a hub server.</p>
<p><img border="0" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7zGspGmcpcRWegaug-8BfFya0Q6i6tsdYvQeExTLgWBHyJQG7xTQJlVb2jbhxOYwmf0ILy4qA0Xein2ynMNwG0-JKI3ygKziGXdBBjYSmMGD4r1QS_Oc22Z6u4PtNC7KkJ2ZhID1daLmN/s400/discourse_jupyterhub_traefik.png" width="339" height="154"/>To run alongside JupyterHub we need to reconfigure Discourse to not use docker-proxy. The docker-proxy passes through SSL to be terminated within the container, while Traefik has to be able to see the URL path component in order to route the request, so we're also moving SSL termination out of Discourse and into Traefik.</p>
<br clear=right/><br clear=left/>
<p>Some searching turned up several articles looked relevant, but did not turn out to be applicable. To save the trouble:</p>
<ul>
<li><a href="https://meta.discourse.org/t/running-other-websites-on-the-same-machine-as-discourse/17247">Running other websites on the same machine as Discourse</a> explains how to set up NGINX as a reverse proxy and use a unix domain socket to communicate from NGINX to Discourse. JupyterHub checks the syntax of the URL configured for its services, I didn't find a way to make a Unix socket work within the JupyterHub Services mechanism.</li>
<li><a href="https://meta.discourse.org/t/discourse-behind-traefik/84874/8">Discourse behind Traefik</a> describes how to create Docker networks via Traefik configuration. Though this might have worked, I found it much easier to use HTTP over the docker0 interface.</li>
</ul>
<p>For bootstrapping, discourse provides a discourse-setup script to ask a few questions and create an app.yml file used to drive construction of the docker container. discourse-setup fails if there is already a webserver on port 80, and I did not find a reasonable alternative to it. In my case, I briefly shut down the JupyterHub server and ran discourse-setup. Running discourse-setup on a separate VM and copying the resulting /var/discourse would likely also work.</p>
<p>Starting from the /var/discourse created by discourse-setup, perform the following steps to make it run as a JupyterHub service.</p>
<ol>
<li>cd /var/discourse</li>
<li>edit containers/app.yml to let Traefik handle the reverse-proxy function. We comment out the external port in the expose section, which will disable docker-proxy and let us handle the reverse proxy function using traefik.
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another
## webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
<span style="background-color: yellow;"># - "80:80" # http
# - "443:443" # https
- "80"</span></pre>
in the "env:" section at the bottom:
<pre style="font-family:monospace;font-size:10px;line-height:1.3em;margin-left:2em;"><span style="background-color: yellow;"> ## TODO: The domain name this Discourse instance will respond to
## Required. Discourse will not work with a bare IP number.
DISCOURSE_HOSTNAME: jupyterhub.example.com
# Running Discourse as a JupyterHub Service
DISCOURSE_RELATIVE_URL_ROOT: /services/discourse</span></pre>
Replace the "run:" section with the recipe to adjust the URL path for /services/discourse:
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">## Any custom commands to run after building
<span style="background-color: yellow;">run:
- exec:
cd: $home
cmd:
- mkdir -p public/services/discourse
- cd public/services/discourse && ln -s ../uploads && ln -s ../backups
- replace:
global: true
filename: /etc/nginx/conf.d/discourse.conf
from: proxy_pass http://discourse;
to: |
rewrite ^/(.*)$ /services/discourse/$1 break;
proxy_pass http://discourse;
- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: etag off;
to: |
etag off;
location /services/discourse {
rewrite ^/services/discourse/?(.*)$ /$1;
}
- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: $proxy_add_x_forwarded_for
to: $http_your_original_ip_header
global: true</span></pre></li>
<li>Run:
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">./launcher rebuild app</pre>
to construct a new docker container.</li>
<li>Add the configuration for a Discourse service to JupyterHub. I'm using <a href="http://tljh.jupyter.org/">The Littlest JupyterHub,</a> where we create a snippet in /opt/tljh/config/jupyterhub_config.d/discourse-service.py.<br/>
Find the IP address to use within the output of "docker inspect app"; look in NetworkSettings for IpAddress and Ports.
<pre style="font-family:monospace;font-size:10px;line-height:1.3em;margin-left:2em;"><span style="background-color: yellow;">c.JupyterHub.services = [
{
'name': 'discourse',
'url': 'http://172.17.0.2:80/',
'api_token': 'no_token',
}
]</span></pre></li>
Then restart JupyterHub with the new configuration:
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">tljh-config reload
tljh-config reload proxy</pre>
</ol>
<br/>
<p>Discourse should now appear on https://jupyterhub.example.com/services/discourse</p>
<p>If something doesn't work, logs can be found in:</p>
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">sudo journalctl --since "1 hour ago" -u jupyterhub
sudo journalctl --since "1 hour ago" -u jupyterhub-proxy
sudo journalctl --since "1 hour ago" -u traefik
/var/discourse/shared/standalone/log/rails/unicorn.stderr.log
/var/discourse/shared/standalone/log/var-log/nginx/access.log</pre>
Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-5405001696418477662019-06-03T07:00:00.000-07:002019-06-03T07:00:05.666-07:00JupyterHub open lab notebook at login<p>Instructions for JupyterHub configuration state that to start JupyterLab by default, one should use a configuration of:</p>
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">c.Spawner.args = ['--NotebookApp.default_url=/lab']</pre>
<p>To start a classic Notebook by default, use:</p>
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">c.Spawner.args = ['--NotebookApp.default_url=/tree']</pre>
<p>To start the classic Notebook and open a specific ipynb file, use:</p>
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">c.Spawner.args = ['--NotebookApp.default_url=/tree/path/to/file.ipynb']</pre>
<p>One might therefore assume that opening /lab/path/to/file.ipynb would open a specific file in JupyterLab, but this does not work and results in an error. The correct configuration is /lab/tree:</p>
<pre style="font-family: monospace; font-size: 10px; line-height: 1.3em; margin-left: 2em;">c.Spawner.args = ['--NotebookApp.default_url=/lab/tree/path/to/file.ipynb']</pre>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-3803843981172278682019-06-01T07:00:00.000-07:002019-10-19T17:16:46.323-07:00JupyterHub OAuth via gitlab.com: setting scopes<p>Recently I set up a <a href="https://jupyter.org/hub">JupyterHub</a> instance, a system for cloud-hosting Jupyter notebooks. JupyterHub supports authentication by a number of different mechanisms. As the code for the notebook is hosted on <a href="https://gitlab.com/">GitLab</a>, I set up OAuth to GitLab as the main authentication mechanism.</p>
<p>Gitlab supports a number of scopes to limit what the granted OAuth token is allowed to do:</p>
<table border=1>
<tr><td style="white-space:nowrap;padding:4px;"><b>api</b></td><td style="padding:4px;">Grants complete read/write access to the API, including all groups and projects.</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>read_user</b></td><td style="padding:4px;">Grants read-only access to the authenticated user's profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users.</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>read_repository</b></td><td style="padding:4px;">Grants read-only access to repositories on private projects using Git-over-HTTP (not using the API).</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>write_repository</b></td><td style="padding:4px;">Grants read-write access to repositories on private projects using Git-over-HTTP (not using the API).</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>read_registry</b></td><td style="padding:4px;">Grants read-only access to container registry images on private projects.</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>sudo</b></td><td style="padding:4px;">Grants permission to perform API actions as any user in the system, when authenticated as an admin user.</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>openid</b></td><td style="padding:4px;">Grants permission to authenticate with GitLab using OpenID Connect. Also gives read-only access to the user's profile and group memberships.</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>profile</b></td><td style="padding:4px;">Grants read-only access to the user's profile data using OpenID Connect.</td></tr>
<tr><td style="white-space:nowrap;padding:4px;"><b>email</b></td><td style="padding:4px;">Grants read-only access to the user's primary email address using OpenID Connect.</td></tr>
</table>
<p>However I found that if I didn't grant api permissions on the gitlab side, the authentication would always fail with "The requested scope is invalid, unknown, or malformed." It appears that the JupyterHub OAuth client was not requesting any specific scope, and that gitlab.com defaults to "api" — which is far too powerful a permission to grant for this purpose, as it allows read/write access to everything when all we really need to know is that the user exists.</p>
<p>Setting the OAuth scope for the JupyterHub client to request turns out to be quite simple to do in the configuration, albeit not documented:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> c.GitLabOAuthenticator.scope = ['read_user']</pre>
<p>A <a href="https://github.com/jupyterhub/oauthenticator/pull/267">pull request to add documentation</a> on this for GitLabOAuthenticator has been submitted.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-13692223471941656312019-05-25T08:09:00.000-07:002019-05-25T08:30:07.418-07:00Adding groupings to TopoJSON files<p><a href="https://geojson.org/">GeoJSON</a> is a structured format for encoding a variety of geographic data structures like land topology, governmental boundaries, etc. It has structures for points, lines, polygons, and discontiguous collections of all of them. GeoJSON has been in use since the late 2000s.</p>
<p><a href="https://github.com/topojson/topojson">TopoJSON</a> is a more recent extension to GeoJSON, which brought a key innovation: when encoding the boundary between two regions, both regions contain a representation of that boundary. Using TopoJSON frequently results in much smaller files by separating out the definition of arcs from the collections of those arcs, allowing adjacent regions to both reference the same data describing the border between them. It also adds delta-encoding where points are encoded as a delta from the previous point, which tends to result in smaller numbers for dense topographical areas. TopoJSON was added as part of <a href="https://d3js.org/">D3.js</a>, an extremely popular 3d visualization JavaScript library, and has thus spread rapidly.</p>
<p>Today's topic is creation of customized TopoJSON files for various purposes. <a href="https://bost.ocks.org/mike/">Mike Bostock,</a> one of the creators of D3, <a href="https://medium.com/@mbostock/command-line-cartography-part-1-897aa8f8ca2c">wrote a series of articles about command line tools available</a> for working with cartographic data. I wanted to develop a visualization of climate model results for regions of the world like Latin America or the Middle East and Africa, and found these articles immensely helpful in creating a TopoJSON file to support this. <a href="https://medium.com/@mbostock/command-line-cartography-part-3-1158e4c55a1e">Part 3, which introduces TopoJSON</a> and the CLI tools to work with it, was especially helpful.</p>
<br/> <br/> <br/>
<h3>Overview</h3>
<p>The overall process we'll cover today is:</p>
<ol>
<li>Annotate existing geometries in a TopoJSON file with a new grouping name.</li>
<li>Merge the annotated geometries to create new groupings.</li>
<li>Remove the original geometries and supporting topology data.</li>
<li>Profit!</li>
</ol>
<br/>
<p>We'll step through this series of commands:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">cat world-countries.json |\
python region_annotate.py |\
topomerge regions=countries1 -k "d.region" |\
topomerge countries1=countries1 -f "false" | toposimplify \
> world_topo_regions.json</pre>
<br/> <br/>
<h3><b>(Step 1)</b> Annotate existing regions: region_annotate.py</h3>
<p>We start from <a href="https://github.com/deldersveld/topojson/blob/master/world-countries.json">world-countries.json</a> provided by <a href="https://github.com/deldersveld">David Eldersveld</a> under an MIT license. The file defines geometry for each country by name and country code:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">"countries1": {
"type": "GeometryCollection",
"geometries": [
{
"arcs": [...<i>etc</i>...
],
"type": "MultiPolygon",
"properties": {
"name": "Argentina",
"Alpha-2": "AR"
},
"id": "ARG"
},</pre>
<br/>
<p>In Python, we create a tool with a mapping table of country names to the regions we want to define:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">region_mapping = {
"Albania": "Eastern Europe",
"Algeria": "Middle East and Africa",
"Argentina": "Latin America",</pre>
<br/>
<p>We read in the JSON, iterate over each country, and add a field for the region it is supposed to be in:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">d = json.load(sys.stdin)
for country in d['objects']['countries1']['geometries']:
name = country['properties']['name']
region = region_mapping[name]
country['region'] = region
json.dump(obj=d, fp=sys.stdout, indent=4)</pre>
<br/>
<p>If one were to examine the JSON at this moment, there would be a new field:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">"countries1": {
"type": "GeometryCollection",
"geometries": [
{
"arcs": [...<i>etc</i>...
],
"type": "MultiPolygon",
"properties": {
"name": "Argentina",
"Alpha-2": "AR"
},
"id": "ARG",
<span style="background-color: yellow;">"region": "Latin America"</span>
},</pre>
<br/> <br/>
<h3><b>(Step 2)</b> Merge annotated regions: topomerge</h3>
<p>topomerge is part of the <a href="https://github.com/topojson/topojson-client">topojson-client</a> package of tools, and exists to manipulate geometries in TopoJSON files. We invoke TopoJSON to create new geometries using the field we just added.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">topomerge regions=countries1 -k "d.region"</pre>
<br/>
<p>The "regions=countries1" argument means to use the source object "countries1" and to target a new "regions" object. The -k argument defines a key to use in creating the target objects, where d is the name of each source object being examined. We're tell it to use the 'region' field we added in step 1.</p>
<p>If we were to examine the JSON at this moment, the original "countries1" collection of objects would be present as well as a new "regions" collection of objects.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">"objects": {
"countries1": {
"type": "GeometryCollection",
"geometries": [
{
"arcs": [...<i>etc</i>...
],
"type": "MultiPolygon",
"properties": {
"name": "Argentina",
"Alpha-2": "AR"
},
"id": "ARG",
"region": "Latin America"
},
<i>...etc, etc...</i>
<span style="background-color: yellow;"> "regions": {
"type": "GeometryCollection",
"geometries": [
{
"type": "MultiPolygon",
"arcs": [...<i>etc</i>...
],
"id": "Latin America"
},</span></pre>
<br/> <br/>
<h3><b>(Step 3)</b> Remove original regions</h3>
<p>As we don't use the individual countries in this application, only regions, we can make the file smaller and the UI more responsive by removing the unneeded geometries. We use topomerge to remove the "countries1" objects:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">topomerge countries1=countries1 -f "false"</pre>
<p>As before, the "countries1=countries1" argument means to use the source object "countries1", and to target the same "countries1" object. We're overwriting it. The -f argument is a filter, which takes a limited JavaScript syntax to examine each object to determine whether to keep it. In our case we're removing all of the objects unconditionally, so we pass in false.</p>
<p>If we were to examine the JSON at this moment, we would see an empty "countries1" collection followed by the "regions" collection we created earlier.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">"objects": {
<span style="background-color: yellow;"> "countries1": {
"type": "GeometryCollection",
"geometries": []
},</span>
"regions": {
"type": "GeometryCollection",
"geometries": [
{
"type": "MultiPolygon",
"arcs": [...<i>etc</i>...
],
"id": "Latin America"
},</pre>
<p>However we're not quite done, as the arcs which define the geometry between all of those countries are still in the file, though not referenced by any object. We use toposimplify, part of the <a href="https://github.com/topojson/topojson-simplify">topojson-simplify</a> package of tools, to remove the unreferenced arcs.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">topomerge countries1=countries1 -f "false" | toposimplify</pre>
<br/> <br/>
<h3><b>(Step 4)</b> Profit!</h3>
<p>That's it. We have a new TopoJSON file defining our regions. Rendered to PNG:</p>
<center><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZcZr70pD3Rfbcd6O3F5plL_LlEm-vlfqSJ64drR1_kYrFiRlwoPZbpiXUkLOl_1RgiPY9INFHn8QeFsp4Ttzjtw7AdVr_FmwTo-z-EO6OQZhJBUzpInO14WaopR3RC7a3wEBXApCq4KSK/s640/equirectangular_topojson.png" width="412" height="310"/></center>
<p>The JSON file viewed using github's gist viewer requires a bit of explanation: the country boundaries seen here are being rendered by github from <a href="https://www.openstreetmap.org/">OpenStreetMap data</a>. The country boundaries are not present in the JSON file we created, only the regional boundaries as seen in the PNG file.</p>
<script src="https://gist.github.com/DentonGentry/f832e120f298c8079caeac3565245390.js"></script>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-30770317067282677352019-05-07T11:21:00.000-07:002019-05-07T11:49:01.541-07:00ipyvolume Frizzle Charts<p><a href="https://github.com/maartenbreddels/ipyvolume">ipyvolume</a> is an extension for <a href="http://jupyter.org">Jupyter notebooks</a> which handles 3D charts and objects. There are several built-in chart types including 3D scatter plots, but those tend to work best for a single large collection of datapoints which span the whole 3D space. Trying to use a scatter plot to chart multiple (though related) series of data didn't work very well, the dots all tended to blend together into a big flock of dots.</p>
<p>Instead, we'll go over a custom chart implemented using a continuous visual element for the series, rather than a discrete dot per datapoint, by creating the requisite triangles and textures. As it uses strips of polygons following a path, we refer to it as a Frizzle Chart. Jumping to the punchline first:</p>
<div style="margin-left: auto; margin-right: auto;">
<!-- Load require.js. Delete this if your page already loads require.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@jupyter-widgets/html-manager@^0.14.0/dist/embed-amd.js" crossorigin="anonymous"></script>
<script type="application/vnd.jupyter.widget-state+json">
{
"version_major": 2,
"version_minor": 0,
"state": {
"953ac6d586b74db0ac9a6249e5579de3": {
"model_name": "VBoxModel",
"model_module": "@jupyter-widgets/controls",
"model_module_version": "1.4.0",
"state": {
"_dom_classes": [],
"children": [
"IPY_MODEL_5ad18a747f0e41e79f9c3a4cca613673"
],
"layout": "IPY_MODEL_c7bc89022b9b4b36ad36cf133ff98020"
}
},
"5ad18a747f0e41e79f9c3a4cca613673": {
"model_name": "FigureModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"_dom_classes": [],
"camera": "IPY_MODEL_109a94e4085e4a49a176bd657fdf2240",
"camera_center": [
0.0,
0.0,
0.0
],
"height": 800,
"layout": "IPY_MODEL_be1ae5b0f04c4a4e905122791940653f",
"matrix_projection": [
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"matrix_world": [
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"meshes": [
"IPY_MODEL_ca7c1f3c1cbf41d7949b02940076561b",
"IPY_MODEL_d8b1e6052f464c4faf5eb9497dd204e5",
"IPY_MODEL_ff8dc979f6454008a1ddd3af185c3c7b",
"IPY_MODEL_03aea76a4bfa471ea0052e349731bbbc",
"IPY_MODEL_cc2ae6f2e0f9474394015dee6de29114",
"IPY_MODEL_f3a3b139912543cca63a8a15b5ffcc0c",
"IPY_MODEL_8aa2d4c6686a4e63a92f633bb04daefb",
"IPY_MODEL_5e66840e51fc4baa9f18e44042276fb8",
"IPY_MODEL_786f40cbad784afebb4f3a467e60ab5b",
"IPY_MODEL_36e5f1d967c64f688bc998838caace92"
],
"scatters": [],
"scene": "IPY_MODEL_ad0c36e8e3c74eb086d498caeab6f035",
"style": {
"axes": {
"visible": true,
"label": {
"color": "black"
},
"ticklabel": {
"color": "black"
},
"color": "black"
},
"box": {
"visible": true
},
"background-color": "white"
},
"volumes": [],
"width": 800,
"xlabel": "Year",
"xlim": [
2012.0,
2062.0
],
"ylabel": "funits",
"ylim": [
0.0,
14599.291612604613
],
"zlabel": "Region",
"zlim": [
-0.5,
10.5
]
}
},
"109a94e4085e4a49a176bd657fdf2240": {
"model_name": "PerspectiveCameraModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"children": [],
"fov": 46.0,
"position": [
-0.09887560216060527,
2.1665770566268576,
-0.3690087708923455
],
"quaternion": [
0.0,
0.0,
0.0,
1.0
],
"scale": [
1.0,
1.0,
1.0
],
"up": [
0.0,
1.0,
0.0
]
}
},
"be1ae5b0f04c4a4e905122791940653f": {
"model_name": "LayoutModel",
"model_module": "@jupyter-widgets/base",
"model_module_version": "1.1.0",
"state": {}
},
"ca7c1f3c1cbf41d7949b02940076561b": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_6952028b82e64805bc2157c8b5485597",
"material": "IPY_MODEL_9f93b4806e354561adf8758406028b1f",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "AEAsRABALESJNmNEimVcRJLdi0Roq4dExBenRH4UokQaQsNEhWa9RNpU4ET8mdlERUj+RGKn9kRPig5FmUMKRRRZHkX3mBlFk4wuRQlQKUXtID9FD2U5RUQSUEVH1ElFuVxhRfGZWkVu/HJFTLJrRcJ2gkWWGX1FDZaLRQhmh0Ur2pRF/GKQRStBnkXGgZlFH8mnRYfAokUWcLFFXR2sRSI0u0VplrVFUxPFRckpv0W7C89FntXIRWkb2UUHmNJFbkDjRSNv3EXceO1FE1nmRcLC90X1U/BFGQ4BRuld+kWeQQZGiDoCRvl6C0bDSwdGMbkQRrdhDEZQ+xVGdHsRRl1AG0YImBZGYYcgRoS2G0ZkzyVG+NUgRm8XK0Zz9SVGiV4wRgUUK0a8ozVGvjAwRg/mOkauSjVGjCRARuRgOkY5XkVGcHI/RiGSSkZifkRGSr9PRsuDSUa+5FRGuIFORoQBWkY7d1NGphRfRmNjWEYrHWRGQEVdRg=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
}
]
},
"6952028b82e64805bc2157c8b5485597": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"9f93b4806e354561adf8758406028b1f": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"d8b1e6052f464c4faf5eb9497dd204e5": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_f380e0e252e44ab7a267f86de05c9a62",
"material": "IPY_MODEL_d723b4892dda40c687ea13921390a992",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "DPLdQwzy3UN9Vv9Af633QBtRkkFl7Y1B6JTmQQqq30FmSB5CyogZQkgaSkIiCkRC/Ld2QjBRb0K0DJJCC6uNQjYbqUJ6CKRCeIPAQve8ukJqQdhCksTRQv9Q8EJdG+lCFFcEQ7ReAENrqhBDY1MMQ34gHUPCaRhDRrcpQ9ufJEO8bDZDtvMwQ9g+Q0NcYz1DlCtQQ9XsSUPoMF1DKY5WQ81MakNhRWNDPX13Q4UQcEMYYIJDnu18Q88JiUNa7YRDwLqPQ+lqi0PpcZZDfu6RQ0QunUMed5hD0O6jQ88Dn0OHsqpDk5OlQ2h4sUNvJaxDbT+4Q2e4skOUBr9DgEu5Q9nMxUO+3b9DOJHMQyRuxkOuUtNDuPvMQzgQ2kN+hdND0cjgQ3kK2kN2e+dDrYngQyQn7kMgAudD18r0Q9Zy7UOMZftD0trzQx/7AEQZOfpD9j0ERFdGAETIegdETGoDRBOxCkTshwZEV+ANRLueCUQQCBFEOa4MRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQAAAgD8AAABAAACAPwAAAEAAAIA/AAAAQA=="
}
]
},
"f380e0e252e44ab7a267f86de05c9a62": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"d723b4892dda40c687ea13921390a992": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"ff8dc979f6454008a1ddd3af185c3c7b": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_9aff1dd52e9b418c973af8e1a61a0188",
"material": "IPY_MODEL_c00a8c70323949fdaf5c532201c6ff2c",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "+FPzP/hT8z+nOQJBC6P8QAiLk0HmHY9BWsLnQXHO4EFE2R5CTxUaQqelSkJTkURCNT53QmLTb0JmTZJCzOmNQqZZqUIKRaRCyb/AQnn3ukK/e9hCJ/3RQnaJ8EIjUulCb3IEQz55AEP0xBBDIG0MQ0A6HUO+ghhDTNApQyG4JEMPhTZDTwsxQ4FWQ0NPej1DmUJQQykDSkNQR11D5KNWQ5xiakOIWmNDdZJ3QxslcENqaoJDpQF9Q9gTiUMW94RDf8SPQ110i0Nde5ZDqveRQ203nUMBgJhDqvejQ2UMn0MRu6pD2pulQ52AsUNlLaxDSke4QwfAskMUDr9DxlK5Q/bTxUOl5L9D7pfMQ6d0xkP1WNNDzwHNQwkW2kMji9NDJc7gQ6QP2kNFgOdDV47gQ2Qr7kNABudDf870Q2J27UOSaPtDwN3zQ0z8AERfO/pDxj4ERCFHAEQ1ewdEtmoDRBixCkTxhwZE7N8NRFOeCUQwBxFEX60MRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQAAAAEAAAEBAAAAAQAAAQEAAAABAAABAQA=="
}
]
},
"9aff1dd52e9b418c973af8e1a61a0188": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"c00a8c70323949fdaf5c532201c6ff2c": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"03aea76a4bfa471ea0052e349731bbbc": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_0053d96777214a61af0c70ccb092ffe9",
"material": "IPY_MODEL_fbba20560afc4386a160e1113414e421",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "9qhCQ/aoQkN9jYVDzouBQ7XbnkOtF5pDR4y4Q/MCs0NAo9JDjlHMQ64k7UNrB+ZDTgoERDwUAESLuxFEUVwNRBWoH0Ts3RpE8tEtRAKbKEQpOzxEi5U2RL/lSkR+z0REu9NZRNFKU0QjB2lEfAliRP6BeERzDXFEKSOERFgsgEQSK4xElPaHRL5ZlERp5o9EL7CcRNL8l0RqL6VEyzqgRHHYrURPoahER6y2RFkxsUTvq79E5eu5RG3YyETv0cJEwzLSRHHky0T2u9tEZyTVRAd15UTMkt5E+l7vRJww6ETTevlE0v7xRMrkAUVp/vtEICYHRS8YA0XugQxF1UoIRbT4EUWllw1F9YoXRRz/EkUyOR1FuIEYRe0DI0X4Hx5Fp+soRVfaI0Xh8C5FVbEpRR4UNUVvpS9F31U7RSK3NUWltkFF7eY7RfI2SEVMNUJFSNdORb6iSEUomFVFwS9PRRR6XEXR3FVFjX1jRW2qXEUVo2pFEpljRQ=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQAAAQEAAAIBAAABAQAAAgEAAAEBAAACAQA=="
}
]
},
"0053d96777214a61af0c70ccb092ffe9": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"fbba20560afc4386a160e1113414e421": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"cc2ae6f2e0f9474394015dee6de29114": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_f827e8afccc04b018300e9c84d33ee88",
"material": "IPY_MODEL_ef7de93f438b438092b0287791379e2a",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "mG6qQJhuqkAcxShB9LQjQdcRg0FzRn5BBpm+QTvhuEG2VQNCHsr+QS1+LULASShCkp9dQoH5VkLHyYlCkKeFQuSZp0K3kqJC9izIQpwrwkLQb+tCqF/kQqOnCEMhjgRDGNwcQ2knGEOvSzJDYPIsQ9TsSEO55UJD8LVgQyn4WUNunXlDYyByQ9zMiUOOqoVDnFCXQ4PGkkMsVaVDa1+gQ8LVs0OgcK5Dks3CQ3v1vEPRN9JDWOnLQ7YP4kOPR9tDdFDyQ3sL60OgegFEdTD7Q6n8CUTs2AVE7qsSRH5FDkQKhhtEntsWRJiIJET6mB9EMrEtRD57KER0/TZEFoAxRPZqQEQxpTpEVPdJRDvoQ0QpoFNE4EZNRA9jXUTPvlZEoD1nRLNNYER4LXFEOvFpRDEwe0QQp3NEsqGCRORsfURXsodEMKCDRNTIjESaj4hE9uORRIaDjUSMApdEynqSRGEjnEQ9dJdEQ0WhRLVunEQBZ6ZECGmhRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQAAAgEAAAKBAAACAQAAAoEAAAIBAAACgQA=="
}
]
},
"f827e8afccc04b018300e9c84d33ee88": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"ef7de93f438b438092b0287791379e2a": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"f3a3b139912543cca63a8a15b5ffcc0c": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_532fd31b08384a19b8924ba9b81204e5",
"material": "IPY_MODEL_1ceae931e7d94996895f797d3f685092",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "ZmaVQWZmlUFZX55BDJ+ZQfnW2UH2TdNBqVwRQkgADUKWWDxCFrI2QqO0bUIPk2ZCGqOSQu08jkJUcbFCkh6sQrIv00LJ2cxC5Mj3QudZ8ELNkw9DIUULQ0SbJEMWqx9DLfA6Q35UNUPjh1JDAzdMQ71Xa0NOSGRDiqqCQwx+fUOgOpBD8uaLQ81WnkPBlplDvfmsQ0nJp0McHrxDXXm2Q5a+y0PUocVD2dXbQ4M91UOPXuxDPkflQ2ZT/UPbufVDhFcHRBdIA0QSNhBEh+ILRLJCGUSoqRREu3oiROOaHUSC2ytEpbMmRF9iNURX8S9Epgw/RGNROUSu10hENdFCRM3AUkQ3bkxEWcVcRNQlVkSp4mZEdvVfRBIWcUSH2mlE61x7RHPSc0RF2oJEpNp9RCINiERC+INEuEWNRL8IiUSygpJEfh2ORLvCl0Q1NZNEfgSdRJlOmESmRqJEX2idRN+Hp0Q8gaJE08asROaXp0QtArJEEqusRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQAAAoEAAAMBAAACgQAAAwEAAAKBAAADAQA=="
}
]
},
"532fd31b08384a19b8924ba9b81204e5": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"1ceae931e7d94996895f797d3f685092": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"8aa2d4c6686a4e63a92f633bb04daefb": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_3d03a1f85d0a42829fd77bdeb458151d",
"material": "IPY_MODEL_e1e6f30fdf5740af82230cf578af3028",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "BmEdQwZhHUPPlUFDE8c7QwbcZENi/l1DkGqEQ5txgEPOu5ZDLDaSQwFdqUNMSKRDa0m8Q2CjtkNMfM9Dz0LJQ+fw4kP/IdxDfaL2Q1Y870MpRgVEnUYBRNJUD0QKCAtE3XoZRCPgFETotSNEnMweRJYDLkQpyyhEiGE4RHzZMkRdzUJESPU8RLhETURCHEdEOMVXRBtMUUSATGJEhoJbRC/YbEQ4vWVE6GV3ROP5b0Sl+YBEOzZ6RPs+hkT5N4JEx4GLRF1Sh0TZwJBEJWmMRAL7lUQoe5FEEi+bREKHlkTZW6BES4ybRCmApUQeiaBE0ZqqRJJ8pUSiqq9EhGWqRGyutETKQq9EAaW5REETtEQvjb5EwNW4RMllw0Qhib1EnS3IRD8swkR948xE8r3GRDqG0UQUPctEoxTWRH+oz0SJjdpEDP/TRLzv3kSVP9hEDjrjRPRo3EROa+dEAXrgREyC60SXceRE2n3vRI9O6ETIXPNEwg/sRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQAAAwEAAAOBAAADAQAAA4EAAAMBAAADgQA=="
}
]
},
"3d03a1f85d0a42829fd77bdeb458151d": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"e1e6f30fdf5740af82230cf578af3028": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"5e66840e51fc4baa9f18e44042276fb8": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_ebcfb017075c4369ae3cacc9cdea7b35",
"material": "IPY_MODEL_6c3f33bd21ba4841aa5ec833c3371fa6",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "7NEFQuzRBUKteCFCk6AcQpbVRkKK3kBCQPpyQi+wa0Kj2ZJC1HGOQqFmr0KNI6pCaArPQlbUyEJGq/FCQWvqQsOXC0OxZwdDvL4fQ+XzGkO1PTVDxs0vQ9MHTEPf6EVDPhBkQ7c4XUMdSn1D2rB1Q0vUi0NooodDaI+ZQxH0lEP5z6dDLceiQ5GPtkOAFbFDxMfFQ9DYv0MlctVD4QrPQ0eI5UN4pd5DvgP2Q1mi7kMObwNESvv+Q3wIDEQH1QdE8MoURDZUEEQ2sx1EE/gYRBa+JkSBvSFEW+gvRGOhKkTOLjlEmqAzRDmOQkQKuDxEZgNMRJPkRUQei1VEGiNPRCoiX0SAcFhEVcVoRKfJYURpcXJEcitrRC4jfETEknREt+uCRH38fUR7xYdEwbKDREWdjERaZYhEfHGRRHsUjUSEQJZElb6RRMIIm0QZYpZEm8ifRHj9mkR0fqREJI+fRLIoqUSNFaREuMWtRCaPqETtU7JEXvqsRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQAA4EAAAABBAADgQAAAAEEAAOBAAAAAQQ=="
}
]
},
"ebcfb017075c4369ae3cacc9cdea7b35": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"6c3f33bd21ba4841aa5ec833c3371fa6": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"786f40cbad784afebb4f3a467e60ab5b": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_e1edc9de013042b79c417522d55b38a3",
"material": "IPY_MODEL_7d56be01fbb647608e31c2c3dcbc0e3e",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "MxNmQzMTZkPuBoFDAVB6Q7h6jUMoPIlDpYGZQ7fmlEPtH6VDxSugQ8hZsENoD6tDbjO7Q7qVtUMXscVD0cK/Q/vWz0PGmslDVKnZQ7Ah00NYLONDp1vcQ0Bk7EPETOVDRVX1Qxz57UOeA/5DyWT2Q8E5A0Tjk/5DllQHREBFA0RqVAtEXCYHRFg7D0RT7wpEfAsTRC6iDkT0xhZE/EASRNpvGkTGzRVESwgeRJpKGURikiFEg7kcRD0QJUSNHCBE94MoRMR1I0Ss7ytENMcmRHlVL0TpEipEebcyRO1aLUTIFzZET6EwRIN4OUQZ6DNExds8RFcxN0SsQ0BEFX86RFKyQ0Rf0z1E1ClHREAwQURNrEpExpdERNs7TkT7C0hEmdpRROyOS0SkilVEpCJPRBZOWUQvyVJEDSddRJqEVkSlF2FE71ZaRPkhZUQ8Ql5EJkhpRItIYkRHjG1E6WtmRHrwcURhrmpE2XZ2RAASb0SBIXtE0phzRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQAAAEEAABBBAAAAQQAAEEEAAABBAAAQQQ=="
}
]
},
"e1edc9de013042b79c417522d55b38a3": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"7d56be01fbb647608e31c2c3dcbc0e3e": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"36e5f1d967c64f688bc998838caace92": {
"model_name": "MeshModel",
"model_module": "ipyvolume",
"model_module_version": "~0.5.1",
"state": {
"line_material": "IPY_MODEL_c631b0c0500a4a32b92ebb72d34133c2",
"material": "IPY_MODEL_f23017c9430f4efd8836ab4b15abfa78",
"texture": [
"data:image/png;base64,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"
],
"triangles": [
{
"dtype": "uint32",
"shape": [
92,
3
]
}
],
"u": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"v": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"x": [
{
"dtype": "int32",
"shape": [
94
]
}
],
"y": [
{
"dtype": "float32",
"shape": [
94
]
}
],
"z": [
{
"dtype": "float32",
"shape": [
94
]
}
]
},
"buffers": [
{
"encoding": "base64",
"path": [
"triangles",
0,
"data"
],
"data": "AAAAAAEAAAADAAAAAAAAAAIAAAADAAAAAgAAAAMAAAAFAAAAAgAAAAQAAAAFAAAABAAAAAUAAAAHAAAABAAAAAYAAAAHAAAABgAAAAcAAAAJAAAABgAAAAgAAAAJAAAACAAAAAkAAAALAAAACAAAAAoAAAALAAAACgAAAAsAAAANAAAACgAAAAwAAAANAAAADAAAAA0AAAAPAAAADAAAAA4AAAAPAAAADgAAAA8AAAARAAAADgAAABAAAAARAAAAEAAAABEAAAATAAAAEAAAABIAAAATAAAAEgAAABMAAAAVAAAAEgAAABQAAAAVAAAAFAAAABUAAAAXAAAAFAAAABYAAAAXAAAAFgAAABcAAAAZAAAAFgAAABgAAAAZAAAAGAAAABkAAAAbAAAAGAAAABoAAAAbAAAAGgAAABsAAAAdAAAAGgAAABwAAAAdAAAAHAAAAB0AAAAfAAAAHAAAAB4AAAAfAAAAHgAAAB8AAAAhAAAAHgAAACAAAAAhAAAAIAAAACEAAAAjAAAAIAAAACIAAAAjAAAAIgAAACMAAAAlAAAAIgAAACQAAAAlAAAAJAAAACUAAAAnAAAAJAAAACYAAAAnAAAAJgAAACcAAAApAAAAJgAAACgAAAApAAAAKAAAACkAAAArAAAAKAAAACoAAAArAAAAKgAAACsAAAAtAAAAKgAAACwAAAAtAAAALAAAAC0AAAAvAAAALAAAAC4AAAAvAAAALgAAAC8AAAAxAAAALgAAADAAAAAxAAAAMAAAADEAAAAzAAAAMAAAADIAAAAzAAAAMgAAADMAAAA1AAAAMgAAADQAAAA1AAAANAAAADUAAAA3AAAANAAAADYAAAA3AAAANgAAADcAAAA5AAAANgAAADgAAAA5AAAAOAAAADkAAAA7AAAAOAAAADoAAAA7AAAAOgAAADsAAAA9AAAAOgAAADwAAAA9AAAAPAAAAD0AAAA/AAAAPAAAAD4AAAA/AAAAPgAAAD8AAABBAAAAPgAAAEAAAABBAAAAQAAAAEEAAABDAAAAQAAAAEIAAABDAAAAQgAAAEMAAABFAAAAQgAAAEQAAABFAAAARAAAAEUAAABHAAAARAAAAEYAAABHAAAARgAAAEcAAABJAAAARgAAAEgAAABJAAAASAAAAEkAAABLAAAASAAAAEoAAABLAAAASgAAAEsAAABNAAAASgAAAEwAAABNAAAATAAAAE0AAABPAAAATAAAAE4AAABPAAAATgAAAE8AAABRAAAATgAAAFAAAABRAAAAUAAAAFEAAABTAAAAUAAAAFIAAABTAAAAUgAAAFMAAABVAAAAUgAAAFQAAABVAAAAVAAAAFUAAABXAAAAVAAAAFYAAABXAAAAVgAAAFcAAABZAAAAVgAAAFgAAABZAAAAWAAAAFkAAABbAAAAWAAAAFoAAABbAAAAWgAAAFsAAABdAAAAWgAAAFwAAABdAAAA"
},
{
"encoding": "base64",
"path": [
"u",
0,
"data"
],
"data": "AAAAAAAAAABBTK48QUyuPEFMLj1BTC49MbmCPTG5gj1BTK49QUyuPVLf2T1S39k9MbkCPjG5Aj65ghg+uYIYPkFMLj5BTC4+yhVEPsoVRD5S31k+Ut9ZPtqobz7aqG8+MbmCPjG5gj71nY0+9Z2NPrmCmD65gpg+fWejPn1noz5BTK4+QUyuPgUxuT4FMbk+yhXEPsoVxD6O+s4+jvrOPlLf2T5S39k+FsTkPhbE5D7aqO8+2qjvPp6N+j6ejfo+MbkCPzG5Aj+TKwg/kysIP/WdDT/1nQ0/VxATP1cQEz+5ghg/uYIYPxv1HT8b9R0/fWcjP31nIz/f2Sg/39koP0FMLj9BTC4/o74zP6O+Mz8FMTk/BTE5P2ejPj9noz4/yhVEP8oVRD8siEk/LIhJP476Tj+O+k4/8GxUP/BsVD9S31k/Ut9ZP7RRXz+0UV8/FsRkPxbEZD94Nmo/eDZqP9qobz/aqG8/PBt1PzwbdT+ejXo/no16Pw=="
},
{
"encoding": "base64",
"path": [
"v",
0,
"data"
],
"data": "AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPw=="
},
{
"encoding": "base64",
"path": [
"x",
0,
"data"
],
"data": "3gcAAN4HAADfBwAA3wcAAOAHAADgBwAA4QcAAOEHAADiBwAA4gcAAOMHAADjBwAA5AcAAOQHAADlBwAA5QcAAOYHAADmBwAA5wcAAOcHAADoBwAA6AcAAOkHAADpBwAA6gcAAOoHAADrBwAA6wcAAOwHAADsBwAA7QcAAO0HAADuBwAA7gcAAO8HAADvBwAA8AcAAPAHAADxBwAA8QcAAPIHAADyBwAA8wcAAPMHAAD0BwAA9AcAAPUHAAD1BwAA9gcAAPYHAAD3BwAA9wcAAPgHAAD4BwAA+QcAAPkHAAD6BwAA+gcAAPsHAAD7BwAA/AcAAPwHAAD9BwAA/QcAAP4HAAD+BwAA/wcAAP8HAAAACAAAAAgAAAEIAAABCAAAAggAAAIIAAADCAAAAwgAAAQIAAAECAAABQgAAAUIAAAGCAAABggAAAcIAAAHCAAACAgAAAgIAAAJCAAACQgAAAoIAAAKCAAACwgAAAsIAAAMCAAADAgAAA=="
},
{
"encoding": "base64",
"path": [
"y",
0,
"data"
],
"data": "WuQ3Q1rkN0MtYkhDO19CQ6zMXUNAJVdD3Cp0Q6fXbEOot4VDtbSBQ07GkUPCZo1DqjqeQ3d7mUMFDqtDUuylQ6k5uEPPsrJD37bFQ23Iv0PxftNDpybNQymL4UP8xtpD0dTvQ+mi6EMyVf5D67P2Q8uCBkS/eQJEo+8NRJGtCUTGbRVEKfIQRNn5HERGRBhEgZAkRKagH0RiLixECAQnRCHQM0Qray5EZHI7RM3SNUTPEUNErTc9RAerSkSJlkREsDpSRCHsS0RwvVlEMjVTROwvYUR8blpEx45oRLyUYUSo1m9EsqRoRDIEd0Qcm29ECxR+RLl0dkRsgYJERy59RJ7mhURD4oFE7zeJRBkahUSyc4xEBj2IRDeYj0RpSYtE0qOSRKA9jkTWlJVEDRiRRJRpmEQN15NEXyCbRAB5lkSKt51ERvyYRGctoEQ9X5tESICiREWgnUR/rqREvr2fRGC2pkQGtqFEPJaoRH2Ho0RnTKpEgjClRA=="
},
{
"encoding": "base64",
"path": [
"z",
0,
"data"
],
"data": "AAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQAAEEEAACBBAAAQQQAAIEEAABBBAAAgQQ=="
}
]
},
"c631b0c0500a4a32b92ebb72d34133c2": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"uniforms": {}
}
},
"f23017c9430f4efd8836ab4b15abfa78": {
"model_name": "ShaderMaterialModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"clippingPlanes": [],
"defines": null,
"extensions": {},
"side": "DoubleSide",
"uniforms": {}
}
},
"ad0c36e8e3c74eb086d498caeab6f035": {
"model_name": "SceneModel",
"model_module": "jupyter-threejs",
"model_module_version": "^2.0.3",
"state": {
"background": null,
"children": [],
"fog": null,
"overrideMaterial": null,
"quaternion": [
0.0,
0.0,
0.0,
1.0
],
"scale": [
1.0,
1.0,
1.0
],
"up": [
0.0,
1.0,
0.0
]
}
},
"c7bc89022b9b4b36ad36cf133ff98020": {
"model_name": "LayoutModel",
"model_module": "@jupyter-widgets/base",
"model_module_version": "1.1.0",
"state": {}
}
}
}
</script>
<script type="application/vnd.jupyter.widget-view+json">
{"version_major": 2, "version_minor": 0, "model_id": "953ac6d586b74db0ac9a6249e5579de3"}
</script>
</div>
<p>The chart is generated from a Pandas DataFrame, where each column is turned into one of the frizzle strips. Walking through the code which builds the chart:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">def get_frizzle_chart(df, ylabel, size=None, key=None):
"""Returns a 3D Frizz chart, one frizzle strip per column in the dataframe.
Arguments:
df: the DataFrame to graph.
ylabel: text label to place on the Y axis.
size: in integer pixels
Returns:
an ipywidget
"""
(width, height) = (size, size) if size is not None else (500, 500)
</pre>
<br/>
<p>We start by calling figure(), to create a new container to hold a chart. ipyvolume follows a pattern established by <a href="https://matplotlib.org">matplotlib</a>, wherein commands are executed in an immediate mode and implicitly join a container which holds all such commands, as opposed to explicitly creating a chart object and calling methods on that object. We also create a list of colors to use for each frizzle strip.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> ipv.figure(width=width, height=height, key=key, controls=True)
color = [(161,222,240), (56,116,114), (16,237,220), (28,69,133), (238,128,254),
(180,39,183), (92,130,210), (22,66,205), (228,204,241), (138,68,136),
(134,202,98), (35,137,16), (68,242,112), (106,127,47), (237,212,94),
(103,61,23), (251,120,16), (180,39,32), (253,108,160), (184,114,90)]
</pre>
<br/>
<p>We create strips of triangles, one for each column in the DataFrame. Each data point in the dataframe determines the Y-axis height of the vertices for the triangle at that point. The row index of the dataframe becomes the X-axis position. The columns turn into the Z-axis, one after another.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> # Draw a strip of triangles for each region, tracing the dataframe values
for (z, region) in enumerate(df.columns):
years = list(df.index)
nyears = len(years)
year = years.pop(0)
X = [year, year]
y = df.loc[year, region]
Y = [y, y]
Z = [float(z), float(z) + 1.0]
</pre>
<br/>
<p>In graphics programming, [U, V] coordinates are offsets within a texture map. We are specifying that [X, Y, Z] in the 3D space corresponds to [U, V] in the texture. When applying a texture to the frizzle strips it will interpolate between the points where we've specified [U, V].</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> U = [0.0, 0.0]
V = [0.0, 1.0]
triangles = []
offset = 2
for (idx, year) in enumerate(years, 1):
X.extend([year, year])
y = df.loc[year, region]
Y.extend([y, y * 0.97])
Z.extend([float(z), float(z) + 1.0])
u = float(idx) / nyears
U.extend([u, u])
V.extend([0.0, 1.0])
triangles.extend([[offset-2, offset-1, offset+1], [offset-2, offset, offset+1]])
offset += 2
</pre>
<br/>
<p>ipyvolume does not have a way to provide descriptive tick labels on the axes. In our case, the Z axis represents different regions of the world like "OECD90" and "Latin America," but the axis will be labelled with with the numbers zero through nine. We use the <a href="https://pillow.readthedocs.io/en/stable/">Python Imaging Library</a> to create a texture to be mapped to each frizzle strip, giving the name of the column from the original DataFrame.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> img = PIL.Image.new(mode='RGB', size=(1000, 100), color=color[z])
draw = PIL.ImageDraw.Draw(img)
font = PIL.ImageFont.truetype(os.path.join('data', 'fonts', 'Roboto-Medium.ttf'), 90)
draw.text(xy=(100, 0), text=region, fill=(255,0,0), font=font)
ipv.pylab.plot_trisurf(np.array(X), np.array(Y), np.array(Z), triangles=triangles,
u=U, v=V, texture=img.transpose(PIL.Image.FLIP_TOP_BOTTOM))
</pre>
<br/>
<p>We set up labels for the axes and position the camera to view the completed scene. We position the camera twice to work around what appears to be a bug: the tick marks on each axis initially appear all bunched up together at the middle, and only move to their proper locations the first time the viewport is changed.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> ipv.style.box_on()
ipv.pylab.xlabel('Year')
first_year = df.index[0]
last_year = df.index[-1]
ipv.pylab.xlim(first_year - 2, last_year + 2)
ipv.pylab.ylabel(ylabel)
ipv.pylab.zlabel('Region')
nregions = len(df.columns)
ipv.pylab.zlim(-0.5, nregions + 0.5)
ipv.pylab.view(10.0, 10.0, 3.0)
ipv.pylab.view(-165.0, 80.0, 2.2)
</pre>
<br/>
<p>Finally, we return the widget containing the frizzle graph. gcc() is "get current container," which was allocated when we called figure() at the top of the routine.</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;"> return ipv.gcc()
</pre>
<p>For convenience, the complete routine without commentary is reproduced at the bottom of the post.</p>
<br/>
<hr/>
<br/>
<p>For reference, this is the DataFrame which generated the Frizzle Chart shown at the top of the post.</p>
<div>
<style>
h2 {
text-align: center;
font-family: Helvetica, Arial, sans-serif;
}
table {
margin-left: auto;
margin-right: auto;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 1px;
text-align: center;
font-family: Helvetica, Arial, sans-serif;
font-size: 70%;
}
table tbody tr:hover {
background-color: #dddddd;
}
.wide {
width: 90%;
}
</style>
<table border="1" class="dataframe wide">
<thead>
<tr style="text-align: right;">
<th>Year</th>
<th>World</th>
<th>OECD90</th>
<th>Eastern Europe</th>
<th>Asia (Sans Japan)</th>
<th>Middle East and Africa</th>
<th>Latin America</th>
<th>China</th>
<th>India</th>
<th>EU</th>
<th>USA</th>
</tr>
</thead>
<tbody>
<tr>
<th>2014</th>
<td>22548.3</td>
<td>9630.9</td>
<td>2021.8</td>
<td>8068.1</td>
<td>1750.3</td>
<td>1681.6</td>
<td>5262.8</td>
<td>1324.9</td>
<td>3379.6</td>
<td>4226.1</td>
</tr>
<tr>
<th>2015</th>
<td>24255.9</td>
<td>9686.1</td>
<td>2046.1</td>
<td>8517.3</td>
<td>1813.4</td>
<td>1729.4</td>
<td>5577.5</td>
<td>1407.8</td>
<td>3402.9</td>
<td>4238.2</td>
</tr>
<tr>
<th>2016</th>
<td>25118.0</td>
<td>9726.6</td>
<td>2070.4</td>
<td>8971.8</td>
<td>1887.4</td>
<td>1782.4</td>
<td>5868.3</td>
<td>1508.6</td>
<td>3423.0</td>
<td>4238.1</td>
</tr>
<tr>
<th>2017</th>
<td>25980.0</td>
<td>9770.9</td>
<td>2095.8</td>
<td>9419.6</td>
<td>1964.8</td>
<td>1838.0</td>
<td>6148.2</td>
<td>1613.2</td>
<td>3443.2</td>
<td>4240.9</td>
</tr>
<tr>
<th>2018</th>
<td>26841.8</td>
<td>9818.8</td>
<td>2122.1</td>
<td>9861.1</td>
<td>2045.6</td>
<td>1896.1</td>
<td>6417.4</td>
<td>1721.5</td>
<td>3463.3</td>
<td>4246.4</td>
</tr>
<tr>
<th>2019</th>
<td>27703.5</td>
<td>9870.2</td>
<td>2149.3</td>
<td>10296.7</td>
<td>2130.0</td>
<td>1956.8</td>
<td>6676.3</td>
<td>1833.5</td>
<td>3483.5</td>
<td>4254.5</td>
</tr>
<tr>
<th>2020</th>
<td>28565.2</td>
<td>9925.0</td>
<td>2177.4</td>
<td>10726.8</td>
<td>2218.1</td>
<td>2019.9</td>
<td>6925.0</td>
<td>1949.2</td>
<td>3503.9</td>
<td>4265.2</td>
</tr>
<tr>
<th>2021</th>
<td>29426.8</td>
<td>9983.0</td>
<td>2206.3</td>
<td>11151.8</td>
<td>2310.0</td>
<td>2085.4</td>
<td>7164.0</td>
<td>2068.5</td>
<td>3524.5</td>
<td>4278.2</td>
</tr>
<tr>
<th>2022</th>
<td>30288.3</td>
<td>10044.2</td>
<td>2235.9</td>
<td>11572.1</td>
<td>2405.8</td>
<td>2153.3</td>
<td>7393.5</td>
<td>2191.4</td>
<td>3545.3</td>
<td>4293.6</td>
</tr>
<tr>
<th>2023</th>
<td>31149.9</td>
<td>10108.3</td>
<td>2266.3</td>
<td>11988.2</td>
<td>2505.7</td>
<td>2223.6</td>
<td>7613.7</td>
<td>2317.8</td>
<td>3566.4</td>
<td>4311.3</td>
</tr>
<tr>
<th>2024</th>
<td>32011.6</td>
<td>10175.3</td>
<td>2297.3</td>
<td>12400.3</td>
<td>2609.7</td>
<td>2296.1</td>
<td>7825.0</td>
<td>2447.7</td>
<td>3587.9</td>
<td>4331.0</td>
</tr>
<tr>
<th>2025</th>
<td>32873.3</td>
<td>10245.0</td>
<td>2329.0</td>
<td>12808.9</td>
<td>2718.0</td>
<td>2370.9</td>
<td>8027.6</td>
<td>2581.1</td>
<td>3609.8</td>
<td>4352.9</td>
</tr>
<tr>
<th>2026</th>
<td>33735.1</td>
<td>10317.4</td>
<td>2361.2</td>
<td>13214.4</td>
<td>2830.7</td>
<td>2447.9</td>
<td>8221.8</td>
<td>2717.8</td>
<td>3632.1</td>
<td>4376.7</td>
</tr>
<tr>
<th>2027</th>
<td>34597.1</td>
<td>10392.2</td>
<td>2393.9</td>
<td>13617.2</td>
<td>2947.8</td>
<td>2527.1</td>
<td>8407.9</td>
<td>2858.0</td>
<td>3655.0</td>
<td>4402.3</td>
</tr>
<tr>
<th>2028</th>
<td>35459.2</td>
<td>10469.4</td>
<td>2427.2</td>
<td>14017.7</td>
<td>3069.7</td>
<td>2608.4</td>
<td>8586.1</td>
<td>3001.4</td>
<td>3678.5</td>
<td>4429.7</td>
</tr>
<tr>
<th>2029</th>
<td>36321.6</td>
<td>10548.8</td>
<td>2460.8</td>
<td>14416.3</td>
<td>3196.2</td>
<td>2691.7</td>
<td>8756.8</td>
<td>3148.1</td>
<td>3702.6</td>
<td>4458.8</td>
</tr>
<tr>
<th>2030</th>
<td>37184.1</td>
<td>10630.4</td>
<td>2494.9</td>
<td>14813.4</td>
<td>3327.6</td>
<td>2777.1</td>
<td>8920.3</td>
<td>3298.0</td>
<td>3727.3</td>
<td>4489.4</td>
</tr>
<tr>
<th>2031</th>
<td>38047.0</td>
<td>10713.9</td>
<td>2529.2</td>
<td>15209.3</td>
<td>3463.9</td>
<td>2864.5</td>
<td>9076.7</td>
<td>3451.2</td>
<td>3752.9</td>
<td>4521.5</td>
</tr>
<tr>
<th>2032</th>
<td>38910.2</td>
<td>10799.2</td>
<td>2563.9</td>
<td>15604.5</td>
<td>3605.4</td>
<td>2953.9</td>
<td>9226.4</td>
<td>3607.4</td>
<td>3779.2</td>
<td>4555.0</td>
</tr>
<tr>
<th>2033</th>
<td>39773.7</td>
<td>10886.3</td>
<td>2598.8</td>
<td>15999.4</td>
<td>3752.0</td>
<td>3045.2</td>
<td>9369.7</td>
<td>3766.8</td>
<td>3806.4</td>
<td>4589.8</td>
</tr>
<tr>
<th>2034</th>
<td>40637.5</td>
<td>10975.0</td>
<td>2633.9</td>
<td>16394.4</td>
<td>3903.9</td>
<td>3138.3</td>
<td>9506.9</td>
<td>3929.3</td>
<td>3834.5</td>
<td>4625.8</td>
</tr>
<tr>
<th>2035</th>
<td>41501.8</td>
<td>11065.1</td>
<td>2669.1</td>
<td>16789.9</td>
<td>4061.3</td>
<td>3233.3</td>
<td>9638.2</td>
<td>4094.7</td>
<td>3863.5</td>
<td>4662.9</td>
</tr>
<tr>
<th>2036</th>
<td>42366.5</td>
<td>11156.6</td>
<td>2704.4</td>
<td>17186.2</td>
<td>4224.2</td>
<td>3330.1</td>
<td>9763.9</td>
<td>4263.1</td>
<td>3893.6</td>
<td>4700.9</td>
</tr>
<tr>
<th>2037</th>
<td>43231.6</td>
<td>11249.3</td>
<td>2739.8</td>
<td>17583.8</td>
<td>4392.8</td>
<td>3428.6</td>
<td>9884.3</td>
<td>4434.5</td>
<td>3924.8</td>
<td>4739.9</td>
</tr>
<tr>
<th>2038</th>
<td>44097.3</td>
<td>11343.0</td>
<td>2775.2</td>
<td>17983.0</td>
<td>4567.1</td>
<td>3528.8</td>
<td>9999.7</td>
<td>4608.8</td>
<td>3957.1</td>
<td>4779.7</td>
</tr>
<tr>
<th>2039</th>
<td>44963.4</td>
<td>11437.8</td>
<td>2810.5</td>
<td>18384.3</td>
<td>4747.4</td>
<td>3630.7</td>
<td>10110.4</td>
<td>4785.9</td>
<td>3990.6</td>
<td>4820.2</td>
</tr>
<tr>
<th>2040</th>
<td>45830.2</td>
<td>11533.3</td>
<td>2845.7</td>
<td>18788.1</td>
<td>4933.6</td>
<td>3734.2</td>
<td>10216.6</td>
<td>4965.8</td>
<td>4025.3</td>
<td>4861.3</td>
</tr>
<tr>
<th>2041</th>
<td>46697.5</td>
<td>11629.6</td>
<td>2880.8</td>
<td>19194.7</td>
<td>5125.9</td>
<td>3839.2</td>
<td>10318.6</td>
<td>5148.5</td>
<td>4061.3</td>
<td>4903.0</td>
</tr>
<tr>
<th>2042</th>
<td>47565.5</td>
<td>11726.5</td>
<td>2915.6</td>
<td>19604.5</td>
<td>5324.5</td>
<td>3945.9</td>
<td>10416.7</td>
<td>5333.9</td>
<td>4098.7</td>
<td>4945.0</td>
</tr>
<tr>
<th>2043</th>
<td>48434.1</td>
<td>11823.8</td>
<td>2950.3</td>
<td>20018.0</td>
<td>5529.4</td>
<td>4053.9</td>
<td>10511.2</td>
<td>5521.9</td>
<td>4137.4</td>
<td>4987.5</td>
</tr>
<tr>
<th>2044</th>
<td>49303.3</td>
<td>11921.4</td>
<td>2984.6</td>
<td>20435.6</td>
<td>5740.8</td>
<td>4163.5</td>
<td>10602.4</td>
<td>5712.6</td>
<td>4177.7</td>
<td>5030.1</td>
</tr>
<tr>
<th>2045</th>
<td>50173.4</td>
<td>12019.2</td>
<td>3018.7</td>
<td>20857.6</td>
<td>5958.8</td>
<td>4274.5</td>
<td>10690.5</td>
<td>5905.9</td>
<td>4219.4</td>
<td>5072.9</td>
</tr>
<tr>
<th>2046</th>
<td>51044.1</td>
<td>12117.1</td>
<td>3052.3</td>
<td>21284.5</td>
<td>6183.5</td>
<td>4386.8</td>
<td>10775.9</td>
<td>6101.8</td>
<td>4262.8</td>
<td>5115.7</td>
</tr>
<tr>
<th>2047</th>
<td>51915.6</td>
<td>12215.0</td>
<td>3085.5</td>
<td>21716.6</td>
<td>6414.9</td>
<td>4500.4</td>
<td>10858.8</td>
<td>6300.1</td>
<td>4307.7</td>
<td>5158.5</td>
</tr>
<tr>
<th>2048</th>
<td>52788.0</td>
<td>12312.6</td>
<td>3118.2</td>
<td>22154.3</td>
<td>6653.3</td>
<td>4615.3</td>
<td>10939.4</td>
<td>6501.0</td>
<td>4354.4</td>
<td>5201.2</td>
</tr>
<tr>
<th>2049</th>
<td>53661.2</td>
<td>12410.0</td>
<td>3150.4</td>
<td>22598.1</td>
<td>6898.8</td>
<td>4731.5</td>
<td>11018.2</td>
<td>6704.2</td>
<td>4402.8</td>
<td>5243.6</td>
</tr>
<tr>
<th>2050</th>
<td>54535.3</td>
<td>12506.9</td>
<td>3182.0</td>
<td>23048.3</td>
<td>7151.4</td>
<td>4848.9</td>
<td>11095.2</td>
<td>6909.8</td>
<td>4452.9</td>
<td>5285.6</td>
</tr>
<tr>
<th>2051</th>
<td>55410.3</td>
<td>12603.3</td>
<td>3213.0</td>
<td>23505.3</td>
<td>7411.2</td>
<td>4967.4</td>
<td>11171.0</td>
<td>7117.8</td>
<td>4505.0</td>
<td>5327.3</td>
</tr>
<tr>
<th>2052</th>
<td>56286.2</td>
<td>12698.9</td>
<td>3243.3</td>
<td>23969.5</td>
<td>7678.5</td>
<td>5087.0</td>
<td>11245.6</td>
<td>7328.0</td>
<td>4558.9</td>
<td>5368.4</td>
</tr>
<tr>
<th>2053</th>
<td>57163.1</td>
<td>12793.8</td>
<td>3272.9</td>
<td>24441.4</td>
<td>7953.3</td>
<td>5207.7</td>
<td>11319.4</td>
<td>7540.5</td>
<td>4614.8</td>
<td>5408.9</td>
</tr>
<tr>
<th>2054</th>
<td>58041.0</td>
<td>12887.7</td>
<td>3301.8</td>
<td>24921.3</td>
<td>8235.6</td>
<td>5329.4</td>
<td>11392.8</td>
<td>7755.2</td>
<td>4672.7</td>
<td>5448.7</td>
</tr>
<tr>
<th>2055</th>
<td>58920.0</td>
<td>12980.5</td>
<td>3329.8</td>
<td>25409.6</td>
<td>8525.7</td>
<td>5452.2</td>
<td>11465.8</td>
<td>7972.1</td>
<td>4732.6</td>
<td>5487.7</td>
</tr>
<tr>
<th>2056</th>
<td>59800.0</td>
<td>13072.1</td>
<td>3357.0</td>
<td>25906.8</td>
<td>8823.7</td>
<td>5575.8</td>
<td>11539.0</td>
<td>8191.1</td>
<td>4794.7</td>
<td>5525.8</td>
</tr>
<tr>
<th>2057</th>
<td>60681.1</td>
<td>13162.5</td>
<td>3383.2</td>
<td>26413.1</td>
<td>9129.6</td>
<td>5700.4</td>
<td>11612.4</td>
<td>8412.1</td>
<td>4859.0</td>
<td>5562.8</td>
</tr>
<tr>
<th>2058</th>
<td>61563.4</td>
<td>13251.3</td>
<td>3408.5</td>
<td>26929.1</td>
<td>9443.6</td>
<td>5825.8</td>
<td>11686.5</td>
<td>8635.3</td>
<td>4925.5</td>
<td>5598.8</td>
</tr>
<tr>
<th>2059</th>
<td>62446.8</td>
<td>13338.6</td>
<td>3432.8</td>
<td>27455.1</td>
<td>9765.8</td>
<td>5952.0</td>
<td>11761.4</td>
<td>8860.4</td>
<td>4994.3</td>
<td>5633.6</td>
</tr>
<tr>
<th>2060</th>
<td>63331.4</td>
<td>13424.2</td>
<td>3456.0</td>
<td>27991.4</td>
<td>10096.3</td>
<td>6079.1</td>
<td>11837.5</td>
<td>9087.4</td>
<td>5065.5</td>
<td>5667.1</td>
</tr>
</tbody>
</table>
</div>
<br/>
<hr/>
<br/>
<p>The code without commentary:</p>
<pre style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">def get_frizzle_chart(df, ylabel, size=None, key=None):
"""Returns a 3D Frizz chart, one frizzle strip per column in the dataframe.
Arguments:
df: the DataFrame to graph.
ylabel: text label to place on the Y axis.
size: in integer pixels
Returns:
an ipywidget
"""
(width, height) = (size, size) if size is not None else (500, 500)
ipv.figure(width=width, height=height, key=key, controls=True)
color = [(161,222,240), (56,116,114), (16,237,220), (28,69,133), (238,128,254),
(180,39,183), (92,130,210), (22,66,205), (228,204,241), (138,68,136),
(134,202,98), (35,137,16), (68,242,112), (106,127,47), (237,212,94),
(103,61,23), (251,120,16), (180,39,32), (253,108,160), (184,114,90)]
# Draw a strip of triangles for each region, tracing the dataframe values
for (z, region) in enumerate(df.columns):
years = list(df.index)
nyears = len(years)
year = years.pop(0)
X = [year, year]
y = df.loc[year, region]
Y = [y, y]
Z = [float(z), float(z) + 1.0]
U = [0.0, 0.0]
V = [0.0, 1.0]
triangles = []
offset = 2
for (idx, year) in enumerate(years, 1):
X.extend([year, year])
y = df.loc[year, region]
Y.extend([y, y * 0.97])
Z.extend([float(z), float(z) + 1.0])
u = float(idx) / nyears
U.extend([u, u])
V.extend([0.0, 1.0])
triangles.extend([[offset-2, offset-1, offset+1], [offset-2, offset, offset+1]])
offset += 2
img = PIL.Image.new(mode='RGB', size=(1000, 100), color=color[z])
draw = PIL.ImageDraw.Draw(img)
font = PIL.ImageFont.truetype(os.path.join('data', 'fonts', 'Roboto-Medium.ttf'), 90)
draw.text(xy=(100, 0), text=region, fill=(255,0,0), font=font)
ipv.pylab.plot_trisurf(np.array(X), np.array(Y), np.array(Z), triangles=triangles,
u=U, v=V, texture=img.transpose(PIL.Image.FLIP_TOP_BOTTOM))
ipv.style.box_on()
ipv.pylab.xlabel('Year')
first_year = df.index[0]
last_year = df.index[-1]
ipv.pylab.xlim(first_year - 2, last_year + 2)
ipv.pylab.ylabel(ylabel)
ipv.pylab.zlabel('Region')
nregions = len(df.columns)
ipv.pylab.zlim(-0.5, nregions + 0.5)
ipv.pylab.view(10.0, 10.0, 3.0)
ipv.pylab.view(-165.0, 80.0, 2.2)
return ipv.gcc()
</pre>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-28946477351201638212019-03-31T08:04:00.000-07:002019-05-07T11:21:23.517-07:00Vega tooltips and format()<p>This took me an inordinately long time to figure out, so I'll document it here. When writing a <a href="https://vega.github.io/vega/">Vega description</a> of a chart and including a tooltip, the accessor methods for datum cannot be used inside of <a href="https://github.com/vega/vega/wiki/Expressions">format()</a>. For example, this doesn't work (it always displays 'NaN'):</p>
<div style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">"tooltip": {"signal": "{title: datum.​name, 'CO2eq': format(<b>datum.​size</b>, '.​2f') + ' Gigatons'}"}</div>
<p>This does:</p>
<div style="font-family: monospace; font-size: 11px; line-height: 1.3em; margin-left: 2em;">"tooltip": {"signal": "{title: datum.​name, 'CO2eq': format(<b>datum['size']</b>, '.​2f') + ' Gigatons'}"}</div>
<p>Note the difference inside the format(), using datum['size'] instead of datum.size.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-1243235748294863282019-03-14T20:27:00.000-07:002019-08-09T11:25:58.284-07:00Vega Visualization Grammar and Jupyter notebooks<p>In the <a href="https://codingrelic.geekhold.com/2019/02/line-graphs-in-jupyterlab.html">previous post about charting options</a> for <a href="https://jupyter.org/">Jupyter Notebooks</a>, the <a href="https://mybinder.org/v2/gh/DentonGentry/blog-posts/master?urlpath=lab/tree/LineGraphs.ipynb">container to run the Notebook</a> had to include a number of extensions for JupyterLab to enable the various charting packages to work. <a href="https://github.com/jupyterlab">JupyterLab, the next major version</a> of Juypter Notebooks, locks down JavaScript within the Notebook web environment and requires extensions to facilitate it for each package.</p>
<pre style="font-family: monospace; font-size: medium; line-height: 1.3em; margin-left: 3em;">jupyter labextension install jupyter-matplotlib
jupyter labextension install bqplot
jupyter labextension install jupyterlab_bokeh
jupyter labextension install beakerx-jupyterlab
jupyter labextension install @pyviz/jupyterlab_pyviz
jupyter labextension install @jupyterlab/plotly-extension
</pre>
<p>All except one charting package required an extension, that is. The one which doesn't is <a href="https://altair-viz.github.io/">Altair</a>, which works not by generating JavaScript but by generating a <a href="https://vega.github.io/vega/">Vega-Lite</a> description of the desired chart. Vega is a visualization grammar, a declarative language for describing visualization. For example, consider the first few lines of a <a href="https://vega.github.io/vega/examples/bar-chart/">bar chart example from the Vega site</a>:</p>
<pre style="font-family: monospace; font-size: medium; line-height: 1.3em; margin-left: 3em;">{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 200,
"padding": 5,
"data": [
{
"name": "table",
"values": [
{"category": "A", "amount": 28},
{"category": "B", "amount": 55},
{"category": "C", "amount": 43},
{"category": "D", "amount": 91},
{"category": "E", "amount": 81},
{"category": "F", "amount": 53},
{"category": "G", "amount": 19},
{"category": "H", "amount": 87}
]
}
],
</pre>
<p>JupyterLab includes a renderer for <a href="https://vega.github.io/vega-lite/">Vega-Lite</a> and <a href="https://vega.github.io/vega/">Vega</a>. A Vega description can be passed to JupyterLab's display() routine, and will render graphically in the Notebook. This means we can write code <i>within the Notebook</i> to generate a Vega description, and then render it, without requiring any extension to be installed.</p>
<p>As one example: consider an interactive treemap. None of the charting packages <a href="https://codingrelic.geekhold.com/2019/02/line-graphs-in-jupyterlab.html">investigated earlier</a> had a treemap implementation which I really liked, but the Vega grammar supports one. Using Python code running within the Notebook, we can generate one:</p>
<pre style="font-family: monospace; font-size: medium; line-height: 1.3em; margin-left: 0em;"># Vega treemap documentation: https://vega.github.io/vega/examples/treemap/
return {
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": width,
"height": height,
"padding": 2.5,
"autosize": "none",
"signals": [
{
"name": "layout", "value": "squarify",
},
{
"name": "aspectRatio", "value": 1.6,
}
],
"data": [
{
"name": "drawdown",
"values": list(elements.values()),
"transform": [
{
"type": "stratify",
"key": "id",
"parentKey": "parent"
},
{
"type": "treemap",
"field": "size",
"sort": {"field": "value"},
"round": True,
"method": {"signal": "layout"},
"ratio": {"signal": "aspectRatio"},
"size": [{"signal": "width"}, {"signal": "height"}]
}
]
},
{
"name": "nodes",
"source": "drawdown",
"transform": [{ "type": "filter", "expr": "datum.children" }]
},
{
"name": "leaves",
"source": "drawdown",
"transform": [{ "type": "filter", "expr": "!datum.children" }]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": list(sector_colormap.keys()),
"range": list(sector_colormap.values())
},
],
"marks": [
{
"type": "rect",
"from": {"data": "nodes"},
"interactive": False,
"encode": {
"enter": {
"fill": {"scale": "color", "field": "name"}
},
"update": {
"x": {"field": "x0"},
"y": {"field": "y0"},
"x2": {"field": "x1"},
"y2": {"field": "y1"}
}
}
},
{
"type": "rect",
"from": {"data": "leaves"},
"encode": {
"enter": {
"stroke": {"value": "#fff"},
"tooltip": {
"signal": "{title: datum.name, 'CO2eq': datum.size + ' Gigatons'}"}
},
"update": {
"x": {"field": "x0"},
"y": {"field": "y0"},
"x2": {"field": "x1"},
"y2": {"field": "y1"},
"fill": {"value": "transparent"}
},
"hover": {
"fill": {"value": "gray"}
}
}
},
{
"type": "text",
"from": {"data": "nodes"},
"interactive": False,
"encode": {
"enter": {
"font": {"value": "Helvetica Neue, Arial"},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {"value": "#fff"},
"text": {"field": "name"},
"fontSize": {"value": 18},
"fillOpacity": {"value": 1.0},
"angle": {"value": -62.0}
},
"update": {
"x": {"signal": "0.5 * (datum.x0 + datum.x1)"},
"y": {"signal": "0.5 * (datum.y0 + datum.y1)"}
}
}
}
]
}
</pre>
<p>The text string is passed to JupyterLab's display() method, annotated with the MIME-type:</p>
<pre style="font-family: monospace; font-size: medium; line-height: 1.3em; margin-left: 3em;">
display(
{'application/vnd.vega.v4+json': solution_treemap(width=400, height=800)},
raw=True)
</pre>
<p>The resulting treemap looks like this:</p>
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiavrt8Lq2KnJX2wiGtztlLhZBDnec7HA7iX4Ril-O4R7j3mY7xs5k0OB0fQrzDMsRTF0BY0saV2kOXd7uVEjaYBGgh1evQTSXOXuiTu4Ok3FL0rAvTJv7tllcXgaPy1frAWFlAgVZVXncA/s320/treemap2.gif" width="280" height="538" /></div>
<p>The notebook can be run for keepsies using mybinder.org, which creates a container to run user code. Clicking on the button below will open Jupyter in a new browser window, albeit after a perhaps lengthy pause while initializing a container to run it.</p>
<center><a href="https://mybinder.org/v2/gh/DentonGentry/blog-posts/master?urlpath=lab/tree/Treemap.ipynb"><img src="https://mybinder.org/static/images/badge_logo.svg"></a></center>
<br/>
<p>For those who have not used Jupyter before: each numbered block of code in the Notebook is a cell, and can be run using the right-pointing triangle button at the top. When the Notebook is first opened there will likely be no graphs displayed. Clicking the run button in each cell will run it and display the treemap.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNyjQ20nHZanVI_EHIsVKohzh2uv7YtpQ12t24SVAAKYAFdIDH-0KCv4901pIMLzlyH3nID5jpBnyJ_mEdT8MWK7-dRUeELvMO8T2qdNS0lS22bMR8K-wwHGTdkqYbFOnUXOGMgNkebrko/s1600/JupyterExplanation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNyjQ20nHZanVI_EHIsVKohzh2uv7YtpQ12t24SVAAKYAFdIDH-0KCv4901pIMLzlyH3nID5jpBnyJ_mEdT8MWK7-dRUeELvMO8T2qdNS0lS22bMR8K-wwHGTdkqYbFOnUXOGMgNkebrko/s800/JupyterExplanation.png" width="640" height="298" data-original-width="695" data-original-height="324" /></a></div>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-48534575171427144372019-02-09T22:50:00.002-08:002019-05-07T11:21:45.227-07:00Line graphs in JupyterLab<p>Recently I've been doing quite a bit of work on climate solution models, using <a hrf="https://jupyter.org/">Jupyter Notebook</a> to interact with the backend model. The Jupyter Notebook is a way to allow front-end code running in a browser to interact with backend code running as kernels managed by Jupyter. Though Jupyter evolved from iPython, there are now kernels available for many languages including Java, R, and even C++. All of my work with Jupyter is in Python, however.</p>
<p>I spent time investigating various graphing and charting packages which support interactive use in a JupyterLab notebook. The <a href="https://github.com/DentonGentry/blog-posts/blob/master/LineGraphs.ipynb">demo code for the different charting packages is available on github</a> for reference. Note that github will render this file in a way which looks nice, but it is not actually running Jupyter and the graphs are just static snapshots.</p>
<p>The notebook can be run for keepsies using mybinder.org, which creates a container to run user code. Clicking on the button below will open Jupyter in a new browser window, albeit after a perhaps lengthy pause while initializing a container to run it.</p>
<center><a href="https://mybinder.org/v2/gh/DentonGentry/blog-posts/master?urlpath=lab/tree/LineGraphs.ipynb"><img src="https://mybinder.org/static/images/badge_logo.svg"></a></center>
<br/>
<p>At launch an error dialog may appear, about jupiterlab_pyviz. I think that is a false alarm as jupiterlab_pyviz is installed in the container and the Altair-viz chart does work, but I haven't figured out how to suppress the popup.</p>
<br/>
<p>For those who have not used Jupyter before: each numbered block of code in the Notebook is a cell, and can be run using the right-pointing triangle button at the top. When the Notebook is first opened there will likely be no graphs displayed. Clicking the run button in each cell (and twice in the matplotlib cell to get it to render) will run each one and allow the graphs to be interacted with.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNyjQ20nHZanVI_EHIsVKohzh2uv7YtpQ12t24SVAAKYAFdIDH-0KCv4901pIMLzlyH3nID5jpBnyJ_mEdT8MWK7-dRUeELvMO8T2qdNS0lS22bMR8K-wwHGTdkqYbFOnUXOGMgNkebrko/s1600/JupyterExplanation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNyjQ20nHZanVI_EHIsVKohzh2uv7YtpQ12t24SVAAKYAFdIDH-0KCv4901pIMLzlyH3nID5jpBnyJ_mEdT8MWK7-dRUeELvMO8T2qdNS0lS22bMR8K-wwHGTdkqYbFOnUXOGMgNkebrko/s800/JupyterExplanation.png" width="640" height="298" data-original-width="695" data-original-height="324" /></a></div>
<hr/><br/>
<h3>Matplotlib + ipympl</h3>
<p><a href="https://matplotlib.org/">matplotlib</a> is one of the oldest plotting packages for Python still in active development. Its primary design point is static graphs, but it does provide interactive features with a suitable renderer. In addition to Jupyter notebooks matplotlib supports renderers for many GUI environments like PyTk and Qt.</p>
<p>Instructions on the web will generally say to include a "%matplotlib inline" statement for use in Jupyter notebooks, but inline graphs are completely static. Instead, this example uses <a href="https://github.com/matplotlib/jupyter-matplotlib">ipympl and "%matplotlib ipympl"</a> which allows interactive features to work. A toolbar at the bottom allows panning and zooming.</p>
<p>However, matplotlib's interactive features are quite limited. Only one chart at a time can be interactive, and the user must click a power button in the upper right to deactivate it before another can be activated. The overall experience isn't great, matplotlib is much stronger when producing purely static graphs.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/VKNm5j15w4g" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<h3>Bokeh</h3>
<p><a href="https://bokeh.pydata.org/">Bokeh</a> is a charting and dashboarding package. Though it supports use within Jupyter, bokeh appears to be mainly aimed at creation of dashboards and larger collections of visualizations. For example it <a href="https://github.com/bokeh/bokeh/issues/7023">doesn't always cooperate with Jupyter widgets</a>, preferring bokeh server's layout functions.</p>
<p>Bokeh's interactive features include a tooltip showing exact values when hovering over a datapoint, plus zoom and panning within the chart.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/gH5_IDVKUx0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<h3>hvplot</h3>
<p><a href="https://hvplot.pyviz.org/">hvplot</a> is built atop bokeh and looks quite similar in operation, with tooltips and pan-and-zoom. hvplot's programming interface is integrated with <a href="https://pandas.pydata.org/">Pandas,</a> adding an hvplot() method to the dataframe.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/UMv6InYQ3C0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<h3>Beaker/X</h3>
<p><a href="http://beakerx.com">Beaker/X</a> is a collection of extensions for Jupyter Notebook, spanning the gamut from computation kernels to a graphing package. Its interactive features include tooltips on hover plus panning and zooming, with double-click to return to the original zoom level.</p>
<p>The charts in Bokeh are <a href="http://groovy-lang.org/">implemented in Groovy</a>. The Python APIs are a direct transfer of the Groovy APIs. They aren't Python bindings in a Pythonic interface, Beaker/X provides a mechanism for different language kernels to call into each other. This did not make it very easy to code for in Python, for example I could not figure out how to set up a Tooltips object and had to leave it with the default.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/hfepZb_izX8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<h3>bqplot</h3>
<p><a href="https://github.com/bloomberg/bqplot">bqplot</a> was released by Bloomberg, and is a charting package used in producing various Bloomberg media properties. It is a thin Python layer which passes through most commands to <a href="https://d3js.org/">D3.js</a> for implementation.</p>
<p>bqplot has ways to support both tooltips on hover and zoom-and-pan features, but I was not able to get both to work at the same time. The video shows a quick edit and re-running the cell in order to demonstrate one and the other. There may well be a way to do so, but I didn't figure it out.</p>
<p>Additionally, the <a href="https://github.com/bloomberg/bqplot/issues/702">tooltips for Line charts are currently not able to retrieve data values</a> and always print NaN.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/6EFppe8xnXU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<h3>Altair-viz</h3>
<p><a href="https://altair-viz.github.io/">Altair</a> is somewhat different from the other packages described here in that it is a declarative API, not imperative. That is, instead of a series of operations to produce a graph, Altair instead provides a way to declare what elements of data should be graphed and how to transform the data while doing so. In that sense, Altair aspires to be more like SQL for fetching data or Prolog for transforming data than it does to be a more traditional API.</p>
<p>Altair-Viz emits a <a href="https://vega.github.io/vega-lite/">Vega-Lite</a> description of the desired graphic, which is expanded to <a href="https://vega.github.io/vega/">Vega</a>, which ultimately sits atop <a href="https://d3js.org/">D3.js</a> in the browser. <a href="https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906">JupyterLab, an early access release for the next major Jupyter version</a>, supports Vega-Lite and Vega natively. Altair does not require installation of a Jupyter extension to work, the only charting package in this post which does not need one.</p>
<p>For interactive use, Altair charts support tooltips on hover and pan-and-zoom of the graph.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/oRmEY1OS9Cc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<h3>plot.ly</h3>
<p><a href="https://plot.ly">Plot.ly</a> is a plotting-as-a-service provider. The main service is hosted online, but the basic functionality of the plot.ly implementation is also available as an open source package which is run locally.</p>
<p>plot.ly charts support tooltips and zoom-and-pan, as well as a mode which prints the X/Y coordinates as the pointer moves over the chart.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/al_yCgwoaOU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br clear="right"/> <br/>
<hr/><br/>
<p>My intention at this point is to focus on Altair-Viz as it is working well and shows promise for future capabilities, with Jupyterlab having native support for the Vega graphics grammar.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-11327043498957474432018-10-16T06:39:00.000-07:002018-10-16T06:39:02.298-07:00Carbon Capture: BECCS<p>BECCS is an acronym for Bio Energy with Carbon Capture and Storage. It uses plant material in a pyrolysis process to produce electricity. As discussed in the <a href="https://codingrelic.geekhold.com/2018/06/carbon-capture-biochar.html">earlier post about biochar</a>, the pyrolysis process produces three outputs:</p>
<ul>
<li>a carbon-rich gas called <i>syngas</i> which is flammable, and contains about half the energy density of natural gas.</li>
<li>the solid <i>char,</i> a charcoal which has a much higher concentration of carbon than the original plant material.</li>
<li>a thick tar referred to as <i>bio-oil,</i> which is much higher in oxygen than petroleum but otherwise similar.</li>
</ul>
<p>BECCS is a commercial operation to pyrolyze organic material at scale, usually by growing trees specifically for the purpose.</p>
<ul>
<li>generate electricity by burning the syngas</li>
<li>use the char to keep the carbon it holds sequestered for a significant length of time. Though this might involve burial deep underground, char is also useful as a soil additive and takes many years to biodegrade. We could handle a substantial amount of carbon returning to the environment at a long enough cadence.</li>
<li>the bio-oil currently has little commercial use but has great potential, as it could displace petroleum in a number of chemical processes.</li>
</ul>
<p>Because the feedstock for BECCS is newly grown vegetative material, it is strictly carbon neutral. If the char keeps carbon out of the atmosphere for a lengthy period of time, BECCS becomes carbon negative and draws down carbon from the environment while providing revenue via power generation to fund its own operation.</p>
<p>BECCS gets a substantial amount of attention because it is already operating at a substantial scale, removing hundreds of kilotons of carbon dioxide from the atmosphere each year. This is a few orders of magnitude off from where we need to get, but is proof that the process works.</p>
<p>The <a href="https://hub.globalccsinstitute.com/publications/global-status-beccs-projects-2010/4-beccs-projects">existing BECCS installations</a> capture byproducts produced in existing agricultural processes, like fermenting corn for ethanol production. An <a href="http://www.pnas.org/content/early/2018/03/06/1720338115">analysis of geo data in 2018 estimated</a> that BECCS could draw down approximately 100 megatons of carbon dioxide per year by 2020 using available land area.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-84387713512754961112018-10-11T10:00:00.000-07:002018-10-11T10:14:48.802-07:00Carbon Capture: Enhanced Weathering<p>Chemical weathering is the process by which various types of rock is broken down by exposure to water, oxygen, and/or carbon dioxide. For our purposes, the most relevant forms of weathering involve uptake of carbon dioxide. CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> dissolved in rainwater forms carbonic acid, which is quite mild as acids go but sufficient over time to dissolve minerals from rock. Calcium and silicon exposed to carbonic acid will form HCO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">3</span> bicarbonate, and release calcium and silicates.</p>
<p>Occurring naturally, this chemical reaction takes place gradually over millions of years. Most of the bicarbonate thus produced eventually washes out to the ocean, where various organisms like coral pull carbon and dissolved calcium out of the water to make shells. The rest of the bicarbonate gradually settles into the deep ocean and eventually adds to the limestone at the ocean floor.</p>
<p><i>Enhanced</i> weathering is a plan by which humans can accelerate this process, by grinding the appropriate types of rock into particles to maximize surface area and spreading them over an area to take up CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span>. There are a number of options.</p>
<ul>
<li>Bicarbonate, calcium, and magnesium at appropriate concentrations are beneficial to soil health, especially tropical soils which tend to be depleted in these minerals. Spreading <a href="https://www.drawdown.org/solutions/coming-attractions/enhanced-weathering-minerals">powdered olivine over one third of tropical agricultural land</a> could pull between 30 and 300 parts per million of carbon dioxide out of the atmosphere.
<br/> <br/>
There is a large range in that number because we just don't know enough about how these processes work at scale. Perhaps fortunately, we also don't have the capacity to quickly seed such a large fraction of the planet's land area. Over time, the results of the earliest years of effort can be measured to guide future plans.</li>
<br/>
<li> Though tropical land is ideal, using <a href="https://www.greensand.nl/en">olivine as a soil additive</a> in agricultural land elsewhere would still have an effect.<br/> <br/>
The term <a href=https://news.ucsc.edu/2018/06/electrogeochemistry.html">"electrogeochemistry" has been coined</a> to refer to enhanced weathering done at large scale.</li>
<br/>
<li>Mine tailings are the heaps of excess rock discarded from mining operations after the valuable minerals have been extracted. The tailings generally contain large amounts of the types of rock which will absorb CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> as they weather, and in fact do rapidly form a shell of carbonate at the surface of the pile. If mining regulations are made to require the tailings be ground more finely and appropriately distributed, they can be effective in pulling carbon dioxide from the atmosphere.
<br/> <br/>
Mine tailings also tend to contain trace amounts of substances which can be harmful, like mercury. Processes such as those developed by <a href="https://www.plantnutritiontech.com/what-we-do.html">Advanced Materials Processing, Inc</a> to remove harmful substances from tailings would be necessary.</li>
</ul>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-1323135819107213822018-09-19T03:54:00.000-07:002018-09-19T03:54:56.670-07:00MacOS Preview.app has a Signature Tool<p>When I receive a PDF file to be signed and returned I have generally printed it out to sign and scan back in... like an animal, as it turns out. On a MacOS system there is a convenient way to add a signature to a PDF file without needing to print it, using only the Preview.app which comes with the system.</p>
<p>In the toolbar is a squiggly icon with a drop down menu:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqy9QlFJX2NfMOBMe3AbXV5pIpUJI7XM4Zy1xHiYZz07XadpPfJLjJ3gvRngg_PxbE01P2ZTTYcqJyT7kjJt4mDqKnixmIFT2mP5wu9aeQ4xipEnca9u1ZziTfm1NQpdBxMvSjkpY2xTO8/s1600/PreviewSignatureTool.png" imageanchor="1" style="margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqy9QlFJX2NfMOBMe3AbXV5pIpUJI7XM4Zy1xHiYZz07XadpPfJLjJ3gvRngg_PxbE01P2ZTTYcqJyT7kjJt4mDqKnixmIFT2mP5wu9aeQ4xipEnca9u1ZziTfm1NQpdBxMvSjkpY2xTO8/s320/PreviewSignatureTool.png" width="320" height="79" data-original-width="443" data-original-height="110" /></a></div>
<p>Clicking it allows one to create a signature by either signing with a finger on the trackpad, or writing a signature on a piece of paper for the camera to scan in. The camera option does a good job of edge detection to extract only the writing and not shadows on the paper.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifxAti9WcwVSjNAUPLq2YEKzob2_KU770dag9lqqwfZKklNDpbE09r1esrGzvqxc_42szLEuW9ogzFhQtHl9w6k-r5f1kbNql6Gcu-25YPcDd7dHWyIfDvzxkTMPxioLmqnxj-CQyjjiFV/s1600/PreviewSignatureToolTrackpad.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifxAti9WcwVSjNAUPLq2YEKzob2_KU770dag9lqqwfZKklNDpbE09r1esrGzvqxc_42szLEuW9ogzFhQtHl9w6k-r5f1kbNql6Gcu-25YPcDd7dHWyIfDvzxkTMPxioLmqnxj-CQyjjiFV/s320/PreviewSignatureToolTrackpad.png" width="296" height="320" data-original-width="440" data-original-height="476" /></a></div>
<div class="separator" style="clear: right; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp9R-7nvBgcXPYJrYsnbHQCsxvPW7KKGVbhc1MYLPasyiG9iPAKC8YZ4khCAkp7bHULxmbDx9uTLbi3CBHxXwgsOdN9TXrw9J-exkdR3ckZ0d-KCxmYKKFpsPX0JU8tBm5gEnQEXTtmaEi/s1600/PreviewSignatureToolCamera.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp9R-7nvBgcXPYJrYsnbHQCsxvPW7KKGVbhc1MYLPasyiG9iPAKC8YZ4khCAkp7bHULxmbDx9uTLbi3CBHxXwgsOdN9TXrw9J-exkdR3ckZ0d-KCxmYKKFpsPX0JU8tBm5gEnQEXTtmaEi/s320/PreviewSignatureToolCamera.png" width="296" height="320" data-original-width="443" data-original-height="479" /></a></div>
<p style="clear: both;">The resulting signature can then be added to the document and dragged to the right spot.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-13784224162392351452018-09-15T07:00:00.000-07:002018-09-15T07:14:27.019-07:00The Arduino before the Arduino: Parallax Basic Stamp<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6YAMEsg7KajK3yN-B2KdGmryPHEl3HvSWod-v8YwYcXj7UsiSzHGqdBhUIRq1xIZHxoLw5STdrUSFPKFRNppaPKpY51dbEfFI050qM9R5niqYFCYgH9WhTyUXNWtjADd2BbAUPIz6_Et2/s1600/parallax_basic_stamp_2.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6YAMEsg7KajK3yN-B2KdGmryPHEl3HvSWod-v8YwYcXj7UsiSzHGqdBhUIRq1xIZHxoLw5STdrUSFPKFRNppaPKpY51dbEfFI050qM9R5niqYFCYgH9WhTyUXNWtjADd2BbAUPIz6_Et2/s320/parallax_basic_stamp_2.jpg" width="240" height="320" data-original-width="1200" data-original-height="1600" /></a>
I recently had cause to dig down through the layers of strata which have accumulated in my electronics bin. In one of the lower layers I found this bit of forgotten kit: the <a href="https://www.parallax.com/">Parallax</a> Basic Stamp II. This was the Arduino before there was an Arduino, a tiny microprocessor aimed at being simple for hobbyist and low-volume commercial use.</p>
<p>The Basic Stamp line is still sold today, though with designs developed over a decade ago. The devices have enough of a market to remain in production, but are otherwise moribund. The past tense will be used in this blog post.</p>
<p>The <a href="https://en.wikipedia.org/wiki/BASIC_Stamp">Basic Stamp</a> line dates back to the early 1990s. The Basic Stamp II shown here was introduced in 1995. It used a <a href="https://en.wikipedia.org/wiki/PIC_microcontrollers">PIC microcontroller,</a> an 8 bit microprocessor line which has been used in deeply embedded applications for decades and is still developed today. The PIC family is a product from <a href="https://www.microchip.com/">Microchip Technology,</a> the same company which now supplies the <a href="https://en.wikipedia.org/wiki/AVR_microcontrollers">AVR chips</a> used in the Arduino after acquiring Atmel in 2016.</p>
<p>The PIC contained several KBytes of flash, which held a BASIC interpreter called PBASIC. An external EEPROM on the BS2 board contained the bytecode compiled user BASIC code. Though it may seem an odd choice now, in the early 1990s the choice of BASIC made sense: the modern Internet and the Tech industry did not exist, with the concordant increase in the number of people comfortable with developing software. BASIC could leverage familiarity with <a href="https://en.wikipedia.org/wiki/GW-BASIC">Microsoft GW-BASIC and QBASIC</a> on the PC, as MS-DOS and Windows computers of this time period all shipped with BASIC. Additionally, Parallax could tap into the experience of the hobbyist community from the Apple II and Atari/Commodore/etc.</p>
<pre style="margin-left: 3em; margin-top: 1em; margin-bottom: 2em;"><code>
' PBASIC code for the Basic Stamp
LED PIN 5
Button PIN 6 ' the BS2 had 16 pins
ButtonVal VAR Bit ' space is precious, 1 *bit* storage
LedDuration CON 500 ' a constant
' Init code
OUTPUT LED
INPUT Button
DO
ButtonVal = Button ' Read button input pin
FREQOUT LED,LedDuration,ButtonVal ' PWM output to flicker LED
PAUSE 200 ' in milliseconds
LOOP
</code></pre>
<p>PBASIC supported a single thread of operation, the BASIC Stamp supported neither interrupts nor threads. Applications needing these functions would generally use a PIC chip without the BASIC interpreter on top. Later Stamp versions added a limited ability to poll pins in between each BASIC statement and take action. This seemed aimed at industrial control users of the stamps, for example Disney used BASIC Stamps in several theme park rides designed during this time frame.</p>
<p>A key piece of the <a href="https://www.arduino.cc/">Arduino</a> and <a href="https://www.raspberrypi.org/">Raspberry Pi</a> ecosystems is the variety of <a href="https://learn.sparkfun.com/tutorials/arduino-shields">expansion kits, or "shields,"</a> which connect to the microprocessor to add capabilities and interface with the external world. The ecosystem of the BASIC Stamp was much more limited, suppliers like <a href="https://www.adafruit.com/">Adafruit</a> were not in evidence because the low volume PCB design and contract manufacturing industry mostly didn't exist. Parallax produced some interesting kits of its own like an early <a href="https://www.parallax.com/product/boe-bot-robot">autonomous wheeled robot.</a> For the most part though, hobbyists of this era had to be <a href="https://www.youtube.com/watch?v=8SSOKppwpAE">comfortable with wire-wrapping</a>.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-45361818459695021132018-09-08T09:25:00.001-07:002018-09-08T20:00:39.127-07:00code.earth hackathon notes<p><a href="https://drawdown.org">Project Drawdown</a> is a comprehensive plan proposed to reverse global warming.
The project researchers analyzed and ranked scenarios according to the potential reduction in carbon levels, and analyzed the costs.</p>
<p>Project Drawdown will continue the analysis work, but is moving into an additional advocacy and empowerment role of showing governments, organizations, and individuals that global warming can be mitigated and providing detailed guidance on strategies which can work. The audience for the project's work is expanding.</p>
<p>This places new demands on the tools. The tooling needs to be more accessible to people in different roles, and provide multiple user interfaces tailored to different purposes. For example, the view provided to policymakers would be more top-level, showing costs and impacts, while the view for researchers would allow comparisons by varying the underlying data.</p>
<p>The <a href="http://codeearth.net/">code.earth</a> hackathon in San Francisco September 5-7, 2018 implemented a first step in this, starting to move the modeling implementation from Microsoft Excel into a web-hosted Python process with Excel providing the data source and presentation of the results. This will separate the model implementation from user interface, making it easier to have multiple presentations tailored for different audiences. It will still be possible to get the results into Excel for further analysis, but web-based interfaces can reach much wider audiences able to act on the results.</p>
<p>I was at the hackathon, working on an end-to-end test for the new backend, and plan to continue working on the project for a while. Global warming is the biggest challenge of our age. We have to start treating it as such.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-4379518448821011732018-09-02T23:05:00.003-07:002018-09-02T23:05:48.047-07:00Carbon Capture: Cryogenic CO2 Separation <p>Sublimation is a phase change directly from a solid to a gas without transitioning through an intermedia liquid state. Desublimation is the opposite, where a gas crystalizes into a solid without becoming a liquid first. The most well-known example of desublimation is snow, where water vapor crystalizes into tiny bits of ice. When water vapor in the cloud first condenses into liquid and then freezes, the result is hail not snow.</p>
<p>Interestingly, and quite usefully for carbon capture, carbon dioxide will desublimate at -78 degrees Centigrade. This is a considerably higher temperature than the main components of the atmosphere like nitrogen and oxygen, and means that as air gets very cold that CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> will be among the first components to turn into ice crystals. This allows the CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> crystals to be harvested.</p>
<p>Several companies have working technology in this area:</p>
<ul>
<li><a href="https://arpa-e.energy.gov/?q=slick-sheet-project/supersonic-technology-co2-capture"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0RMnAo1Pd8x26UQvwYCqAWfPDHNH-r0mNM19qU7dBmU20ZU1aT_zqfax36lJU_L3Qlbboql-v0EKwOlufd8lKljWXnyPooCvKGfKQXbKMFCy1K4VtkcF-UnN6jQGW8tnE7qo-DzPNXLM4/s320/cryogenic+separation.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" width="320" height="152" data-original-width="554" data-original-height="263" /></a><a href="https://en.wikipedia.org/wiki/Alliant_Techsystems">Alliant Techsystems</a> (now defunct) and <a href="http://acentlabs.com/business-areas/carbon-capture/">ACENT Laboratories</a> developed a supersonic wind tunnel which compresses incoming air, causing it to heat up, then expands the supersonic airflow causing it to rapidly freeze. CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> crystals can be extracted via <a href="https://en.wikipedia.org/wiki/Cyclonic_separation">cyclonic separation,</a> relying on the mass of the frozen particles.</li>
<br/>
<li><a href="https://sesinnovation.com/technology/carbon_capture/">Sustainable Energy Solutions</a> in Utah uses a heat exchanger process to rapidly cool air, harvest the CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> crystals, then reclaim the energy spent on cooling before exhausting the remaining gases.</li>
</ul>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-74848752657252975802018-08-29T06:00:00.000-07:002018-08-29T06:00:07.322-07:00Google Software Engineering Levels and Ladders<p>Google (now Alphabet) hires a lot of engineers every year. There are articles out there about the interview process and <a href="http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html">how to prepare</a>, and I do definitely recommend spending time in preparation. Google interviews for software engineers mostly do not focus on the candidate's resume or prior experience, instead asking technical questions on various topics and coding. You'll do better if you mentally refresh topics in computer science which you have not recently worked with.</p>
<p><a href="https://commons.wikimedia.org/wiki/File:Keuffel_%26_Esser_slide_rule,_model_4081-3_(ca._1940)_-_Detail.jpg" imageanchor="1"><img border="0" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqbHsNiPF4ZeolyhErcTuU3jrV9MzvWa3GMJ5fe6_9rmK_Y47S7DA_b5C0aDv_tzFDOLJadbS_OOlwD9o_tbkbZARdslrN9P8PmXnA_K8Fdddb0XGIZjrzmwhT42WkLnIFfFkfhdDHtQSe/s200/slide_rule.jpg" width="200" height="133" data-original-width="1200" data-original-height="800" /></a>
This post focuses on a different area: how to evaluate an engineering job offer from Alphabet. The financial aspects will presumably be clear enough, but the career aspects of the offer may not be. This post will attempt to explain what Google's engineering career progression looks like.</p>
<p>There are two concepts: ladder and level. The ladder defines the role you are expected to do, like manager or engineer or salesperson, while the level is how senior you are in that role.</p>
<p>Like many Tech companies, Google has parallel tracks for people who wish to primarily be individual contributors and for people who wish to primarily be managers. This takes the form of two ladders, Software Engineer (universally abbreviated as "SWE") and Software Engineering Manager. Google <i>does</i> allow people on the SWE ladder to manage reports, and allows people on the Manager ladder to make technical contributions. The difference is in how performance is evaluated. For those on the SWE ladder the expectation is that at least 50% of their time will be spent on individual contributing engineering work, leaving no more than 50% on management. For those on the Manager ladder the expectation is more like 80% of the time to be spent on management. People on one ladder veering too far out of the guidance for that ladder will be encouraged to switch to the other, as performance evaluations will begin to suffer.</p>
<br/> <br/>
<h3>Software Engineer Ladder</h3>
<p>The levels are:</p>
<ul>
<li>SWE-I (Level 2) is a software engineering intern, expected to be in the junior or senior year of a four year degree program.</li>
<li>SWE-II (Level 3) is an entry level full-time software engineer. An L3 SWE is generally someone who recently graduated with an undergraduate or Master's degree, or equivalent education.</li>
<li>SWE-III (Level 4) is someone with several years of experience after graduation, or for someone who just finished a PhD in a technical field.</li>
<li>Senior Software Engineer (Level 5) is the level where a software engineer is expected to be primarily autonomous: capable of being given tasks without excessive detail, and being able to figure out what to do and then do it. A software engineer advances to L5 primarily by demonstrating impact on tasks of sufficient difficulty. When hiring externally, six to ten years of experience is generally expected.</li>
<li>Staff Software Engineer (Level 6) is the level where leadership increasingly becomes the primary criteria by which performance is judged. Many, though by no means all, SWEs begin managing a team of engineers by this point in their career. When hiring externally, ten or more years of experience are generally expected.</li>
<li>Senior Staff Software Engineer (Level 7) is essentially L6 with larger expectations. Guidance for years of experience begins to break down at this level, as most candidates with ten or more years experience will be hired at Level 6 unless there is a strong reason to offer a higher level. Involvement of the hiring manager or strong pushback by the candidate can sometimes push the offer to Level 7.</li>
<li>Principal Software Engineer (Level 8) is the first level which is considered an executive of the Alphabet corporation for the purposes of remuneration and corporate governance. Principal Software Engineers drive technical strategy in relatively large product areas. SWEs at level 8 or above are relatively rare: the equivalent level on the manager ladder will routinely have five or more times as many people as on the SWE ladder. By this level of seniority, most people are focussed on management and leadership.</li>
<li>Distinguished Software Engineer (Level 9) drives technical strategy in efforts spanning a large technical area.</li>
<li>Google Fellow (Level 10) is the same level as a Vice President, expected to drive technical strategy and investment in crucial areas.</li>
<li>Google Senior Fellow (Level 11) is for people like <a href="https://en.wikipedia.org/wiki/Jeff_Dean_(computer_scientist)">Jeff Dean</a> and <a href="https://en.wikipedia.org/wiki/Sanjay_Ghemawat">Sanjay Ghemawat</a>.</li>
</ul>
<p>Most external hiring for software engineers is for L4 through L6, with L7 also possible though less common. Hiring externally directly to L8 and L9 does happen, but is quite rare and demands the direct sponsorship of a high-level executive like a Senior Vice President of a Google Product Area or CEO of an Alphabet company. For example <a href="https://en.wikipedia.org/wiki/James_Gosling">James Gosling</a> and <a href="https://en.wikipedia.org/wiki/David_Patterson_(computer_scientist)">David Patterson</a> both joined the company as L9 Distinguished Engineers.</p>
<p>Also notable is that the external hiring process and the internal promotion process are entirely separate, and at this point have diverged substantially in their calibration. It is fair to say that Alphabet substantially undervalues experience outside of the company, or perhaps overvalues experience within the company. Someone with ten years experience externally would be hired at L5 or L6, while ten years within the company can make it to L7 or L8.</p>
<br/> <br/>
<h3>Software Engineering Manager Ladder</h3>
<p>The levels are:</p>
<ul>
<li>Manager, Software Engineering I (Level 5) is the first level on the manager ladder. It is expected that people will have a few years experience in the field before they begin managing a team, and therefore the Manager ladder starts at level 5. Manager I will typically lead a small team of engineers, five to ten is common.</li>
<li>Manager, Software Engineering II (Level 6) is typically a manager of a team of ten to twenty, sometimes a mixture of direct reports and managing other managers. When hiring externally, 10+ years of experience is expected.</li>
<li>Manager, Software Engineering III (Level 7) begins the transition to be primarily a manager of managers. Teams are larger than L6, typically twenty to forty.</li>
<li>Director (Level 8) is the first level which is considered an executive of the Alphabet corporation for the purposes of remuneration and corporate governance. Directors are mostly managers of managers, and typically lead organizations of forty up to several hundred people.</li>
<li>Senior Director (Level 9) is basically a secret level at Google: all of the internal tools will show only "Director," and by tradition promotions to Senior Director are not publicly announced. Senior Directors may lead slightly larger organizations than L8 Directors, though mostly it provides a way to have a larger gap between Director and VP while still allowing career progression.</li>
<li>Vice President (Level 10) typically leads organizations of hundreds to thousands of people. Their direct reports will typically be Directors and will be second to third level managers themselves.</li>
<li>Vice President II (Level 11), like Senior Director, is shown only as "VP" in internal tools and provides a way to maintain a larger gap between VP and SVP while still allowing managers to advance in their careers.</li>
<li>There are executive levels beyond L12, notably Senior Vice Presidents of Google divisions and CEOs of other Alphabet companies. This blog post is not a good guide to hiring for those levels, if you happen to be such a candidate. Sorry.</li>
</ul>
<p>When hiring managers externally, L5 through Director is most common. Above Director is rare and generally only happens with the sponsorship of a high level executive. However where SWE hiring essentially tops out at L9, manager hires can come in at almost any level given sufficient sponsorship. Alphabet hires CEOs for its affiliated companies (<a href="https://en.wikipedia.org/wiki/John_Krafcik">John Krafcik</a>, <a href="https://en.wikipedia.org/wiki/Andrew_Conrad_(geneticist)">Andrew Conrad</a>) and Google SVPs (<a href="https://en.wikipedia.org/wiki/Craig_H._Barratt">Craig Barratt</a>, <a href="https://en.wikipedia.org/wiki/Diane_Greene">Diane Greene</a>) externally.</p>
<br/> <br/>
<h3>Other ladders equivalent to SWE</h3>
<p>There is one other software engineering role at Alphabet which is parallel to the SWE/Software Manager ladders: Site Reliability Engineer or SRE. The individual contributor ladder is called SRE-SWE — for historical reasons, as there used to be an SRE-System Administration ladder which is no longer hired for. There is also an SRE Manager ladder. The levels on SRE-SWE and SRE Manager roughly correspond in responsibilities and years of experience to the SWE and Software Manager ladders described above, though the nature of the work differs.</p>
<p>SRE is equivalent to SWE in that at any time, an SRE can choose to relinquish the SRE duties and transfer to the SWE ladder and SRE Manager can switch to the Software Manager ladder. If originally hired as an SRE, they can also generally switch back if they choose to to do in the future. Engineers hired as a SWE who wish to transfer to SRE require a bit more process, often via an internal training program to serve a rotation as an SRE.</p>
<br/> <br/>
<h3>Other ladders NOT equivalent to SWE</h3>
<p>SETI, for Software Engineer in Tools and Infrastructure, is another engineering ladder within Google. Though recruiters will make the claim that it is just like being a SWE, transfers from SETI to SWE require interviews, acceptance by a hiring committee, and approval of the SVP who owns the SWE ladder. Though often successful, transfers from SETI to SWE are not automatic and do get rejected, at both stages of the approval process. As such, recruiter claims that it is just like being a SWE are not accurate. The recruiter just has an SETI role to fill.</p>
<p>Only accept an SETI role if automated testing and continuous software improvement are really passions. Projects listing SETI openings will be less numerous than SWE, though will often be more focussed on automation and quality improvement. In many cases, internal transfers to projects which list a SWE opening will accept an SETI applicant, but not always. Being on the SETI ladder will therefore be slightly limiting in choice of projects for internal mobility.</p>
<p>There are other ladders which also involve software development but are even further removed from the SWE ladder, notably Technical Solutions Engineer (TSE) and Web Solutions Engineer (WSE). As with SETI, transfers to the SWE ladder require interviews and approvals. Recruiter claims that TSE or WSE are "just like being a SWE" are not accurate, as people on these ladders cannot internally transfer to projects which have a SWE opening. They can only transfer to TSE/WSE openings, which limit the choice of projects.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-17479999988309651962018-08-25T09:31:00.000-07:002019-04-17T11:44:55.487-07:00Carbon Capture: Soil health<p>Topsoil across the land areas of the planet holds substantially more carbon than the entire atmosphere, and over the past several hundred years we have released at least 50 percent of the carbon formerly held by soils into the air. This is primarily because of tilling, which disturbs the deeper soils and kills the roots and fungi which reside there. Tilling is necessary for modern agricultural practices using fertilizer and insecticides, which can improve yields substantially until the soil has become substantially depleted of carbon and gradually less productive. Much farmland around the world now is stuck in a local maxima: stopping tilling and allowing the soil to recover would eventually result in improved yields, but only after a few years of very poor harvests.</p>
<p><a href="https://pxhere.com/en/photo/460969" style="clear:right; float:right; margin-bottom:1em; margin-left:1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9b_NDqnFYEWEQVBXWKGXRKrSEREkkags0wuwPQYDgSziif6kCNfOJOHaDu5RY9SD_1OVFaFDLEKN06OgLOszPK5zW7CWDkSUtdo2QYWoftC8gJW-H7MfdQHb7LXPzOtcj2bLvmZT28dCs/s200/agriculture.jpg" width="200" height="89" data-original-width="1600" data-original-height="712" /></a>It <a href="https://www.drawdown.org/solutions/food/regenerative-agriculture">is estimated that regenerating depleted land</a> can absorb two to five tons of CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> per acre per year, for about ten years. Done at scale, regenerative agriculture could absorb tens of gigatons of CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> per year. For perspective, current human emissions are approximately 36 gigatons per year. Improving soil health could offset a nontrivial fraction of current emissions or, in conjunction with other methods to reduce new emission, pull previously emitted carbon from the air.</p>
<h3>Companies in this technology space</h3>
<ul>
<li><a href="https://www.regen.network/">Regen Network</a> provides tools to gather and analyze data for soil health in regenerative agriculture, silvopasturing, and other practices to improve ecological health. It also provides a trading platform to invest and fund these developments.</li>
<li><a href="https://cometfarm.nrel.colostate.edu/">COMET-Farm</a> at Colorado State University tracks data entered by farms to estimate the levels of carbon stored, plus other factors relating to soil health.</li>
<li><a href="https://techhivemind.com/">HiveMind</a> produces Mycelium soil enhancements which jump-start the process of sequestering substantially more carbon per acre of soil.</li>
</ul>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-42673968045861778772018-08-11T22:37:00.000-07:002018-10-18T18:48:52.171-07:00Carbon Capture: Other Types of Sorbents<p>A <a href="https://codingrelic.geekhold.com/2018/06/carbon-capture-adsorption.html">previous post discussed temperature swing adsorption</a>, wherein carbon dioxide is captured when the <a href="https://en.wikipedia.org/wiki/Sorbent">sorbent</a> is at low temperature and released when raised to sufficiently high temperature. Desorption temperatures of five to seven hundred degrees Celsius are typical with known sorbents, imposing a substantial energy cost to heat and cool the material.</p>
<p>There are other sorbent materials where the capture and release cycle is controlled not be temperature but by other factors. The two most common are:</p>
<ul>
<li>pressure-swing, where adsorption is controlled by the pressure of the gases in the process. In <a href="https://ac.els-cdn.com/S1876610217315382/1-s2.0-S1876610217315382-main.pdf?_tid=9315a97f-e5fc-4219-8cbb-f7cbf2728473&acdnat=1534032192_4d3bae17acd71b6d42a46502382f1c78">one study, activated carbon</a> was used as the sorbent to capture carbon dioxide.</li>
<a href="https://www.flickr.com/photos/johntrathome/6341427227/in/photostream/" imageanchor="1" style="clear:right; float:right;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCk-yrQUtaeSTL42J8qDrk5extzcq-oqrPodYCLK22oQECGX655Rv2IBlG0_mxJsmBLIFttc49vBieWrg_Dc1LU_gBA6D8kPhl8q-Fsyci-fkZrcEhsszOH1FYFj5NAmLXMSlIxR_QwOfA/s200/6341427227_640a175e9b_o.jpg" width="96" height="128" data-original-width="1200" data-original-height="1600" /></a>
<br/>
<li>moisture-swing, where the presence of water or water vapor controls the adsorption cycle. A great deal of recent work on moisture swing sorbents for carbon dioxide has been done at the Arizona State University, apparently focused on a Metal Oxide Framework material containing zirconium.</li>
<br/>
</ul>
<br style="clear:both;"/>
<p>The goal with both of these technologies is for a carbon dioxide removal process requiring less energy than for temperature swing adsorption. The Temperature Swing Adsorption processes are much further along in development, with several commercial carbon capture systems (detailed in the <a href="https://codingrelic.geekhold.com/2018/06/carbon-capture-adsorption.html">earlier post</a>). Pressure Swing Adsorption is used to scrub CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span> in high-oxygen feeds like for hospitals, but is not currently used at scale for carbon capture from the atmosphere. So far as I can tell, Moisture Swing Adsorption has thus far only been used in the lab and small scale trials.</p>
<br/> <br/>
<h3>Companies and organizations in this technology space</h3>
<ul>
<li>The <a href="https://cnce.engineering.asu.edu/">Center for Negative Carbon Emissions</a> at Arizona State University originated the moisture swing adsorption technology for CO<span style="vertical-align: baseline; position: relative; top: 0.1em; font-size:8px;">2</span>, and continues to evangelize its potential.</li>
<br/>
<li>The <a href="https://healthyclimatealliance.org/">Healthy Climate Alliance</a> and <a href="https://www.linkedin.com/in/jim-aldridge-97b23/">Engineer Jim Aldridge</a> demonstrated a <a href="https://globenewswire.com/news-release/2018/09/11/1568996/0/en/Direct-Air-Capture-Prototype-to-be-Revealed-at-Global-Climate-Action-Summit-by-the-Healthy-Climate-Alliance.html">direct air capture prototype</a> using a moisture-swing sorbent at an affiliated event of the <a href="https://www.globalclimateactionsummit.org/">Global Climate Action Summit</a> in September 2018.</li>
<br/>
<li><a href="https://www.infinitreellc.com/">Infinitree</a> appears to be working in this space and using moisture swing adsorbents for carbon removal, though there are few details. Infinitree also uses the <i>Carbon Sink</i> brand, as mentioned in <a href="http://ceassessment.org/wp-content/uploads/2017/06/Ishimoto-WPS002.pdf">a paper by Ishimoto et al.</a></li>
<br/>
<li><a href="https://www.skytree.eu/">Skytree</a> in the EU is a spinout from the European Space Agency. Its technology is a moisture-swing sorbent originally developed for air recycling in space.</li>
<br/>
<li><a href="https://www.sri.com/work/projects/mixed-salt-process-carbon-dioxide-separation">SRI International</a> has developed a pressure-swing adsorption technology using ammonia and potassium salts. It is claimed to require very low energy inputs to cycle the sorbents and be ready for another round of adsorption.</li>
</ul>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-56457297783086649792018-08-10T00:18:00.001-07:002018-08-10T08:34:52.450-07:00Flatulenating, Wherein We Attempt to Rectify a Dictionaric Injustice<p><b>Flatulenating:</b> having the property of inducing <a href="https://www.merriam-webster.com/dictionary/flatulence">flatulence</a>.</p>
<p>Example: <i>"Beans are flatulenating. I get such terrible gas every time I eat them."</i></p>
<br/> <br/>
<hr/>
<br/> <br/>
<p>At the time of this writing on August 10th, 2018, <a href="https://www.google.com/search?q=%22flatulenating%22">https://www.google.com/search?q="flatulenating"</a> shows zero results. This blog post is an attempt to resolve this <a href="https://en.wiktionary.org/wiki/dictionaric">dictionaric</a> injustice.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.comtag:blogger.com,1999:blog-9151880169490356401.post-15727704169423063852018-08-01T10:00:00.000-07:002018-08-01T10:35:40.214-07:00Career & Interviewing Help<p>Something I find rewarding is helping others in their careers. I am quite happy to conduct practice embedded software engineer or manager interviews, answer questions about engineering at Google or in general, advise on career planning, etc.</p>
<p><a href="http://bit.ly/dgentry_career_help">I keep a bookable calendar</a> with two timeslots per week. I am in the Pacific timezone, and can set up special times more convenient for people in timezones far from my own. If the calendar doesn't work for you, you can contact me at denny@geekhold.com to make special arrangements.</p>
<p>Anyone is welcome, you don't need an intro or to know me in person. The sessions are conducted via Google Hangout or by phone. My only request for this is to pay it forward: we all have opportunities to help others. Every time we do so, we make the world a slightly better place.</p>Denton Gentryhttp://www.blogger.com/profile/11782508603268183191noreply@blogger.com