Showing posts with label color. Show all posts
Showing posts with label color. Show all posts

Monday, May 9, 2016

More colors for Matplotlib

 
The default Matplotlib color scheme is not good. While searching for something better for my thesis, I stumbled upon Bridget Riley's painting "Gather" in the RISD museum. Is uses five colors: white, black, ochre, blue, turquoise, and a rust-colored red. But, from a distance they combine to create something far more vibrant. The blue and the turquoise hues are similar, so perhaps not the best to combine in a plot, but the others form an attractive and distinct pallet:

White #f1f0e9
Black #44525c
Rust #eb7a59
Ochre #eea300
Azure #5aa0df
Turquoise #00bac9

Surprisingly, when I ran this through a color-blindness simulator , some colors become even more distinct, so it is fairly color-blind friendly. I added colors to expand the pallet, to handle gradients and plots with extra lines.

Yellow #efcd2b
Moss #77ae64
Mauve #b56ab6
Magenta #cc79a7
Violet #8d5ccd
Indigo #606ec3
Viridian #11be8d
Chartreuse #b59f1a

These are less distinct, and not all combinations are color-blind friendly. Here's a bit of Python to define and tests these colors:

from pylab import *
from matplotlib import patches

WHITE = mpl.colors.to_rgb('#f1f0e9') RUST = mpl.colors.to_rgb('#eb7a59') OCHRE = mpl.colors.to_rgb('#eea300') AZURE = mpl.colors.to_rgb('#5aa0df') TURQUOISE = mpl.colors.to_rgb('#00bac9') BLACK = mpl.colors.to_rgb('#44525c') YELLOW = mpl.colors.to_rgb('#efcd2b') INDIGO = mpl.colors.to_rgb('#606ec3') VIOLET = mpl.colors.to_rgb('#8d5ccd') MAUVE = mpl.colors.to_rgb('#b56ab6') MAGENTA = mpl.colors.to_rgb('#cc79a7') CHARTREUSE = mpl.colors.to_rgb('#b59f1a') MOSS = mpl.colors.to_rgb('#77ae64') VIRIDIAN = mpl.colors.to_rgb('#11be8d')

GATHER = [WHITE,RUST,OCHRE,AZURE,TURQUOISE,BLACK] COLORS = [BLACK,WHITE,YELLOW,OCHRE,CHARTREUSE,MOSS,VIRIDIAN,TURQUOISE,AZURE,INDIGO,VIOLET,MAUVE,MAGENTA,RUST] CYCLE = [BLACK,RUST,AZURE,OCHRE,TURQUOISE,MAUVE,YELLOW,INDIGO] mpl.rcParams['axes.prop_cycle'] = mpl.cycler(color=CYCLE)

def test_panel(COLORS): ax = gca() NCOLORS = len(COLORS) axis('off') xlim(0,NCOLORS) ylim(NCOLORS,0) for j in range(NCOLORS): for i in range(NCOLORS): ax.add_patch(patches.Rectangle((i,j),1,1,linewidth=1, edgecolor='none',facecolor=COLORS[i])) ax.add_patch(patches.Rectangle((i+.25,j+.25),.5,.5,linewidth=1, edgecolor='none',facecolor=COLORS[j])) axis('equal')

figure(figsize=(6,3),dpi=200) subplots_adjust(0,0,1,1,0.1,0) subplot(111) test_panel(COLORS) savefig('colorblind_test_panel.png',bbox_inches='tight',pad_inches=0) </pre></div>

Two squences form decent color maps. They aren't perceptually uniform, but pass the color blindness simulator tests. Adding violet, mauve, and moss, to the original Gather pallet creates a hue wheel. This one flunks color-blindness test (see Crameri et al. ). Here they are in python:

riley2 = matplotlib.colors.LinearSegmentedColormap.from_list('riley2',
    [INDIGO,VIOLET,MAUVE,MAGENTA,RUST,OCHRE])

riley3 = matplotlib.colors.LinearSegmentedColormap.from_list('riley3', [OCHRE,CHARTREUSE,MOSS,VIRIDIAN,TURQUOISE,AZURE])

# Smoothed out mauve, violet, rust, ochre, moss, turquoise, azure, in a loop hues = ['#8c62cc', '#9560c8', '#9e62c3', '#a765be', '#b068b6', '#bb6caa', '#c66f98', '#d27384', '#dd7670', '#e67c5c', '#ea8348', '#ec8b34', '#ec9421', '#e99c13', '#dea212', '#c9a620', '#b0a934', '#96ab4a', '#7cae60', '#62b076', '#48b38c', '#2eb5a2', '#1ab7b6', '#12b6c5', '#1cb2ce', '#2dadd4', '#41a7d8', '#529fdb', '#6194db', '#6d86d8', '#7977d4', '#836ad0'] riley = matplotlib.colors.LinearSegmentedColormap.from_list('riley',hues)

# Make new maps behave like native Matplotlib maps plt.register_cmap(name='riley2',cmap=riley2) plt.register_cmap(name='riley3',cmap=riley3) plt.register_cmap(name='riley' ,cmap=riley )

# Show as figure figure(figsize=(5,1),dpi=300) subplot(311) imshow([linspace(0,1,256)],cmap='riley2',aspect='auto') axis('off'); tight_layout() subplot(312) imshow([linspace(0,1,256)],cmap='riley3',aspect='auto') axis('off'); tight_layout() subplot(313) imshow([linspace(0,1,256)],cmap='riley',aspect='auto') axis('off'); tight_layout() subplots_adjust(hspace=0.3) savefig('moremaps.png') </pre></div>

Thursday, September 3, 2009

DIY ganzfeld flicker hallucination goggles

This post describes how to construct a pair of goggles that can be used to induce geometric visual hallucinations (1 2 3) via strobe light patterns. This tutorial should be accessible to anyone familiar with Arduino, and I do not cover details of the electronics design.

WARNING : this and similar projects have been known to induce seizures in susceptible individuals.


Device Summary

This device consists of three major components : a physical interface to provide the visual stimulation, electronics to control the physical interface, and code which governs the behavior of the interface. The physical interface consists of ping pong balls in swimming goggles with LEDs inside. The electronics are an Arduino pro-mini, and a few additional interface parts. The code is Arduino SDK C style driver code.

Component 1 : Physical Interface
Update : This later post suggests there might be an easier, faster, and more durable way to construct the goggles. The design posted here works fine, but is tricky and time consuming to make, and also fragile.

parts :
  • 4 to 10 Ping pong balls
  • 2 RGB LEDs, frosted clear casing (this is important, sand down the outside if not frosted)
  • 2 4x1 male headers, .1" spacing
  • 2 4x1 female headers, .1" spacing
  • 1 8x1 female header
  • 1 Dolfino medium sized silicone adult swim goggles ( had to buy in a 3 pack )
  • 2-3 ft of elastic ribbon
  • 3-4 ft of ribbon cable, only 8 channels required. Other cables with 8 channels also work.