prettyplotlib.plot

The default matplotlib color cycle is not pretty to look at ... It was taken from MATLAB's color cycle. Need to do this example first because prettyplotlib changes the default color cycle to a nicer one, from ColorBrewer's Set2.


In [1]:
import matplotlib.pyplot as mpl_plt
# Set the random seed for consistency
np.random.seed(12)

fig, ax = mpl_plt.subplots(1)

# Show the whole color range
for i in range(8):
    y = np.random.normal(size=1000).cumsum()
    ax.plot(y, label=str(i))

ax.legend()
    
ax.set_title('prettyplotlib `plot` example\nshowing default matplotlib `plot`')
fig.savefig('plot_matplotlib_default.png')


Yeah.. not nice. I used to have to do all kinds of modifications to get the plots that I wanted:


In [2]:
import matplotlib.pyplot as mpl_plt
import brewer2mpl

# Get Colorbrewer colors
set2 = brewer2mpl.get_map('Set2', 'qualitative', 8).mpl_colors

# Set the random seed for consistency
np.random.seed(12)

fig, ax = mpl_plt.subplots(1)

# Show the whole color range
for i in range(8):
    y = np.random.normal(size=1000).cumsum()
    color = set2[i]
    ax.plot(y, label=str(i), color=color)

# Remove top and right axes lines ("spines")
spines_to_remove = ['top', 'right']
for spine in spines_to_remove:
    ax.spines[spine].set_visible(False)

# Get rid of ticks. The position of the numbers is informative enough of
# the position of the value.
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')

# For remaining spines, thin out their line and change the black to a slightly off-black dark grey
almost_black = '#262626'
spines_to_keep = ['bottom', 'left']
for spine in spines_to_keep:
    ax.spines[spine].set_linewidth(0.5)
    ax.spines[spine].set_color(almost_black)

# Change the labels to the off-black
ax.xaxis.label.set_color(almost_black)
ax.yaxis.label.set_color(almost_black)

# Change the axis title to off-black
ax.title.set_color(almost_black)

# Remove the line around the legend box, and instead fill it with a light grey
# Also only use one point for the scatterplot legend because the user will 
# get the idea after just one, they don't need three.
light_grey = np.array([float(248)/float(255)]*3)
legend = ax.legend(frameon=True, scatterpoints=1)
rect = legend.get_frame()
rect.set_facecolor(light_grey)
rect.set_linewidth(0.0)

# Change the legend label colors to almost black, too
texts = legend.texts
for t in texts:
    t.set_color(almost_black)

    
ax.set_title('prettyplotlib `plot` example\nshowing default matplotlib `plot`')
fig.savefig('plot_matplotlib_improved.png')


But.... that got really annoying to have to modify the exact same things every time I wanted to make a plot. So I made prettyplotlib. This is how you call it:

import prettyplotlib as ppl

# prettyplotlib imports 
from prettyplotlib import plt
from prettyplotlib import mpl
from prettyplotlib import brewer2mpl
...
ppl.plot(ax, x, y, label=str(i))
...
ppl.legend(ax)

Notice that it's not a simple switcheroo with ax.plot and ax.legend, that ppl.plot must take an ax as its first argument.


In [1]:
import prettyplotlib as ppl

# prettyplotlib imports 
import matplotlib.pyplot as plt
from prettyplotlib import brewer2mpl

# Set the random seed for consistency
np.random.seed(12)

fig, ax = plt.subplots(1)

# Show the whole color range
for i in range(8):
    y = np.random.normal(size=1000).cumsum()
    x = np.arange(1000)

    # For now, you need to specify both x and y :(
    # Still figuring out how to specify just one
    ppl.plot(ax, x, y, label=str(i), linewidth=0.75)
    
ppl.legend(ax)

fig.savefig('plot_prettyplotlib_default.png')


And of course you can change the location and other parameters of the legend as you see fit. Here, we put the legend in the lower left corner and force it to be in 4 columns instead of one with:

ppl.legend(ax, loc='lower left', ncol=4)

In [5]:
import prettyplotlib as ppl

# prettyplotlib imports 
import matplotlib.pyplot as plt
from prettyplotlib import mpl
from prettyplotlib import brewer2mpl

# Set the random seed for consistency
np.random.seed(12)

fig, ax = plt.subplots(1)

# Show the whole color range
for i in range(8):
    y = np.random.normal(size=1000).cumsum()
    x = np.arange(1000)

    # For now, you need to specify both x and y :(
    # Still figuring out how to specify just one
    ppl.plot(ax, x, y, label=str(i))
    
ppl.legend(ax, loc='lower left', ncol=4)

fig.savefig('plot_prettyplotlib_legend_lower_left.png')


Now that's pretty nice!

A few things happened here:

  1. Default color cycle changed to the colors of ColorBrewer's Set2
  2. Removed top and right axis lines
  3. Ever-so-subtly changed the ticklabel and axis line colors from black (#000000) to almost black (#262626)
  4. On the legend, removed the black frame and filled the body of the legend with a light grey.