Color and Style
In our
previous tutorial
which explored form as a preattentive feature, we investigated
drawing different shapes. In this tutorial, we continue Skills Lab 3
by looking at our next preattentive features: color. Indeed, color
is one part of a broader set of glyph attributes often referred to
simply as style. This suite of options can help as important
encoding device and, when used together with other preattentive
features, can help increase data density.
Contents
Hex Codes
Our glyphs can actually have multiple potential colors at the
same time. However, the first step is finding the color we want.
We discussed some options in class:
ColorBrewer
and
I Want Hue
both provide good options. If you have Python installed on your
machine, you might also take a look at
Viscm. Finally, if you just need to manipulate some colors, a great
tool is
HSL Color Picker, which can work on multiple color spaces at the same time. All
that said, many (maybe most) tools will work with hex codes or
offer hex codes as an option. I'll be using those color codes
below but you can see what they correspond to (and change them)
using HSL Color Picker. Indeed, many of these colors will come
from ColorBrewer. On that note, be sure to check out a short
hex code primer
if you are unfamiliar with color hex codes.
Fill
The easiest place to start for styling in
Sketchingpy
is the fill color for a shape. Let's use circles to demonstrate!
Here, we can draw circles with different colors as well one
circle which has no fill (will pass through to any figures drawn
behind):
import sketchingpy
sketch = sketchingpy.Sketch2D(500, 500)
sketch.set_fill("#a6cee3")
sketch.draw_ellipse(150, 250, 100, 100)
sketch.clear_fill()
sketch.draw_ellipse(250, 250, 100, 100)
sketch.set_fill("#b2df8a")
sketch.draw_ellipse(350, 250, 100, 100)
sketch.show()
Try using some of our color tools to specify a different fill
color!
Transparency
With our circles overlapping, we notice that what is drawn first
goes at the bottom and is obsurced by whatever is drawn
afterwards. This is called the
Painter's Algorithm
which basically says you should draw your scene from back to
front. Let's let the user peer through those overlapping shapes
though by adding transparency to our color. Appending two
additional numbers to our hex codes specifies opacity where 00
means fully transparent and FF means fully opaque.
import sketchingpy
sketch = sketchingpy.Sketch2D(500, 500)
sketch.set_fill("#a6cee399")
sketch.draw_ellipse(150, 250, 100, 100)
sketch.clear_fill()
sketch.draw_ellipse(250, 250, 100, 100)
sketch.set_fill("#b2df8a99")
sketch.draw_ellipse(350, 250, 100, 100)
sketch.show()
Try changing the order in which the colors are set and the
opacity part of the color code.
Stroke
So far, we've been manipulating the insides of our circles.
Let's change the outsides. Same thing as before, let's have one
circle that's different.
import sketchingpy
sketch = sketchingpy.Sketch2D(500, 500)
sketch.set_stroke("#1f78b4")
sketch.clear_fill()
sketch.draw_ellipse(150, 250, 100, 100)
sketch.set_fill("#C0C0C0")
sketch.clear_stroke()
sketch.draw_ellipse(250, 250, 100, 100)
sketch.set_stroke("#33a02c")
sketch.clear_fill()
sketch.draw_ellipse(350, 250, 100, 100)
sketch.show()
Try changing the colors again. When the area is smaller, is the
contrast needed for readability higher?
Weight
Let's continue that thought around the size of these areas. We
change the stroke width through its weight:
import sketchingpy
sketch = sketchingpy.Sketch2D(500, 500)
sketch.set_stroke_weight(3)
sketch.set_stroke("#1f78b4")
sketch.clear_fill()
sketch.draw_ellipse(150, 250, 100, 100)
sketch.set_fill("#C0C0C0")
sketch.clear_stroke()
sketch.draw_ellipse(250, 250, 100, 100)
sketch.set_stroke("#33a02c")
sketch.clear_fill()
sketch.draw_ellipse(350, 250, 100, 100)
sketch.show()
Try changing the strokes such that the first and last circle
have different weights.
Context
Before we move on to the transformation matrix, we have a chance
to play with some of the concepts around relative color
interpretation and figure / ground as discussed in lectures. Try
this sketch out for a moment which uses colors which could be
useful for a quantitative scale:
import sketchingpy
sketch = sketchingpy.Sketch2D(500, 500)
sketch.clear('#FFFFFF')
sketch.set_ellipse_mode("radius")
def draw_circles(y):
sketch.set_stroke("#000000")
sketch.set_fill("#edf8fb")
sketch.draw_ellipse(150, y, 20, 20)
sketch.set_fill("#b2e2e2")
sketch.draw_ellipse(200, y, 20, 20)
sketch.set_fill("#66c2a4")
sketch.draw_ellipse(250, y, 20, 20)
sketch.set_fill("#2ca25f")
sketch.draw_ellipse(300, y, 20, 20)
sketch.set_fill("#006d2c")
sketch.draw_ellipse(350, y, 20, 20)
draw_circles(125)
sketch.set_rect_mode("corner")
sketch.clear_stroke()
sketch.set_fill("#555555")
sketch.draw_rect(0, 250, 500, 250)
draw_circles(375)
sketch.show()
Note that this uses
clear. Let's assume for a moment that this is a
heatmap. We don't have a color scale listed. However, based on the
background, which dot do you think corresponds to the highest
and lowest number? Does your answer change depending on the
background? It is possible that, using the concept of figure /
ground from lecture, you may think the color with the highest
luminance contrast corresponds to the highest number. That is a
common recommendation! In other words, the rightmost dot may be
seen as the highest in the top part of the graphic and the
leftmost dot may be seen as the highest in the bottom part of
the graphic.
Next
We are starting to build up a comprehensive set of tools to
bring into our data visualization work. Next, continue on to
Tutorial 6
to learn about the transformation matrix and our next
preattentive feature: position.
Citations
-
A. Pottinger, "Sketchingpy." Sketchingpy Project,
2024. [Online]. Available:
https://sketchingpy.org/
-
C. Brewer, M Harrower, and The Pennsylvania State
University, “Colorbrewer 2.0,†The Pennsylvania
State University, 2013. [Online]. Available:
https://colorbrewer2.org/
-
M. Jacomy, "I Want Hue," Sciences-Po Medialab, 2024.
[Online]. Available:
https://medialab.github.io/iwanthue/
-
B. Mathis "HSL Color Picker," 2024. [Online].
Available:
https://hslpicker.com/#ffd900
-
Matplotlib, "Viscm," 2023. [Online]. Available:
https://github.com/matplotlib/viscm?tab=readme-ov-file
-
N. Davies, "How Hex Code Colors Work," FreeCodeCamp,
2023. [Online]. Available:
https://www.freecodecamp.org/news/how-hex-code-colors-work-how-to-choose-colors-without-a-color-picker/
-
BCA Labs, "Painter's Algorithm in Computer
Graphics," BCA Labs, 2024. [Online]. Available:
https://bcalabs.org/subject/painter-algorithm-in-computer-graphics
-
Y. Holtz, "From Data to Viz." Data to Viz, 2018.
[Online]. Available:
https://www.data-to-viz.com/