making matplotlib graphs look like R by default?


Question

Is there a way to make matplotlib behave identically to R, or almost like R, in terms of plotting defaults? For example R treats its axes pretty differently from matplotlib. The following histogram enter image description here

has "floating axes" with outward ticks, such that there are no inner ticks (unlike matplotlib) and the axes do not cross "near" the origin. Also, the histogram can "spillover" to values that are not marked by the tick - e.g. the x-axis ends at 3 but the histograms extends slightly beyond it. How can this be achieved automatically for all histograms in matplotlib?

Related question: scatter plots and line plots have different default axes settings in R, for example: enter image description here

There no inner ticks again and the ticks face outward. Also, the ticks start slightly after the origin point (where the y and x axes cross at the bottom left of the axes) and the ticks end slightly before the axes end. This way the labels of the lowest x-axis tick and lowest y-axis tick can't really cross, because there's a space between them and this gives the plots a very elegant clean look. Note that there's also considerably more space between the axes ticklabels and the ticks themselves.

Also, by default there are no ticks on the non-labeled x or y axes, meaning the y-axis on the left that is parallel to the labeled y-axis on the right has no ticks, and same for the x-axis, again removing clutter from the plots.

Is there a way to make matplotlib look like this? And in general to look by default as much as default R plots? I like matplotlib a lot but I think the R defaults / out-of-the-box plotting behavior really have gotten things right and its default settings rarely lead to overlapping tick labels, clutter or squished data, so I would like the defaults to be as much like that as possible.

1
58
1/15/2013 11:45:53 PM

Edit 1 year later:

With seaborn, the example below becomes:

import numpy as np
import matplotlib.pyplot as plt
import seaborn
seaborn.set(style='ticks')
# Data to be represented
X = np.random.randn(256)

# Actual plotting
fig = plt.figure(figsize=(8,6), dpi=72, facecolor="white")
axes = plt.subplot(111)
heights, positions, patches = axes.hist(X, color='white')
seaborn.despine(ax=axes, offset=10, trim=True)
fig.tight_layout()
plt.show()

Pretty dang easy.

Original post:

This blog post is the best I've seen so far. http://messymind.net/making-matplotlib-look-like-ggplot/

It doesn't focus on your standard R plots like you see in most of the "getting started"-type examples. Instead it tries to emulate the style of ggplot2, which seems to be nearly universally heralded as stylish and well-designed.

To get the axis spines like you see the in bar plot, try to follow one of the first few examples here: http://www.loria.fr/~rougier/coding/gallery/

Lastly, to get the axis tick marks pointing outward, you can edit your matplotlibrc files to say xtick.direction : out and ytick.direction : out.

Combining these concepts together we get something like this:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
# Data to be represented
X = np.random.randn(256)

# Actual plotting
fig = plt.figure(figsize=(8,6), dpi=72, facecolor="white")
axes = plt.subplot(111)
heights, positions, patches = axes.hist(X, color='white')

axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
axes.xaxis.set_ticks_position('bottom')

# was: axes.spines['bottom'].set_position(('data',1.1*X.min()))
axes.spines['bottom'].set_position(('axes', -0.05))
axes.yaxis.set_ticks_position('left')
axes.spines['left'].set_position(('axes', -0.05))

axes.set_xlim([np.floor(positions.min()), np.ceil(positions.max())])
axes.set_ylim([0,70])
axes.xaxis.grid(False)
axes.yaxis.grid(False)
fig.tight_layout()
plt.show()

The position of the spines can be specified a number of ways. If you run the code above in IPython, you can then do axes.spines['bottom'].set_position? to see all of your options.

R-style bar plot in python

So yeah. It's not exactly trivial, but you can get close.

44
1/19/2015 4:36:31 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon