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. 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 ## Today
- Grammar of Graphics - What is a **grammar of graphics** and how do we use it in practice?
- Types of Data - What **types of data** do we encounter, and how does that affect visualizations?
- Intro to Altair - 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: slides:
for file in `ls */slides.md`; do \ for file in `ls */slides.md`; do \
marp $file; \ marp --theme custom-theme.css $file; \
done 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", "pandas>=2.2.3",
"polars>=1.8.2", "polars>=1.8.2",
"ruff>=0.6.8", "ruff>=0.6.8",
"vega-datasets>=0.9.0",
] ]

14
uv.lock generated
View File

@ -16,6 +16,7 @@ dependencies = [
{ name = "pandas" }, { name = "pandas" },
{ name = "polars" }, { name = "polars" },
{ name = "ruff" }, { name = "ruff" },
{ name = "vega-datasets" },
] ]
[package.metadata] [package.metadata]
@ -25,6 +26,7 @@ requires-dist = [
{ name = "pandas", specifier = ">=2.2.3" }, { name = "pandas", specifier = ">=2.2.3" },
{ name = "polars", specifier = ">=1.8.2" }, { name = "polars", specifier = ">=1.8.2" },
{ name = "ruff", specifier = ">=0.6.8" }, { name = "ruff", specifier = ">=0.6.8" },
{ name = "vega-datasets", specifier = ">=0.9.0" },
] ]
[[package]] [[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 }, { 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]] [[package]]
name = "wcwidth" name = "wcwidth"
version = "0.2.13" version = "0.2.13"