Merge branch 'lec02'

This commit is contained in:
James Turk 2024-10-04 22:56:19 -05:00
commit 68cc1a4baa
88 changed files with 8244 additions and 63 deletions

File diff suppressed because one or more lines are too long

View File

@ -335,7 +335,7 @@ Use of Altair is **strongly** recommended, but other libraries allowed.
---
## Acknowledgements
## Acknowledgements & References
Thanks to Alex Hale, Andrew McNutt, and Jessica Hullman for sharing their materials.

File diff suppressed because one or more lines are too long

View File

@ -6,9 +6,9 @@
## Today
- Grammar of Graphics
- Types of Data
- Intro to Altair
- What is a **grammar of graphics** and how do we use it in practice?
- What **types of data** do we encounter, and how does that affect visualizations?
- Introduction to **Altair**
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="608.00006"
height="608"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="CMY.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<metadata
id="metadata15">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
inkscape:window-height="667"
inkscape:window-width="640"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
guidetolerance="10.0"
gridtolerance="10.0"
objecttolerance="10.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
showgrid="false"
inkscape:zoom="0.75986842"
inkscape:cx="304.00003"
inkscape:cy="304"
inkscape:window-x="22"
inkscape:window-y="29"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 304 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="608.00006 : 304 : 1"
inkscape:persp3d-origin="304.00003 : 202.66667 : 1"
id="perspective17" />
</defs>
<g
transform="translate(-18.291045,-16.542123)"
style="opacity:1;display:inline"
id="layer1">
<path
d="M 420 460.93362 A 217.14285 217.14285 0 1 1 -14.285706,460.93362 A 217.14285 217.14285 0 1 1 420 460.93362 z"
transform="matrix(0.9189367,0,0,0.9189367,37.127658,-202.74718)"
style="opacity:1;fill:#00ffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path2162" />
<path
d="M 420 460.93362 A 217.14285 217.14285 0 1 1 -14.285706,460.93362 A 217.14285 217.14285 0 1 1 420 460.93362 z"
transform="matrix(0.9189367,0,0,0.9189367,237.62766,-202.74718)"
style="opacity:1;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path2164" />
<path
d="M 420 460.93362 A 217.14285 217.14285 0 1 1 -14.285706,460.93362 A 217.14285 217.14285 0 1 1 420 460.93362 z"
transform="matrix(0.9189367,0,0,0.9189367,137.58713,-3.2066487)"
style="opacity:1;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path9203" />
<path
d="M 324,48.087181 C 264.49414,82.636501 224.46875,147.05693 224.46875,220.77468 C 224.46875,294.49339 264.49287,358.91318 324,393.46218 C 383.50713,358.91318 423.53126,294.4934 423.53125,220.77468 C 423.53125,147.05692 383.50585,82.636501 324,48.087181 z "
style="opacity:1;fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path18905" />
<path
d="M 324,220.8125 C 288.46034,220.8125 255.06916,230.12991 226.15625,246.4375 C 238.94927,344.27103 322.69542,419.90626 424,419.90625 C 459.54321,419.90625 492.92884,410.59187 521.84375,394.28125 C 509.04887,296.44977 425.30313,220.81251 324,220.8125 z "
style="opacity:1;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path19879" />
<path
d="M 324,220.8125 C 222.69688,220.8125 138.95113,296.44976 126.15625,394.28125 C 155.07115,410.59187 188.45679,419.90624 224,419.90625 C 325.30458,419.90625 409.05074,344.27103 421.84375,246.4375 C 392.93084,230.12991 359.53966,220.8125 324,220.8125 z "
style="opacity:1;fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path20853" />
<path
d="M 324,220.8125 C 288.45334,220.8125 255.07252,230.12055 226.15625,246.4375 C 234.33959,309.10064 271.62382,362.65363 324,393.0625 C 325.25763,392.33212 326.50996,391.56938 327.75,390.8125 C 329.0098,390.04356 330.25876,389.26463 331.5,388.46875 C 333.98249,386.87699 336.43792,385.22833 338.84375,383.53125 C 342.45249,380.98563 345.94791,378.33593 349.375,375.5625 C 351.60265,373.75974 353.82169,371.92643 355.96875,370.03125 C 356.02346,369.98296 356.07034,369.92335 356.125,369.875 C 357.44508,368.70721 358.74264,367.51434 360.03125,366.3125 C 361.96384,364.51004 363.85893,362.65831 365.71875,360.78125 C 366.75205,359.73837 367.77099,358.69034 368.78125,357.625 C 369.79151,356.55966 370.79443,355.49364 371.78125,354.40625 C 373.75489,352.23147 375.68507,350.01054 377.5625,347.75 C 378.50122,346.61973 379.4297,345.4636 380.34375,344.3125 C 381.2578,343.1614 382.14227,342.01527 383.03125,340.84375 C 383.92023,339.67223 384.79275,338.47278 385.65625,337.28125 C 386.51975,336.08972 387.38114,334.89863 388.21875,333.6875 C 389.85137,331.32684 391.43676,328.93285 392.96875,326.5 C 393.00847,326.43692 393.0541,326.37563 393.09375,326.3125 C 393.87837,325.06338 394.64874,323.79875 395.40625,322.53125 C 396.73254,320.31204 398.00853,318.05509 399.25,315.78125 C 399.32814,315.63814 399.39096,315.48707 399.46875,315.34375 C 399.56668,315.16327 399.68387,314.99331 399.78125,314.8125 C 400.48332,313.50946 401.17001,312.1952 401.84375,310.875 C 403.19123,308.2346 404.48704,305.55033 405.71875,302.84375 C 406.17778,301.83506 406.61986,300.83007 407.0625,299.8125 C 407.21377,299.46452 407.38191,299.13025 407.53125,298.78125 C 407.59766,298.62615 407.65272,298.4678 407.71875,298.3125 C 407.9018,297.88167 408.0699,297.43237 408.25,297 C 408.5763,296.21704 408.90218,295.44421 409.21875,294.65625 C 410.33143,291.88674 411.3846,289.07917 412.375,286.25 C 412.39017,286.20665 412.42235,286.16836 412.4375,286.125 C 413.41085,283.3383 414.30465,280.52886 415.15625,277.6875 C 415.56134,276.33591 415.96673,274.95719 416.34375,273.59375 C 416.73996,272.16091 417.10391,270.72679 417.46875,269.28125 C 417.49767,269.16659 417.53378,269.05224 417.5625,268.9375 C 418.12885,266.6763 418.66786,264.38471 419.15625,262.09375 C 419.30275,261.40577 419.45437,260.72183 419.59375,260.03125 C 419.67542,259.62713 419.73328,259.2175 419.8125,258.8125 C 420.02622,257.71995 420.24171,256.63008 420.4375,255.53125 C 420.70587,254.02509 420.95317,252.51761 421.1875,251 C 421.37038,249.8156 421.52557,248.62865 421.6875,247.4375 C 421.73317,247.10115 421.79976,246.77438 421.84375,246.4375 C 392.93084,230.12991 359.53966,220.8125 324,220.8125 z "
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
id="path21827" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
sodipodi:docname="hexrgb.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.78127806"
inkscape:cx="264.31051"
inkscape:cy="271.99023"
inkscape:window-width="1390"
inkscape:window-height="1027"
inkscape:window-x="2244"
inkscape:window-y="58"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<rect
x="84.476966"
y="92.15669"
width="78.077196"
height="174.07375"
id="rect8128" />
<rect
x="138.23504"
y="104.95623"
width="213.75232"
height="131.83527"
id="rect236" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
transform="scale(0.26458333)"
id="text234"
style="fill:#005e5c;font-size:48px;text-align:center;-inkscape-font-specification:Silom;font-family:Silom;stroke-linejoin:round;stroke-linecap:round;line-height:normal;text-decoration-color:#000000;stroke-width:0.99999874;-inkscape-stroke:none;stop-color:#000000;white-space:pre;shape-inside:url(#rect236)" />
<text
xml:space="preserve"
style="font-size:12.7px;line-height:normal;font-family:Silom;-inkscape-font-specification:Silom;text-align:center;text-decoration-color:#000000;fill:#005e5c;stroke-width:0.264583;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;stop-color:#000000"
x="53.507412"
y="35.897377"
id="text242"><tspan
sodipodi:role="line"
style="stroke-width:0.264583"
x="53.507412"
y="35.897377"
id="tspan246">#<tspan
style="fill:#ff0000;fill-opacity:1"
id="tspan856">aa</tspan><tspan
style="fill:#00ff00;fill-opacity:1"
id="tspan994">33</tspan><tspan
style="fill:#0000ff;fill-opacity:1"
id="tspan1126">99</tspan></tspan></text>
<text
xml:space="preserve"
style="font-size:5.60128px;line-height:normal;font-family:Silom;-inkscape-font-specification:Silom;text-align:center;text-decoration-color:#000000;fill:#0000ff;fill-opacity:1;stroke-width:0.116693;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;stop-color:#000000"
x="65.144798"
y="33.956829"
id="text1130"
transform="scale(0.96581023,1.0354001)"><tspan
sodipodi:role="line"
id="tspan1128"
style="stroke-width:0.116693"
x="65.144798"
y="33.956829" /><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="40.958431"
id="tspan1236">aa/ff</tspan><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="47.960033"
id="tspan1240">170/255</tspan><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="54.961636"
id="tspan5612">66%</tspan><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="61.963223"
id="tspan1968" /><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="68.964828"
id="tspan1972" /><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="75.966431"
id="tspan2700" /><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="82.968033"
id="tspan6340" /><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="89.969635"
id="tspan4156" /><tspan
sodipodi:role="line"
style="fill:#ea0000;fill-opacity:1;stroke-width:0.116693"
x="65.144798"
y="96.971237"
id="tspan4884" /></text>
<text
xml:space="preserve"
style="font-size:5.60128px;line-height:normal;font-family:Silom;-inkscape-font-specification:Silom;text-align:center;text-decoration-color:#000000;fill:#0000ff;fill-opacity:1;stroke-width:0.116693;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;stop-color:#000000"
x="93.374222"
y="40.958431"
id="text6454"
transform="scale(0.96581023,1.0354001)"><tspan
sodipodi:role="line"
id="tspan6452"
style="fill:#00ff00;fill-opacity:1;stroke-width:0.116693"
x="93.374222"
y="40.958431">33/ff</tspan><tspan
sodipodi:role="line"
style="fill:#00ff00;fill-opacity:1;stroke-width:0.116693"
x="93.374222"
y="47.960033"
id="tspan6456">51/255</tspan><tspan
sodipodi:role="line"
style="fill:#00ff00;fill-opacity:1;stroke-width:0.116693"
x="93.374222"
y="54.961636"
id="tspan6568">20%</tspan></text>
<text
xml:space="preserve"
style="font-size:5.60128px;line-height:normal;font-family:Silom;-inkscape-font-specification:Silom;text-align:center;text-decoration-color:#000000;fill:#0000ff;fill-opacity:1;stroke-width:0.116693;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;stop-color:#000000"
x="116.37598"
y="40.958431"
id="text6462"
transform="scale(0.96581023,1.0354001)"><tspan
sodipodi:role="line"
id="tspan6460"
style="stroke-width:0.116693"
x="116.37598"
y="40.958431">99/ff</tspan><tspan
sodipodi:role="line"
style="stroke-width:0.116693"
x="116.37598"
y="47.960033"
id="tspan6464">153/255</tspan><tspan
sodipodi:role="line"
style="stroke-width:0.116693"
x="116.37598"
y="54.961636"
id="tspan8022">39%</tspan></text>
<text
xml:space="preserve"
transform="scale(0.26458333)"
id="text8126"
style="fill:#ea0000;font-size:48px;text-align:center;-inkscape-font-specification:Silom;font-family:Silom;stroke-linejoin:round;stroke-linecap:round;line-height:normal;text-decoration-color:#000000;stroke-width:0.99999874;-inkscape-stroke:none;stop-color:#000000;fill-opacity:1;white-space:pre;shape-inside:url(#rect8128)" />
<text
xml:space="preserve"
style="font-size:5.60128px;line-height:normal;font-family:Silom;-inkscape-font-specification:Silom;text-align:center;text-decoration-color:#000000;fill:#0000ff;fill-opacity:1;stroke-width:0.116693;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;stop-color:#000000"
x="40.459595"
y="33.583755"
id="text1130-1"
transform="scale(0.96581023,1.0354001)"><tspan
sodipodi:role="line"
id="tspan1128-6"
style="stroke-width:0.116693"
x="40.459595"
y="33.583755" /><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="40.585354"
id="tspan5612-0">hex</tspan><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="47.586956"
id="tspan8263">dec</tspan><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="54.588558"
id="tspan8265">percent</tspan><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="61.590157"
id="tspan1968-4" /><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="68.591759"
id="tspan1972-4" /><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="75.593361"
id="tspan2700-5" /><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="82.594963"
id="tspan6340-9" /><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="89.596565"
id="tspan4156-7" /><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.116693"
x="40.459595"
y="96.59816"
id="tspan4884-5" /></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,542 @@
---
theme: custom-theme
---
# Perception & Color
## CAPP 30239
---
## Today
- What matters most when creating a visualization?
- How does human **perception** factor into visualization design?
- Understanding **color**, and computational representations of it.
---
## What is the most important question when creating a visualization?
---
## What is the most important question when creating a visualization?
<ul>
<li><s>Where will the data come from?</s>
<li><s>What type of chart do I use?</s></li>
<li>Who is the audience?</li>
</ul>
---
## Audience First
- Who are you presenting to?
- How familiar are they with the data?
- What is their numerical & visualization literacy?
- Via what medium will they receive the information?
- What are you trying to do? (Persuade, Inform, Inspire?)
*Only now can we start thinking about data and presentation.*
---
## Perception
- **Selective** - We can only pay attention to so much.
- **Patterns** - Our brains are pattern-matching machines, audience will benefit from intentional patterns & be distracted by unintentional ones.
- **Limited working memory** - We hold a very limited set of information in our minds at once.
---
## What do you see?
<div class="container">
<div class="col">
![](viz-1.png)
</div><div class="col">
```python
alt.Chart(random_df).mark_point().encode(
alt.X("a"),
alt.Y("c"),
alt.Color("b"),
alt.Size("c"),
alt.Shape("a:N"),
alt.Fill("b"),
alt.Opacity("b"),
)
```
</div>
</div>
---
## What do you see?
<div class="container">
<div class="col">
![](viz-2.png)
```
alt.Chart(random_df).mark_line().encode(
x="a",
y="c",
)`
```
</div>
</div>
---
## Effectiveness Revisited
![width:800px](effectiveness.png)
---
<div class="container">
<div class="col">
**Altair Channels**
- Position (`X, Y`)
- Angle (`Angle`)
- Area (`Radius`, `Size`)
- Hue, Saturation (`Color`)
- Texture (`Opacity`, `Fill`)
- Shape (mark type, `Shape`)
</div>
<div class="col">
**What about?**
- Length
- Slope
- Volume
- Density
- Connection
- Containment
</div>
</div>
---
**Derived Properties**
- Length/Area - size of bars (`X`, `Y`)
- Slope & Density - affected by scale
- Connection - ex. layering of lines w/ points
- Containment - achieved with layering
What about *volume*?
---
## Stevens' Power Law
Stevens (1975): Human response to sensory stimulus is characterized by a power law with different exponents with different stimuli.
perception = (magnitude of sensation)<sup>a</sup>
Smaller <sup>a</sup> exponent: harder to perceive changes.
Stevens measured values of a by exposing people to varied stimulus and asking them to compare magnitudes.
---
<div class="container"><div class="col">
![](stevens.png)
</div><div class="col">
| Continuum | Exponent |
|-|-|
| Color **Brightness**| 0.33-0.5 |
| Smell| 0.6 |
| Loudness | 0.67 |
| **Depth Perception** | 0.67 |
| Area | 0.7 |
| 2D Planar Position | 1.0 |
| Warmth | 1.3-1.6 |
| Color **Saturation** | 1.7 |
| Electric Shock | 3.5 |
</div></div>
---
## 3D Graphs
![](stunning-3d-chart.jpg)
---
![](datavizproject.png)
---
![](3d-scatter.png)
---
## Instead of 3D Graphs
- Find other channels: hue & size are good candidates. (bubble chart)
- Or make multiple 2D graphs with XY/YZ/XZ pairs.
![bg left](scatter-matrix.png)
---
## What is Color?
Wavelengths of light are perceived as particular colors:
![](linear_visible_spectrum.svg.png)
What's missing?
<!-- credit: https://en.wikipedia.org/wiki/File:Linear_visible_spectrum.svg -->
---
## Color & the Eye
### Rods
- spread throughout retina
- more sensitive in low light conditions
- brightness ("lightness")
### Cones
- 3 types with peak sensitivity at different frequencies
- concentrated in center of eye
- less sensitive in low light conditions
- hue & saturation
![bg right](cone-fundamentals.png)
<!-- source https://commons.wikimedia.org/wiki/File:Cone-fundamentals-with-srgb-spectrum.svg -->
---
## Spectrum vs. What We See
What we actually see is always a blend of multiple peaks.
This is impacted by ambient light conditions, as well as quirks of our visual processing.
![height:400px](the-dress.jpg)
In actuality, multiple combinations of light can give same color (**metamers**).
---
## Chromatic Adaptation
![](demo-bw-illusion-andrew-steele.gif)
Source: Andrew Steele <https://www.youtube.com/channel/UC-XYsDNh4-886rMNLnnwR_w>
---
## Color Naming
Color naming is highly subjective, and research has shown that the ability to name a color correlates highly with the ability to distinguish it.
![bg right](xkcd-color-map.png)
Be particularly careful with blue/green boundaries, as there are significant cultural differences.
Source: https://blog.xkcd.com/2010/05/03/color-survey-results/
---
## Cultural Considerations
![bg right width:600px](hok-uk.svg)
- American audiences associated <span color="red">red</span> & <span color="blue">blue</span> with political parties on any map in a political context.
- Also international meaning of <span color="red">red</span> & <span color="blue">blue</span> is flipped: red is left, blue is right.
- Most other colors have contradictory meanings depending on culture. For example, yellow might be chosen to denote success (parts of Africa) or be associated with death (Middle East).
<!--Source: https://www.color-meanings.com/color-symbolism-different-cultures/-->
<!-- image from wikipedia: UK House of Commons -->
---
## Color Vision Deficiency
More accurate name for what is commonly known as colorblindness.
- Red-Green CVD - most common
- four types: Dueteranomaly and Protanomaly (mild) to Protanopia and Dueteranopia (complete)
- Tritanomaly/Tritanopia: blue/green and yellow/red confusion.
- rarest, complete lack of color vision, usually corresponds to other vision issues as well
![bg right width:600px](colorblind.jpg)
---
## Color on a Page
![bg right](cmyk.svg)
Ink absorbs light, so we work with subtractive blending. Our base colors are cyan, magenta, and yellow. To save on ink costs, we throw in black/contrast as well.
We call this CMYK color.
---
## Color on a Screen
Screens emit light, which means we use **additive blending** of red, green, and blue light. Every pixel of a screen can emit these three colors in different intensities.
![bg right](additive.png)
---
## Color Spaces
Ways of describing a color mathematically, usually have 3 components to match our perception of color:
- RGB (early photography)
- CIE XYZ (1931)
- HSB/HSV/HSL (1970s)
![bg right width:700px](rgb-khan.jpg)
<!-- https://commons.wikimedia.org/wiki/File:Rgb-compose-Alim_Khan.jpg -->
---
A common way to refer to colors is by their intensity in each of these three channels.
<span style="color: rgb(0% 100% 0%)">this is 0% red, 100% green, 0% blue intensity (#00ff00)</span>
<span style="color: rgb(20% 60% 20%)">this is 20% red, 60% green, 20% blue intensity: (#143c14)</span>
<span style="color: #ff00ff">this is 100% red, 0% green, 100% blue intensity: #ff00ff</span>
This is sometimes expressed in hexadecimal:
![height:120px](hexrgb.png)
![bg right](rgb-pixels.jpg)
---
### RGB space as a cube
![cube](LinearRGBCube.png)
---
### RGB as pair plots
![pair plots](RGBPairPlots.png)
Remember this trick for your own 3-dimensional data!
---
![height:500px](TriangleSliceRGB.png)
A slice through the middle of the cube gives colors of comparable brightness. (You may have seen such a triangle in color pickers.)
---
## HSL
![height:500px](HSL.png)
An alternative color space that's very useful for visualization is HSL color space.
Hue, Saturation, Lightness | <https://hslpicker.com/>
---
## Aside: What about "alpha"?
You will often see a fourth channel: RGB**A**, HSL**A**.
This is known as alpha transparency (translucency).
This has to do with how the program in question *blends* the colors. The final pixel values on the screen will still be converted to RGB components.
- Use sparingly.
- Variations are very subtle, and background dependent.
<!-- image source: https://upload.wikimedia.org/wikipedia/commons/3/34/RGB_pixels.jpg -->
---
## CIE (RGB / XYZ / CIELAB)
Based on human perception experiments where people would adjust dials to recreate colors out of red, green, and blue light.
First from 1920s, revised in 1970s.
*Commission internationale de l'éclairage* (Illumination)
![bg right](cie-xyz.png)
---
## Screen Gamut
Screens can't show the entire range of visible colors accurately, they define a "gamut". Since ~1996 most devices aim at a standard gamut to ensure similar representations of color, but even high end devices are not perfectly aligned.
![bg right](gamut2.png)
Projectors (like the one you're likely viewing this on) usually have skewed gamut.
Moral of the story: **Consider your medium!**
---
## What does all this mean for visualization?
Color choices should be made with respect to:
- medium (screen vs. print, type of screen)
- audience (culture, vision differences, expectations)
- differentiability
---
## Role of Color
- **Identify** - Different color per category/actor.
- opt for distinct hues
- **Group** - Group like entities using same/like colors.
- often with similar hues
- **Layer** - Overlay different information while keeping contrast.
- saturation differences very important to not overwhelm eye
- **Highlight** - Call out important/relevant information.
- brightness and hue differences important
---
## Color Channels & Data Types
### Lightness is perceived as ordered
Good for **Ordinal** variables
![height:50px](ordinal.png)
**Quantitative** (Continuous) variables harder to discern
![height:50px](qual.png)
### Hue typically unordered
**Nominal** variables.
![height:50px](nominal.png)
---
### Types of Palettes
- Qualitative - Nominal data
- Sequential - Quantitative data
- Diverging - Data with a meaningful zero-point (increase/decrease, more/less)
![](palette-types.jpg)
<!-- source: Peter Aldhous, NICAR 2016 -->
---
### Hue Separation
Pick distinct hues for unrelated variables.
Grouped schemes can be used where there are relationships among the categories.
![bg left width:600px](vega-schemes.png)
<https://vega.github.io/vega/docs/schemes/>
---
## Color Tips
- Aim for no more than ~6 colors that need to be distinguished.
- Colors should be distinct & differentiable by name.
- Be mindful of cultural considerations & symbolism.
- Ensure color schemes chosen appropriately for types of data.
- "Get it right in black & white"
---
## "Get it right in black & white"
A common mantra among visual designers.
Ensure that your hues have different brightness levels.
Ensure that you aren't using hue alone for your image.
![bg left width:600px](vega-schemes-bw.jpg)
---
## Text Legibility
An important issue when using colored text and/or backgrounds is **legibility**.
Web Content Accessibility Guidelines require a 4.5 color contrast (3:1 for large text).
Minimize *saturation* in backgrounds, pick a font color with opposing *lightness*.
<https://webaim.org/resources/contrastchecker/>
![bg left width:600px](contrast.png)
---
## Tools
- Vega Schemes: https://vega.github.io/vega/docs/schemes/
- Contrast/theme exploration: https://schubert-da.github.io/dataviz-palette-tool/
- Theme exploration for cartography: <https://colorbrewer2.org/>
- Color-theory based theme creator: https://meodai.github.io/poline/
- Theme creator w/ theme sharing: https://coolors.co
- HSL/RGB picker: <https://hslpicker.com/>
- Contast checker: <https://webaim.org/resources/contrastchecker/>
### Color-Blindness
- MacOS/iOS app: https://michelf.ca/projects/sim-daltonism/
- Browser extensions (search "colorblindness" in your browser of choice)
---
## Acknowledgements & References
Thanks to Alex Hale, Andrew McNutt, and Jessica Hullman for sharing their materials.
Color space images are from <https://jamie-wong.com/post/color/>, which is an incredible resource if you'd like to go deeper into both the biology and math of color.
- https://www.math.csi.cuny.edu/~mvj/GC-DataViz-S23/lectures/L6.html
- https://en.wikipedia.org/wiki/Stevens%27s_power_law
- https://colorusage.arc.nasa.gov
- https://vega.github.io/vega/docs/schemes/

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
03.charts/1080.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
03.charts/5920.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

77
03.charts/Untitled.ipynb Normal file
View File

@ -0,0 +1,77 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "52cc5dd5-93ce-4370-adc0-8842764a359e",
"metadata": {},
"outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'vega_datasets'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01maltair\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01malt\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mvega_datasets\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m data\n\u001b[1;32m 4\u001b[0m source \u001b[38;5;241m=\u001b[39m data\u001b[38;5;241m.\u001b[39mstocks()\n\u001b[1;32m 6\u001b[0m lines \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 7\u001b[0m alt\u001b[38;5;241m.\u001b[39mChart(source)\n\u001b[1;32m 8\u001b[0m \u001b[38;5;241m.\u001b[39mmark_line()\n\u001b[1;32m 9\u001b[0m \u001b[38;5;241m.\u001b[39mencode(x\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdate\u001b[39m\u001b[38;5;124m\"\u001b[39m, y\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mprice\u001b[39m\u001b[38;5;124m\"\u001b[39m, color\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msymbol\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 10\u001b[0m )\n",
"\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'vega_datasets'"
]
}
],
"source": [
"import altair as alt\n",
"from vega_datasets import data\n",
"\n",
"source = data.stocks()\n",
"\n",
"lines = (\n",
" alt.Chart(source)\n",
" .mark_line()\n",
" .encode(x=\"date\", y=\"price\", color=\"symbol\")\n",
")\n",
"\n",
"xrule = (\n",
" alt.Chart()\n",
" .mark_rule(color=\"cyan\", strokeWidth=2)\n",
" .encode(x=alt.datum(alt.DateTime(year=2006, month=\"November\")))\n",
")\n",
"\n",
"yrule = (\n",
" alt.Chart().mark_rule(strokeDash=[12, 6], size=2).encode(y=alt.datum(350))\n",
")\n",
"\n",
"\n",
"lines + yrule + xrule"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a208413-acd4-4ec5-a4ac-3e77558ec9bb",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

BIN
03.charts/age-junk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 979 KiB

BIN
03.charts/area.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
03.charts/bars.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
03.charts/bubble.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
03.charts/bump.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
03.charts/crochet.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

BIN
03.charts/eec.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

290
03.charts/examples.ipynb Normal file

File diff suppressed because one or more lines are too long

BIN
03.charts/facet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
03.charts/fox-bar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
03.charts/francetrains.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
03.charts/heatmap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
03.charts/labeled.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
03.charts/lhc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 KiB

BIN
03.charts/liefactor.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
03.charts/lines.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
03.charts/london-trees.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
03.charts/nyt1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

BIN
03.charts/nyt2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 KiB

BIN
03.charts/obama-treemap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
03.charts/pie-many.avif Normal file

Binary file not shown.

BIN
03.charts/pyramid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
03.charts/rankline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
03.charts/sizecycle.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

273
03.charts/slides.html Normal file

File diff suppressed because one or more lines are too long

373
03.charts/slides.md Normal file
View File

@ -0,0 +1,373 @@
---
theme: custom-theme
---
# Chart Design
## CAPP 30239
---
## Today
- What general **principles of visual design** are relevant to our work?
- What are the **common types of charts** and how do we use them?
- When and how do we break the rules?
---
## Edward Tufte
### The Visual Display of Quantitative Information
![](tufte.png)
---
## Key Ideas
- Graphical Integrity: Above all else, show the data.
- Maximize the data-ink ratio.
- Minimize chart junk.
- Aim for high chart density, consider *small multiples*.
- Revision & Editing are essential.
---
## Tufte's Principles for **Graphical Integrity**
---
1. The representation of numbers, as physically measured on the surface of the graphic itself, should be directly **proportional** to the numerical quantities represented.
![](liefactor.jpg)
Mileage increase: 53%
Graph length increase: 783%
"Lie Factor": 14.8x
---
2. Clear, detailed and thorough **labeling** should be used to defeat graphical distortion and ambiguity.
![bg left](spinal.webp)
How many children get a spinal injury every year? (out of 74,000,000 children in US)
Note: there are only 22,000 total spinal cord injuries a year in America (and most are 16-30yo).
<!-- .0000003% -->
---
3. Write out explanation of the data on the graphic itself. **Label important events** in the data.
![bg right width:600px](labeled.png)
---
4. Show **data variation, not design variation**.
Deflated & standardized units of money are almost almost superior to nominal units.
The number of information-carrying (variable) dimensions depicted should not exceed the number of dimensions in the data. (roughly 1:1 channel mapping)
Exception: It is OK/common to pair color & shape, or for print color & texture to address issues that color presents.
---
## Axes/Scale Mistakes
- Carefully consider not starting at zero.
- Beware dual axes.
- Consider audience when using log scale.
- Related: No pie charts that don't add up to 100%
---
![bg fit](tools_misleading_axes.png)
---
![bg fit](fox-bar.jpg)
---
![bg vertical fit](1080.png)
---
![bg fit](5920.png)
---
## Data-Ink Ratio
- **Data-ink**: Ink (pixels) used to show data.
- Data-ink ratio: data-ink / total-ink
![](francetrains.jpg)
---
![](eec.gif)
![bg right width:600px](sizecycle.gif)
---
## Optimizing Data Density
Number of entries in DataFrame / Area of Graphic.
Classic example of high data density is the sparkline, which can fit on a line of text.
![](sparkline.png)
---
![bg left height:700px](age-junk.png)
## Chart Junk
Anything that isn't relevant to understanding the data.
---
![](chartjunk-bullet.webp)
via junkcharts.typepad.com
---
## Common Chart Types
---
## How to Pick?
- Quantitative / Quantitative:
- Quantitative / Temporal:
- Quantitative / Nominal:
- Nominal / Nominal:
---
### Bar Charts & Histograms
- X/Y: Nominal (Binned Numerical - Histogram)
- Y/X: Quantitative
- Area must be relevant on bar charts: no log scales/cut axes!
![](bars.png)
---
### Line & Area Charts
- X: Temporal / Quantitative
- Y: Quantitative (means / sums)
![bg right width:600px](lines.png)
---
### When to use stacked area charts?
![bg left width:600px](area.png)
Sum of stacked axis variable **must have meaning**.
---
### Heatmap
![bg right width:600px](heatmap.png)
- X & Y: Quantitative or Nominal
- Color: Quantitative
- `mark_rect`
---
### Strip Plot
![bg left width:600px](strip.png)
- Y: Nominal
- X: Temporal or Quantitative
- Color: Optional (any type)
- `mark_tick`
---
### Pie / Donut / Radial Charts
![bg right fit](pyramid.png)
Theta: Quantitative (ratio)
Color: Nominal
Direct comparison of segments is very difficult at n > 2.
Only use when most important information is ratio between sizes, and relatively few categories.
**Must add up to 100%**
---
![](pie-comparison.png)
https://www.storytellingwithdata.com/blog/2020/5/14/what-is-a-pie-chart
---
### Bump / Rank Line Chart
![width:200px left](rankline.png)
![width:500px left](bump.png)
Useful for showing changes in relative positioning.
Require some data manipulation using `transform_window` or pre-computing ranks. (see Altair gallery examples.)
---
### Scatter & Bubble Plots
![bg left width:600px](bubble.png)
- X / Y: Quantitative
Bubble charts use size as a 3rd dimension.
(Note subtle but useful transparency usage as well.)
---
### Small Multiples / Faceting
![facet](facet.png)
![bg right fit](small-maps.png)
<!-- source: https://www.juiceanalytics.com/writing/better-know-visualization-small-multiples -->
Useful when there is a nominal variable being compared across two other dimensions.
---
![bg fit](obama-treemap.png)
<!-- source https://obamawhitehouse.archives.gov/interactive-budget -->
---
### Map Basics
Two most common:
- point maps
- choropleths
![bg left width:600px](london-trees.png)
*Image: Trees in London, data.london.gov.uk*
<!-- source: https://data.london.gov.uk/dataset/local-authority-maintained-trees#:~:text=The%20data%20does%20not%20represent,streets%2C%20private%20gardens%20and%20more. -->
**We will revisit maps later in this course.**
---
## Two choropleths, same data.
![bg right vertical width:600px](arcgis-chorolpleth.png)
![bg right width:600px](arcgis-choropleth2.png)
<!-- source: https://carto.maps.arcgis.com/apps/webappviewer/index.html?id=7475c5788efe4c75a9642f552f61d568 -->
Color scale & unit of measurement is incredibly important.
Consider alternatives if district/population sizes vary significantly.
---
## When & How to Break the Rules
**When in doubt...**
9 out of 10 visualizations should be some variation of the common types.
This does not need to hamper creativity, in the right context a little flourish can add a lot. But ensure that it does not obfuscate the data.
Focus on Tufte's principles & ask for feedback!
---
### Case Study: Two Innovations
Two visualization types that have had their moment in the past 10-15 years:
- Hex/Grid Maps
- Word Clouds
---
## Grid Map
![](npr-side-by-side.png)
Introduced in <https://blog.apps.npr.org/2015/05/11/hex-tile-maps.html>
<!-- discuss: is this a good thing? -->
---
## Word Cloud
![](word-cloud.jpg)
---
![bg left](nyt1.png)
![](nyt2.png)
Derived from same data as word cloud.
source: NYTimes via https://www.niemanlab.org/2011/10/word-clouds-considered-harmful/
---
## Narrative-supporting graphics
![bg left width:500px](crochet.jpg)
by ulaniulani on flickr
---
### When it's OK to use 3D
You have data that relates to a spatial third dimension.
![bg vertical right](snowfall.png)
![bg right fit](lhc.png)
(Image: Snowfall, NY Times)
(Image: CERN Large Hadron Collider)
---
## Acknowledgements & References
Thanks to Alex Hale, Andrew McNutt, and Jessica Hullman for sharing their materials.
- https://www2.cs.uh.edu/~ceick/NO/COSC3337-DV2.pdf
- Images from Tufte's Visual Display of Quantitative Information
- Images from Altair <https://altair-viz.github.io/gallery/index.html>

BIN
03.charts/small-maps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

BIN
03.charts/snowfall.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
03.charts/sparkline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

BIN
03.charts/spinal.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
03.charts/strip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 KiB

BIN
03.charts/tufte.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

BIN
03.charts/word-cloud.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

BIN
03.charts/word-cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@ -1,4 +1,7 @@
preview lecture:
marp -pw --html --theme custom-theme.css {{lecture}}/slides.md
slides:
for file in `ls */slides.md`; do \
marp $file; \
marp --theme custom-theme.css $file; \
done

11
custom-theme.css Normal file
View File

@ -0,0 +1,11 @@
/* custom-theme.css */
/* @theme custom-theme */
@import "default";
.container {
display: flex;
}
.col {
flex: 1;
}

View File

@ -10,4 +10,5 @@ dependencies = [
"pandas>=2.2.3",
"polars>=1.8.2",
"ruff>=0.6.8",
"vega-datasets>=0.9.0",
]

14
uv.lock generated
View File

@ -16,6 +16,7 @@ dependencies = [
{ name = "pandas" },
{ name = "polars" },
{ name = "ruff" },
{ name = "vega-datasets" },
]
[package.metadata]
@ -25,6 +26,7 @@ requires-dist = [
{ name = "pandas", specifier = ">=2.2.3" },
{ name = "polars", specifier = ">=1.8.2" },
{ name = "ruff", specifier = ">=0.6.8" },
{ name = "vega-datasets", specifier = ">=0.9.0" },
]
[[package]]
@ -1696,6 +1698,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 },
]
[[package]]
name = "vega-datasets"
version = "0.9.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pandas" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8f/a0/ce608d9a5b82fce2ebaa2311136b1e1d1dc2807f501bbdfa56bd174fff76/vega_datasets-0.9.0.tar.gz", hash = "sha256:9dbe9834208e8ec32ab44970df315de9102861e4cda13d8e143aab7a80d93fc0", size = 215013 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e6/9f/ca52771fe972e0dcc5167fedb609940e01516066938ff2ee28b273ae4f29/vega_datasets-0.9.0-py3-none-any.whl", hash = "sha256:3d7c63917be6ca9b154b565f4779a31fedce57b01b5b9d99d8a34a7608062a1d", size = 210822 },
]
[[package]]
name = "wcwidth"
version = "0.2.13"