In [1]:
%load_ext watermark
In [2]:
%watermark -u -v -d -p matplotlib,numpy,scipy
Last updated: 09/10/2014 

CPython 3.4.1
IPython 2.2.0

matplotlib 1.4.0
numpy 1.9.0
scipy 0.14.0

[More info](http://nbviewer.ipython.org/github/rasbt/watermark) about the `%watermark` extension

In [3]:
%matplotlib inline


Preparing Plots for Publication via matplotlib

Sometimes, we are not quite happy with matplotlib's default designs. Here are a few suggestions to adjust matplotlib's default plots so that they are more pleasing in the viewer's eye.

In this section, I will re-use certain settings for different types of plots, but if you'd like to change the settings globally (for the active session or even in the matplotlib settings) please see the section Applying customization and settings globally.

Sections



Errorbar Plots



Default Errorbar Plot

In [4]:
import matplotlib.pyplot as plt

def errorbar_default():

    # Data
    data = [1, 1.5, 1.2]
    std_devs = [0.15, 0.25, 0.12]

    # X axis positions
    x_pos = range(len(data))

    for d, std, x in zip(data, std_devs, x_pos):
        plt.errorbar(x=x, y=d, yerr=std, fmt='o')

    # setting axis limits   
    plt.xlim([min(x_pos)-1, max(x_pos)+1])    
    plt.ylim([min(data)*0.7, max(data)*1.3])  

    # setting labels and titles   
    plt.ylabel('x label')
    plt.title('Matplotlib default')

    plt.legend(['X1', 'X2', 'X3'], loc='upper right')

    plt.show()

Modified Errorbar Plot

In [7]:
import numpy as np
def errorbar_modified():

    # Data
    data = [1, 1.5, 1.2]
    std_devs = [0.15, 0.25, 0.12]

    # X axis positions
    x_pos = range(len(data))

    colors = ['lightblue', 'pink', 'lightgreen']

    fig = plt.gca()
    ax = plt.subplot(111)  

    # draw plots
    for d, std, col, x in zip(data, std_devs, colors, x_pos):
        plt.errorbar(x=x, y=d, yerr=std, fmt='o', color=col, ecolor='black')
    
    # setting axis limits    
    plt.xlim([min(x_pos)-1, max(x_pos)+1])    
    plt.ylim([min(data)*0.7, max(data)*1.3])  
    
    # setting labels and titles    
    plt.ylabel('x label')
    plt.text(1, 2, 'Modified',
         horizontalalignment='center',
         fontsize=14)

    # remove axis spines
    ax.spines["top"].set_visible(False)  
    ax.spines["right"].set_visible(False) 
    ax.spines["bottom"].set_visible(False) 
    ax.spines["left"].set_visible(False)

    # hiding axis ticks
    plt.tick_params(axis="both", which="both", bottom="off", top="off",  
                labelbottom="off", left="off", right="off", labelleft="on")

    # adding horizontal grid lines 
    ax.yaxis.grid(True)

    plt.legend(['X1', 'X2', 'X3'], loc='upper right', fancybox=True, numpoints=1)
    
    plt.tight_layout()
    plt.show()
In [8]:
errorbar_default()

In [9]:
errorbar_modified()



Boxplots

In [11]:
data = [np.random.normal(0, std, 50) for std in range(1, 4)]

Default Boxplot

In [12]:
import matplotlib.pyplot as plt
import numpy as np

def boxplot_default():

    fig = plt.figure(figsize=(8,6))

    plt.boxplot(data, 
            notch=False, # box instead of notch shape 
            sym='rs',    # red squares for outliers
            vert=True)   # vertical box aligmnent

    plt.xticks([y+1 for y in range(len(data))], ['x1', 'x2', 'x3'])
    plt.title('Matplotlib default')
    plt.show()

Modified Boxplot

In [23]:
def boxplot_modified():
    
    fig = plt.figure(figsize=(8,6))
    ax = plt.subplot(111) 

    bplot = plt.boxplot(data, 
            notch=True,          # notch shape 
            vert=True,           # vertical box aligmnent
            sym='ko',            # red circle for outliers
            patch_artist=True,   # fill with color
            )   

    # choosing custom colors to fill the boxes
    colors = ['pink', 'lightblue', 'lightgreen']
    for patch, color in zip(bplot['boxes'], colors):
        patch.set_facecolor(color)

    # modifying the whiskers: straight lines, black, wider
    for whisker in bplot['whiskers']:
        whisker.set(color='black', linewidth=1.2, linestyle='-')    
    
    # making the caps a little bit wider 
    for cap in bplot['caps']:
        cap.set(linewidth=1.2)
    
    # hiding axis ticks
    plt.tick_params(axis="both", which="both", bottom="off", top="off",  
            labelbottom="on", left="off", right="off", labelleft="on")

    # adding horizontal grid lines 
    ax.yaxis.grid(True) 
    
    # remove axis spines
    ax.spines["top"].set_visible(False)  
    ax.spines["right"].set_visible(False) 
    ax.spines["bottom"].set_visible(False) 
    ax.spines["left"].set_visible(False)

    plt.xticks([y+1 for y in range(len(data))], ['x1', 'x2', 'x3'])

    # raised title
    plt.text(2, 9, 'Modified',
         horizontalalignment='center',
         fontsize=18)

    plt.tight_layout()
    plt.show()
In [24]:
boxplot_default()

In [25]:
boxplot_modified()



Barplots



Default Barplot

In [26]:
import matplotlib.pyplot as plt

def barplot_default():   

    # input data
    mean_values = [1, 2, 3]
    variance = [0.2, 0.4, 0.5]
    bar_labels = ['bar 1', 'bar 2', 'bar 3']

    fig = plt.figure(figsize=(6,4))

    # plot bars
    x_pos = list(range(len(bar_labels)))
    plt.bar(x_pos, mean_values, yerr=variance, align='center')


    # set axes labels and title
    plt.ylabel('variable y')
    plt.xticks(x_pos, bar_labels)
    plt.title('Matplotlib default')

    plt.show()

Modified Barplot

In [30]:
import matplotlib.pyplot as plt

def barplot_modified():

    # input data
    mean_values = [1, 2, 3]
    variance = [0.2, 0.4, 0.5]
    bar_labels = ['bar 1', 'bar 2', 'bar 3']

    fig = plt.figure(figsize=(6,4))
    ax = plt.subplot(111) 
    
    # plot bars
    x_pos = list(range(len(bar_labels)))
    plt.bar(x_pos, mean_values, yerr=variance, 
            ecolor='black', # black error bar color
            alpha=0.5,      # transparency
            width=0.5,      # smaller bar width
            align='center')

    # set height of the y-axis
    max_y = max(zip(mean_values, variance)) # returns a tuple, here: (3, 5)
    plt.ylim([0, (max_y[0] + max_y[1]) * 1.1])

    # hiding axis ticks
    plt.tick_params(axis="both", which="both", bottom="off", top="off",  
            labelbottom="on", left="off", right="off", labelleft="on")

    # adding horizontal grid lines 
    ax.yaxis.grid(True) 
    
    # remove axis spines
    ax.spines["top"].set_visible(False)  
    ax.spines["right"].set_visible(False) 
    ax.spines["bottom"].set_visible(False) 
    ax.spines["left"].set_visible(False)

    # set axes labels and title
    plt.ylabel('variable y')
    plt.xticks(x_pos, bar_labels)
    
    plt.text(1, 4, 'Modified',
         horizontalalignment='center',
         fontsize=18)

    
    
    plt.tight_layout()
    plt.show()
In [31]:
barplot_default()

In [32]:
barplot_modified()



Histograms

In [33]:
import numpy as np
import random
from matplotlib import pyplot as plt

data1 = [random.gauss(15,10) for i in range(500)]  
data2 = [random.gauss(5,5) for i in range(500)]  

Default Histogram

In [34]:
def histogram_default():

    fig = plt.figure(figsize=(8,6))
    
    bins = np.arange(-60, 60, 2.5)

    # plot histograms
    plt.hist(data1, bins=bins, label='class 1')
    plt.hist(data2, bins=bins, label='class 2')
    
    # labels
    plt.title('Matplotlib default')
    plt.xlabel('variable X')
    plt.ylabel('count')
    plt.legend(loc='upper right')

    plt.show()

Modified Histogram

In [40]:
def histogram_modified():

    bins = np.arange(-60, 60, 2.5)
    
    fig = plt.figure(figsize=(8,6))
    ax = plt.subplot(111) 
    
    # plot histograms
    plt.hist(data1, bins=bins, 
             alpha=0.3,        # transparency
             label='class 1')
    plt.hist(data2, bins=bins, 
             alpha=0.3,        # transparency
             label='class 2')
    
    # axis formatting
    plt.ylim([0, 110])
    plt.xlim([min(data1+data2)-5, max(data1+data2)+5])

    # hiding axis ticks
    plt.tick_params(axis="both", which="both", bottom="off", top="off",  
            labelbottom="on", left="off", right="off", labelleft="on")

    # adding horizontal grid lines 
    ax.yaxis.grid(True) 
    
    # remove axis spines
    ax.spines["top"].set_visible(False)  
    ax.spines["right"].set_visible(False) 
    ax.spines["bottom"].set_visible(False) 
    ax.spines["left"].set_visible(False)    
    
    # labels    
    plt.xlabel('variable X')
    plt.ylabel('count')
    plt.legend(loc='upper right', fancybox=True)

    # raised title
    plt.text(15, 120, 'Modified',
         horizontalalignment='center',
         fontsize=18)    
    
    plt.show()
In [41]:
histogram_default()

In [42]:
histogram_modified()



Pie charts

Default pie chart

In [8]:
from matplotlib import pyplot as plt
import numpy as np

def piechart_default():

    plt.pie(
        (10,5),
        labels=('spam','ham'))
    plt.legend()
    plt.title('Matplotlib default')
    plt.show()

Modified pie chart

In [9]:
def piechart_modified():

    plt.pie(
        (10,5),
        labels=('spam','ham'),
        shadow=True,
        colors=('lightskyblue', 'yellowgreen'),
        explode=(0,0.15), # space between slices 
        startangle=90,    # rotate conter-clockwise by 90 degrees
        autopct='%1.1f%%',# display fraction as percentage
        )
    plt.legend(fancybox=True)
    plt.axis('equal')     # plot pyplot as circle
    plt.tight_layout()
    plt.title('Modified')
    plt.show()
In [10]:
piechart_default()
In [11]:
piechart_modified()



Violin plots

In [5]:
import numpy as np
data = [np.random.normal(0, std, 50) for std in range(1, 4)]

Default violin plot

In [10]:
import matplotlib.pyplot as plt

def violin_default():

    fig = plt.figure(figsize=(8,6))

    plt.violinplot(data)

    plt.xticks([y+1 for y in range(len(data))], ['x1', 'x2', 'x3'])
    plt.title('Matplotlib default')
    plt.show()

Modified violin plot

In [14]:
def violin_modified():
    
    fig = plt.figure(figsize=(8,6))
    ax = plt.subplot(111) 

    vplot = plt.violinplot(data,
               showmeans=False,
               showmedians=True,
               showextrema=False
               )

    # choosing custom colors to fill the boxes
    colors = ['red', 'blue', 'green']
    for patch, color in zip(vplot['bodies'], colors):
        patch.set_facecolor(color)


    # hiding axis ticks
    plt.tick_params(axis="both", which="both", bottom="off", top="off",  
            labelbottom="on", left="off", right="off", labelleft="on")

    # adding horizontal grid lines 
    ax.yaxis.grid(True) 
    
    # remove axis spines
    ax.spines["top"].set_visible(False)  
    ax.spines["right"].set_visible(False) 
    ax.spines["bottom"].set_visible(False) 
    ax.spines["left"].set_visible(False)

    plt.xticks([y+1 for y in range(len(data))], ['x1', 'x2', 'x3'])

    # raised title
    plt.text(2, 9, 'Modified',
         horizontalalignment='center',
         fontsize=18)

    plt.tight_layout()
    plt.show()
In [15]:
violin_default()
In [16]:
violin_modified()