Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color selection for matplotlib that prints well

I am using pandas and matplotlib to generate bar-graphs with lots of bars.

I know how to cycle through a list of selected colors (How to give a pandas/matplotlib bar graph custom colors). The question is what colors to select so that my graph prints nicely on a paper (it is for a research paper). What I am most interested in is sufficient contrast between the columns and a selection of colors that looks pleasant. I would like to have multiple colors instead of gray-scale or single-hue colorschemes.

Are there any predetermined schemes to select from that people use?

like image 691
vkontori Avatar asked Dec 20 '12 09:12

vkontori


3 Answers

So your requirements are "lots of colors" and "no two colors should map to the same grayscale value when printed", right? The second criteria should be met by any "sequential" colormaps (which increase or decrease monotically in luminance). I think out of all the choices in matplotlib, you are left with cubehelix (already mentioned), gnuplot, and gnuplot2:

3 colormaps, showing luminance and hue

The white line is the luminance of each color, so you can see that each color will map to a different grayscale value when printed. The black line is hue, showing they cycle through a variety of colors.

Note that cubehelix is actually a function (from matplotlib._cm import cubehelix), and you can adjust the parameters of the helix to produce more widely-varying colors, as shown here. In other words, cubehelix is not a colormap, it's a family of colormaps. Here are 2 variations:

enter image description here

enter image description here

For less wildly-varying colors (more pleasant for many things, but maybe not for your bar graphs), maybe try the ColorBrewer 3-color maps, YlOrRd, PuBuGn, YlGnBu:

3 colormaps with monotonic luminance but less hue variation

https://www.flickr.com/photos/omegatron/7298887952/

I wouldn't recommend using only this color to identify bar graphs, though. You should always use text labels as the primary identifier. Also note that some of these produce white bars that completely blend in with the background, since they are intended for heatmaps, not chart colors:

from matplotlib import pyplot as plt
import pandas, numpy as np  # I find np.random.randint to be better

# Make the data
x = [{i:np.random.randint(1,5)} for i in range(10)]
df = pandas.DataFrame(x)

# Make a list by cycling through the colors you care about
# to match the length of your data.
cmap = plt.get_cmap('cubehelix')
indices = np.linspace(0, cmap.N, len(x))
my_colors = [cmap(int(i)) for i in indices]

# Specify this list of colors as the `color` option to `plot`.
df.plot(kind='bar', stacked=True, color=my_colors)
gnuplot bar graph gnuplot2 bar graph cubehelix bar graph YlGnBu bar graph

And these are the new guys:

new guys colorbars viridis bar graph
like image 75
endolith Avatar answered Oct 22 '22 13:10

endolith


In 1.5 matplotlib will ship with 4 new rationally designed color maps:

  • 'viridis' (default color map as of 2.0)
  • 'magma'
  • 'plasma'
  • 'inferno'.

The process of designing these color maps is presented in A Better Default Colormap for Matplotlib | SciPy 2015 .

enter image description here

The tool developed for this process can be installed by pip install viscm.


I would suggest the cubehelix color map. It is designed to have correct luminosity ordering in both color and gray-scale.

like image 27
tacaswell Avatar answered Oct 22 '22 14:10

tacaswell


I am not aware of predetermined schemes. I usually use a few colours for publication plots. I mostly take two things into consideration when choosing colours:

  1. Colour-blindness: this page on wikipedia has lots of good info about choosing colours that are distinguishable to most color-blind people. If you notice on the "tips for editors" section, once you take the guidelines into account there are only a few sets of colours available. (A good rule of thumb is to never mix red and green!) You can also use the linked colour-blind simulators to see if your plot would be well visible.
  2. Luminance: most of the journals in my field will publish in B&W by default. Even though most people read the papers online, I still like to make sure that the plots can be understood when printed in grayscale. So I take care to use colours that have different luminances. To test, a good way is to just desaturate the image produced, and you'll have a good idea of how it looks when printed in grayscale. In many cases (particularly line or scatter plots), I also use other things than colour to distinguish between sets (eg. line styles, different markers).

If no colours are specified in matplotlib plots, it has a default set of colours that it cycles through. This answer has a good explanation on how to change that default set of colours. You can customise that to your preferred set of colours, so the plots would use them in turn.

like image 5
tiago Avatar answered Oct 22 '22 14:10

tiago