Python-Generated Color Themes for Design System

Fuyen Hsiao
7 min readMar 2, 2023

--

Design systems are an integral part of creating effective and cohesive user interfaces. In this post, I’ll dive into the process of developing a color palette for AirBrush, a digital photo editing app. I’ll explore how to create a balanced and harmonious color theme using an auto-color generator tool and the impact it had on the app’s success.

About AirBrush

iOS & Android Photo Editor

  • +100M Downloads worldwide
  • +167K 5-Star iOS ratings
  • US #9 in iOS Photo & Video app category

Auditing the Current Color Palette

Starting with auditing the current color palette with engineers, I found many previous color attempts with different arbitrary names in the code base, like “orangePrimary”, “orange2”, “lemonYellow”, “blushPink” pointed to similar shades of orange, and red.

In order to make decisions on what colors to keep in the product, I put colors into 2 groups that serve different business purposes, and mapped them on a color wheel to visualize their relationships:

  1. Orange Group: Our branding colors
  2. Red Group: Special promotion theme colors

Ensuring Accessibility

Next, I looked into the accessibility for each color through contrast tests. The goal was to pass the “WCAG AA” standard on the Large Text, and the Graphic Objects categories. Any color that failed would be removed. However, the result was- none of the colors in the orange group pass the contrast test with the white background! To ensure app’s accessibility, I needed to created a new color with a lower lightness to pass the test.

As a result, I had 2 base colors that pass the contrast test. These colors will serve as the foundation for the new color palette, and from here, I will be able to build out a full color theme.

Creating the Theme

With the base colors, I began the process of building out a complete color theme. Starting with defining theme’s function:

A theme made of a sequence of color swatches
  1. The base color- Theme60: The base color is the dominate tone across the app. I defined that it always should be 60 in light mode, and 50 in dark mode. Both contrast ratios are higher than 3.03 (WCAG AA ready).
  2. Auxiliary colors- Near Theme60: They will be used for visual feedback, like mobile’s pressed state or the hover state for web/desktop based platforms.
  3. Accent colors- Both ends: These colors can be used as the elevated background of a selected item in a popover or a dropdown in both light and dark modes.

Building a Color Generator

Alright, let’s get to the main point of this article.

Achieving a balanced and harmonious color scale often requires many iterations. To avoid spending excessive amounts of time manually tweaking color values, I created a simple Python environment that allowed me to explore a variety of HSL color settings.

  1. Input: R, G, B value
  2. The code will transform the RGB color into HSL
  3. Set H, S, L values and play around with them.
Auto color scale tool visualized by Matplotlib

It’s basically a function that takes H, L, S value inputs. I can set some rules to change each value, and append them on a list.

To print out the result as a bar diagram, I used the Matplotlib library to visualize the color scale.

Why HSL?

In the HSL space, we can manipulate colors with saturation and lightness, which separates lightness into its own dimension. Unlike HSB, this can adjust lightness without affecting saturation.

Hue-agnostic Approach

While there is no definitive best practice for choosing colors, it is important to establish some guiding principles. In consideration of the potential expansion of our base colors in the future, I opted for a Hue-agnostic approach.

This means that the HSL palette is not tied to any specific hue, allowing it to be applied uniformly across colors of any hue.

I created a diagram with saturation on the x-axis and lightness on the y-axis. By using this diagram, I was able to identify patterns in saturation and lightness levels that could be used to generate a new palette in the future, if needed.

Orange and blue hue share the similar color attribute pattern

Playing Around

I started with playing around the parameters I set, like adding or decreasing saturation or lightness levels. After creating a couple of arbitrary scales, I realized that without a holistic process, it would be impossible to get a smooth color transition.

Examples of some early stage color scale

Selecting the Right Curve Type

Through experimentation, I discovered that the scatter pattern was closely tied to the smoothness of the colors being used. Based on this observation, I decided to explore the effect of different curve shapes on the final outcome.

To put this theory to the test, I began by setting the start color to Theme10 and the end color to Theme100, and generated a series of intermediate colors using three different interpolation types.

  1. Linear
  2. Positive Curvature- Bezier
  3. Negative Curvature- Log
3 curve shapes that reflects lightness and saturation levels

After conducting the experiment, the results were quite interesting. I observed noticeable uneven transitions in both the Linear and Positive Curvature scales, while the Negative Curvature scale produced the smoothest and most dynamic outcome.

Adding the Middle Color

Next, I had to include the Base Color in the scale based on the Negative Curvature color curve.

I made adjustments to the script to generate a spline that passed through three key points: the Start Color (Theme10), Middle Color (Theme50), and End Color (Theme100), and interpolated colors in between.

After a few adjustments, I ultimately settled on the outcome shown below due to its smooth transition and dynamic range of colors.

The spline curve made with Scipy
Using the Spline Interpolation

Finally, I applied this rule, and generated the red, and grey scales. Please note that grey does not have a hue value, as it is represented as a line.

Manually Testing Colors

Although the color generator was a valuable tool in the creation of an effective and visually appealing user interface, it was just one aspect of the overall design process. Ultimately, manual testing of colors was essential to achieving the final look and feel of the interface, particularly with regards to the dark theme.

Result & Impact

Before

Previously, the AirBrush color palette lacked any cohesive structure.

After

After implementing a comprehensive design system, the AirBrush color palette is now well-organized and structured.

Color palette example
Color token guide

The structured color palette has also allowed for greater flexibility and customization when designing new features and updates, while maintaining a consistent and recognizable brand identity.

Overall, the implementation of a structured color palette has had a significant impact on the success and growth of AirBrush.

Reflection

Exploring different approaches to building color themes has been an enjoyable experience, and having an auto tool at your pocket can make the process more efficient.

However, it’s also important to consider that developing such a tool requires investment of time, especially for a none-programmer like me. While the auto-generator may be overkill for a smaller app like AirBrush, it has the potential to be valuable for larger projects with more complex color creating process.

Reference

Designing Systematic Colors- Jeeyoung Jung

Mastering Multi-hued Color Scales with Chroma.js- Gregor Aisch

--

--