How to set default matplotlib style? - python

When using matplotlib, I tend to use
import matplotlib.pyplot as plt
plt.style.use('ggplot')
quiet often. Is there an easy way to change the default style to ggplot (or any other style)? I looked into the 'matplotlibrc'-documentation but was unable to find an appropriate option.
Is there a better way then copying/linking the system-wide .mplstyle?
Thanks!

You can change the settings file of matplotlib. According to the docs :
matplotlib uses matplotlibrc configuration files to customize all kinds of properties, which we call rc settings or rc parameters. You can control the defaults of almost every property in matplotlib: figure size and dpi, line width, color and style, axes, axis and grid properties, text and font properties and so on.
You can locate your matplotlibrc file with the following command:
import matplotlib
matplotlib.matplotlib_fname()
Hence we can put ggplot settings at the end of the matplotlibrc file. You can easily find ggplot style (as well as other styles) on official matplotlib repository.

Apparently, there is no such option (yet).
However, you can tell iPython to load the ggplot style at startup, by adding "plt.style.use('ggplot')" to c.InteractiveShellApp.exec_lines in ipython_config.py.

Create a file (call it e.g. startup-01.py) in
~/.ipython/profile_default/startup/
(substitute another profile name for profile_default as needed)
and put there any needed notebook (and interactive ipython) initialization statements, including
import matplotlib.pyplot as plt
plt.style.use('ggplot')
## other settings, e.g.
# plt.rcParams['figure.figsize'] = (10.0, 8.0)

plt.style.use('default') worked for me.
As I understand this, it tells matplotlib to switch back to its default style mode.

Related

Jupyter notebook: How to set matplotlib figure default size persistently, even after `from matplotlib import pyplot`?

I'm looking for a way to configure my default notebook set up and set the size of plots and figures, so that I do not have to set it manually for each notebook individually.
I'm aware of questions like How to set the matplotlib figure default size in ipython notebook? which detail how to use jupyter_notebook_config.py.
However this isnt working, presumably because I reimport pyplot in the notebook. Is there a better way to set default settings, behaviors, options etc?
In python 3.x
ipython profile create
ipython profile locate
go to the locate and edit ipython_kernel_config.py
manually add the line:
c.InlineBackend.rc = {'figure.dpi':160}
rcParams references
https://matplotlib.org/3.1.1/tutorials/introductory/customizing.html
One away to set default plot size in matplotlib is:
from pylab import rcParams
rcParams['figure.figsize'] = 8, 6
where 8, 6 is the figure size you want to set.

Matplotlib figure size in Jupyter reset by inlining in Jupyter

This question is more of a curiosity.
To change the default fig size to a custom one in matplotlib, one does
from matplotlib import rcParams
from matplotlib import pyplot as plt
rcParams['figure.figsize'] = 15, 9
after that, figure appears with chosen size.
Now, I'm finding something new (never happened/noticed before just now): in a Jupyter notebook, when inlining matplotlib as
%matplotlib inline
this apparently overwrites the rcParams dictionary restoring the default value for the figure size. Hence in oder to be able to set the size, I have to inline matplotlib before changing the values of the rcParams dictionary.
I am on a Mac OS 10.11.6, matplotlib version 1.5.1, Python 2.7.10, Jupyter 4.1.
IPython's inline backend sets some rcParams when it is initialized. This is configurable, and you can override it with your own configuration:
# in ~/.ipython/ipython_config.py
c.InlineBackend.rc = {
'figure.figsize': (15, 9)
}
The above would replace all of the rcParams that the inline backend sets, and you get total control. If you already have a matplotlib style that works nicely for inline output, you can tell the backend to leave everything alone:
c.InlineBackend.rc = {}
If you want to change just a few values, rather than overriding the whole thing, you can use the dictionary .update method:
c.InlineBackend.rc.update({'figure.figsize': (15, 9)})
In the future, the inline backend should be doing its defaults via matplotlib's nice new style mechanism, which should make it behave nicer in terms of respecting your preferences and allowing easier customization.

ggplot styles in Python

When I look at the plotting style in the Pandas documentation, the plots look different from the default one. It seems to mimic the ggplot "look and feel".
Same thing with the seaborn's package.
How can I load that style? (even if I am not using a notebook?)
Update: If you have matplotlib >= 1.4, there is a new style module which has a ggplot style by default. To activate this, use:
from matplotlib import pyplot as plt
plt.style.use('ggplot')
To see all the available styles, you can check plt.style.available.
Similarly, for seaborn styling you can do:
plt.style.use('seaborn-white')
or, you can use seaborn's own machinery to set up the styling:
import seaborn as sns
sns.set()
The set() function has more options to select a specific style (see docs). Note that seaborn previously did the above automatically on import, but with the latest versions (>= 0.8) this is no longer the case.
If you actually want a ggplot-like syntax in Python as well (and not only the styling), take a look at the plotnine package, which is a grammar of graphics implementation in Python with a syntax very similar to R's ggplot2.
Note: the old answer mentioned to do pd.options.display.mpl_style = 'default'
. This was however deprecated in pandas in favor of matplotlib's styling using plt.style(..), and in the meantime this functionality is even removed from pandas.
For the themes in python-ggplot, you can use them with other plots:
from ggplot import theme_gray
theme = theme_gray()
with mpl.rc_context():
mpl.rcParams.update(theme.get_rcParams())
# plotting commands here
for ax in plt.gcf().axes:
theme.post_plot_callback(ax)
If you need to see available styles :
import matplotlib.pyplot as plt
print(plt.style.available)
This will print available styles.
And use this link to select the style you prefer
https://tonysyu.github.io/raw_content/matplotlib-style-gallery/gallery.html
Jan Katins's answer is good, but the python-ggplot project seems to have become inactive. The plotnine project is more developed and supports an analogous, but superficially different, solution:
from plotnine import theme_bw
import matplotlib as mpl
theme = theme_bw()
with mpl.rc_context():
mpl.rcParams.update(theme.rcParams)
While I think that joris answer is a better solution since you're using Pandas, it should be mentioned that Matplotlib can be set to mimic ggplot by issuing the command matplotlib.style.use('ggplot').
See examples in the Matplotlib gallery.

Why is matplotlib plot produced from ipython notebook slightly different from terminal version?

I have a strange issue. Using IPython Notebook, I created a quite extensive script using pandas and matplotlib to create a number of charts.
When my tinkering was finished, I copied (and cleaned) the code into a standalone python script (so that I can push it into the svn and my paper co-authors can create the charts as well).
For convenience, I import the standalone python script into the notebook again and create a number of charts:
import create_charts as cc
df = cc.read_csv_files("./data")
cc.chart_1(df, 'fig_chart1.pdf')
...
Strange enough, the .pdf file I get using the above method is slightly different from the .pdf file I get when I run my standalone python script from my Windows 7 terminal. The most notable difference is that in a particular chart the legend is located in the upper corner instead of the lower corner. But there are other small diferences as well (bounding box size, font seems slightly different)
What could be the cause of this. And how can I troubleshoot it?
(I already shut down my notebook and restarted it, to reimport my create_charts script and rule out any unsaved changes)
My terminal reports I am using Python 2.7.2, and pip freeze | grep ipython reports ipython 0.13.1
To complete Joe answer, the inlinebackend (IPython/kernel/zmq/pylab/backend_inline.py) have some default matplotlib parameters :
# The typical default figure size is too large for inline use,
# so we shrink the figure size to 6x4, and tweak fonts to
# make that fit.
rc = Dict({'figure.figsize': (6.0,4.0),
# play nicely with white background in the Qt and notebook frontend
'figure.facecolor': 'white',
'figure.edgecolor': 'white',
# 12pt labels get cutoff on 6x4 logplots, so use 10pt.
'font.size': 10,
# 72 dpi matches SVG/qtconsole
# this only affects PNG export, as SVG has no dpi setting
'savefig.dpi': 72,
# 10pt still needs a little more room on the xlabel:
'figure.subplot.bottom' : .125
}, config=True,
help="""Subset of matplotlib rcParams that should be different for the
inline backend."""
)
As this is not obvious to everyone, you can set it in config through c.InlineBackend.rc.
[Edit] precise info about configurability.
IPython have the particularity that most of the classes have properties which default values can be configured. Those are often refered as Configurable (uppercase C), those property can easily be recognize in the code as they are declared like so before __init__:
property = A_Type( <default_value>, config=True , help="a string")
You can overwrite those properties in IPython configuration files (which one depends on what you want to do) by doing
c.ClassName.propertie_name = value
Here as it is a dict you could do
#put your favorite matplotlib config here.
c.InlineBackend.rc = {'figure.facecolor': 'black'}
I guess an empty dict would allow inline backend to use matplotlib defaults.
Extending Matt's answer (lots of credit to him, but I think the answers can be less complex), this is how I eventually solved it.
(a) I looked up ipython's default matplotlib settings in C:\Python27\Lib\site-packages\IPython\zmq\pylab\backend_inline.py (see Matt's answer).
(b) and overwrote them with the values as set in the terminal version (I used print mpl.rcParams['figure.figsize'] etc. to find out) by inserting the following code in my script:
import matplotlib as mpl
#To make sure we have always the same matplotlib settings
#(the ones in comments are the ipython notebook settings)
mpl.rcParams['figure.figsize']=(8.0,6.0) #(6.0,4.0)
mpl.rcParams['font.size']=12 #10
mpl.rcParams['savefig.dpi']=100 #72
mpl.rcParams['figure.subplot.bottom']=.1 #.125
The font size issues are due to differences in the dpi. I'd guess the slightly different size of the figure (in pixels) changes the "best" location for the legend, as well.
The default dpi a figure is displayed at is 80, while savefig defaults to 100. This means that by default, matplotlib figures will look slightly different when saved compared to what's displayed on the screen.
I don't know for sure, but I'm guessing that ipython notebooks set the dpi to something other than 100 (most likely 80) and use that when saving figures.
Try doing savefig('filename.pdf', dpi=80) in your standalone script.

Multiple figure arrangement using Matplotlib

Can we control where Matplotlib places figures on the screen?
I want to generate four figures (in four separate windows) that do not overlap.
From IPython you can do the following:
figure()
get_current_fig_manager().window.wm_geometry("400x600+20+40")
Or equivalently in a Python script:
import pylab as pl
pl.figure()
pl.get_current_fig_manager().window.wm_geometry("400x600+20+40")
pl.show()
Note that this assumes you're using the TkAgg backend.
It is also possible to use the IPython interface with the Qt backend to achieve a similar result:
import matplotlib
import pylab as pl
f1 = pl.figure()
f_manager = pl.get_current_fig_manager()
f_manager.window.move(600, 600)
pl.show()
With f_manager you basically have a PyQt4 object that allows you to modify the window properties as you like.
Not using show() and Matplotlib alone. The simplest solution may be to use savefig(..) and use your favorite OS image viewer. If you need interactivity with the plots, Matplotlib offers backends.
The easiest way I know to do this is to make the window for the figure in your preferred GUI application, and then put the matplotlib figure into this window. There are a bunch of examples of how to do this embedding using different GUI frameworks here.
The code samples can look a bit complicated, but it's mostly boilerplate where you'll only need to modify a few lines.

Categories