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
Here's a blog post you may be interested to read:
Plotting for Pandas GSoC2012
http://pandasplotting.blogspot.com/
Decided to try to implement a ggplot2 type plotting interface...Not yet sure how much of the ggplot2 functionality to implement...
The author forked pandas and built what looks like quite a lot of ggplot2-style grammar for pandas.
plot = rplot.RPlot(tips_data, x='total_bill', y='tip')
plot.add(rplot.TrellisGrid(['sex', 'smoker']))
plot.add(rplot.GeomHistogram())
plot.render(plt.gcf())
The pandas fork is here: https://github.com/orbitfold/pandas
Seems like meat of the code to make the R-influenced graphics is in a file called rplot.py
which can be found in a branch in the repo.
class GeomScatter(Layer):
"""
An efficient scatter plot, use this instead of GeomPoint for speed.
"""
class GeomHistogram(Layer):
"""
An efficient histogram, use this instead of GeomBar for speed.
"""
Link to the branch:
https://github.com/orbitfold/pandas/blob/rplot/pandas/tools/rplot.py
I thought this was really cool, but I can't figure out if this project is being maintained or not. The last commit was a while ago.
The Seaborn visualisation library can do that. For example, to reproduce the style of the R histogram use:
sns.despine(offset=10, trim=True)
as in https://seaborn.pydata.org/tutorial/aesthetics.html#removing-axes-spines
To reproduce the style of the R scatter plot use:
sns.set_style("ticks")
as shown in https://seaborn.pydata.org/tutorial/aesthetics.html#seaborn-figure-styles
matplotlib >= 1.4 suports styles (and ggplot-style is build in):
In [1]: import matplotlib as mpl
In [2]: import matplotlib.pyplot as plt
In [3]: import numpy as np
In [4]: mpl.style.available
Out[4]: [u'dark_background', u'grayscale', u'ggplot']
In [5]: mpl.style.use('ggplot')
In [6]: plt.hist(np.random.randn(100000))
Out[6]:
...
Setting spines in matplotlibrc explains why it is not possible to simply edit Matplotlib defaults to produce R-style histograms. For scatter plots,
R style data-axis buffer in matplotlib and In matplotlib, how do you draw R-style axis ticks that point outward from the axes? show some defaults that can be changed to give a more R-ish look. Building off some of the other answers, the following function does a decent job of mimicking R's histogram style, assuming you've called hist()
on your Axes
instance with facecolor='none'
.
def Rify(axes):
'''
Produce R-style Axes properties
'''
xticks = axes.get_xticks()
yticks = axes.get_yticks()
#remove right and upper spines
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
#make the background transparent
axes.set_axis_bgcolor('none')
#allow space between bottom and left spines and Axes
axes.spines['bottom'].set_position(('axes', -0.05))
axes.spines['left'].set_position(('axes', -0.05))
#allow plot to extend beyond spines
axes.spines['bottom'].set_bounds(xticks[0], xticks[-2])
axes.spines['left'].set_bounds(yticks[0], yticks[-2])
#set tick parameters to be more R-like
axes.tick_params(direction='out', top=False, right=False, length=10, pad=12, width=1, labelsize='medium')
#set x and y ticks to include all but the last tick
axes.set_xticks(xticks[:-1])
axes.set_yticks(yticks[:-1])
return axes
import matplotlib.pyplot as plt
plt.style.use('ggplot')
do something plot here, and enjoy it
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.
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.
So yeah. It's not exactly trivial, but you can get close.