There are several plotting modules in python. Matplolib is the most complete/versatile package for all 2D plotting. The easiest way to construct a new plot is to have a look at http://matplotlib.org/gallery.html and get inspiration from the available examples. The official documentation can be found at: http://matplotlib.org/contents.html
In [ ]:
%matplotlib
import numpy as np
import matplotlib.pyplot as plt
# To get interactive plotting (otherwise you need to
# type plt.show() at the end of the plotting commands)
plt.ion()
x = np.linspace(0, 10)
y = np.sin(x)
# basic X/Y line plotting with '--' dashed line and linewidth of 2
plt.plot(x, y, '--', label='first line')
# overplot a dotted line on the previous plot
plt.plot(x, np.cos(x)*np.cos(x/2), '.', linewidth=3, label='other')
x_axis_label = plt.xlabel('x axis') #change the label of the xaxis
In [ ]:
# change your mind about the label : you do not need to replot everything !
plt.xlabel('another x axis')
In [ ]:
# or you can use the re-tuned object
x_axis_label.set_text('changed it from the object itself')
In [ ]:
# simply add the legend (from the previous label)
legend = plt.legend()
In [ ]:
plt.savefig('plot.png') # save the current figure in png
plt.savefig('plot.eps') # save the current figure in ps, no need to redo it !
In [ ]:
!ls
We will use interactive plots inline in the notebook. This feature is enabled through:
In [ ]:
%matplotlib
In [ ]:
import matplotlib.pyplot as plt
import numpy as np
# define a figure which can contains several plots, you can define resolution and so on here...
fig2 = plt.figure()
# add one axis, axes are actual plots where you can put data.fits (nx, ny, index)
ax = fig2.add_subplot(1, 1, 1)
Add a cruve with a title to the plot
In [ ]:
x = np.linspace(0, 2*np.pi)
ax.plot(x, np.sin(x), '+')
ax.set_title('this title')
plt.show()
In [ ]:
# is a simpler syntax to add one axis into the figure (we will stick to this)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), '+')
ax.set_title('simple subplot')
A long list of markers can be found at http://matplotlib.org/api/markers_api.html as for the colors, there is a nice discussion at http://stackoverflow.com/questions/22408237/named-colors-in-matplotlib
All the components of a figure can be accessed throught the 'Figure' object
In [ ]:
print(type(fig))
In [ ]:
print(dir(fig))
In [ ]:
print(fig.axes)
In [ ]:
print('This is the x-axis object', fig.axes[0].xaxis)
print('And this is the y-axis object', fig.axes[0].yaxis)
In [ ]:
# arrow pointing to the origin of the axes
ax_arrow = ax.annotate('ax = fig.axes[0]',
xy=(0, -1), # tip of the arrow
xytext=(1, -0.5), # location of the text
arrowprops={'facecolor':'red', 'shrink':0.05})
# arrow pointing to the x axis
x_ax_arrow = ax.annotate('ax.xaxis',
xy=(3, -1), # tip of the arrow
xytext=(3, -0.5), # location of the text
arrowprops={'facecolor':'red', 'shrink':0.05})
xax = ax.xaxis
# arrow pointing to the y axis
y_ax_arrow = ax.annotate('ax.yaxis',
xy=(0, 0), # tip of the arrow
xytext=(1, 0.5), # location of the text
arrowprops={'facecolor':'red', 'shrink':0.05})
Add a labels to the x and y axes
In [ ]:
# add some ascii text label
# this is equivelant to:
# ax.set_xlabel('x')
xax.set_label_text('x')
# add latex rendered text to the y axis
ax.set_ylabel('$sin(x)$', size=20, color='g', rotation=0)
Finally dump the figure to a png file
In [ ]:
fig.savefig('myplot.png')
!ls
!eog myplot.png
Lets define a function that creates an empty base plot to which we will add stuff for each demonstration. The function returns the figure and the axes object.
In [ ]:
from matplotlib import pyplot as plt
import numpy as np
def create_base_plot():
fig, ax = plt.subplots()
ax.set_title('sample figure')
return fig, ax
def plot_something():
fig, ax = create_base_plot()
x = np.linspace(0, 2*np.pi)
ax.semilogx(x, np.cos(x)*np.cos(x/2), 'r--.')
plt.show()
In [ ]:
fig, ax = create_base_plot()
# normal-xlog plots
ax.semilogx(x, np.cos(x)*np.cos(x/2), 'r--.')
In [ ]:
# clear the plot and plot a function using the y axis in log scale
ax.clear()
ax.semilogy(x, np.exp(x))
In [ ]:
# you can (un)set it, whenever you want
#ax.set_yscale('linear') # change they y axis to linear scale
#ax.set_yscale('log') # change the y axis to log scale
In [ ]:
# you can also make loglog plots
#ax.clear()
#ax.loglog(x, np.exp(x)*np.sin(x))
plt.setp(ax, **dict(yscale='log', xscale='log'))
This is equivelant to:
ax.plot(x, np.exp(x)*np.sin(x))
plt.setp(ax, 'yscale', 'log', 'xscale', 'log')
here we have introduced a new method of setting property values via pyplot.setp.
setp takes as first argument a matplotlib object. Each pair of positional argument after that is treated as a key value pair for the set method name and its value. For example:
ax.set_scale('linear')
becomes
plt.setp(ax, 'scale', 'linear')
This is useful if you need to set lots of properties, such as:
In [ ]:
plt.setp(ax, 'xscale', 'linear', 'xlim', [1, 5], 'ylim', [0.1, 10], 'xlabel', 'x',
'ylabel', 'y', 'title', 'foo',
'xticks', [1, 2, 3, 4, 5],
'yticks', [0.1, 1, 10],
'yticklabels', ['low', 'medium', 'high'])
In [ ]:
fig1, ax = create_base_plot()
n, bins, patches = ax.hist(np.random.normal(0, 0.1, 10000), bins=50)
Making subplots is relatively easy. Just pass the shape of the grid of plots to plt.subplots() that was used in the above examples.
In [ ]:
# Create one figure with two plots/axes, with their xaxis shared
fig, (ax1, ax2) = plt.subplots(2, sharex=True)
ax1.plot(x, np.sin(x), '-.', color='r', label='first line')
other = ax2.plot(x, np.cos(x)*np.cos(x/2), 'o-', linewidth=3, label='other')
ax1.legend()
ax2.legend()
In [ ]:
# adjust the spacing between the axes
fig.subplots_adjust(hspace=0.0)
In [ ]:
# add a scatter plot to the first axis
ax1.scatter(x, np.sin(x)+np.random.normal(0, 0.1, np.size(x)))
create a 3x3 grid of plots
In [ ]:
fig, axs = plt.subplots(3, 3)
In [ ]:
print(axs.shape)
In [ ]:
# add an index to all the subplots
for ax_index, ax in enumerate(axs.flatten()):
ax.set_title(ax_index)
In [ ]:
# remove all ticks
for ax in axs.flatten():
plt.setp(ax, 'xticks', [], 'yticks', [])
In [ ]:
fig.subplots_adjust(hspace=0, wspace=0)
In [ ]:
# plot a curve in the diagonal subplots
for ax, func in zip(axs.diagonal(), [np.sin, np.cos, np.exp]):
ax.plot(x, func(x))
In [ ]:
xx, yy = np.mgrid[-2:2:100j, -2:2:100j]
img = np.sin(xx) + np.cos(yy)
In [ ]:
fig, ax = create_base_plot()
In [ ]:
# to have 0,0 in the lower left corner and no interpolation
img_plot = ax.imshow(img, origin='lower', interpolation='None')
# to add a grid to any axis
ax.grid()
In [ ]:
img_plot.set_cmap('hot') # changing the colormap
In [ ]:
img_plot.set_cmap('spectral') # changing the colormap
colorb = fig.colorbar(img_plot) # adding a color bar
In [ ]:
img_plot.set_clim(-0.5, 0.5) # changing the dynamical range
In [ ]:
# add contour levels
img_contours = ax.contour(img, [-1, -0.5, 0.0, 0.5])
plt.clabel(img_contours, inline=True, fontsize=20)
In [ ]:
from IPython.display import HTML
import matplotlib.animation as animation
def f(x, y):
return np.sin(x) + np.cos(y)
fig, ax = create_base_plot()
im = ax.imshow(f(xx, yy), cmap=plt.get_cmap('viridis'))
def updatefig(*args):
global xx, yy
xx += np.pi / 15.
yy += np.pi / 20.
im.set_array(f(xx, yy))
return im,
ani = animation.FuncAnimation(fig, updatefig, interval=50, blit=True)
_ = ani.to_html5_video()
In [ ]:
# change title during animation!!
ax.set_title('runtime title')
matplotlib
Most of the matplotlib
code chunk that are written are usually about styling and not actual plotting.
One feature that might be of great help if you are in this case is to use the matplotlib.style
module.
In this notebook, we will go through the available matplotlib styles and their corresponding configuration files. Then we will explain the two ways of using the styles and finally show you how to write a personalized style.
An available
variable returns a list of the names of some pre-configured matplotlib style files.
In [ ]:
print('\n'.join(plt.style.available))
In [ ]:
x = np.arange(0, 10, 0.01)
def f(x, t):
return np.sin(x) * np.exp(1 - x / 10 + t / 2)
def simple_plot(style):
plt.figure()
with plt.style.context(style, after_reset=True):
for t in range(5):
plt.plot(x, f(x, t))
plt.title('Simple plot')
In [ ]:
simple_plot('ggplot')
In [ ]:
simple_plot('dark_background')
In [ ]:
simple_plot('grayscale')
In [ ]:
simple_plot('fivethirtyeight')
In [ ]:
simple_plot('bmh')
A matplotlib style file is a simple text file containing the desired matplotlib rcParam
configuration, with the .mplstyle
extension.
Let's display the content of the 'ggplot' style.
In [ ]:
import os
ggplotfile = os.path.join(plt.style.core.BASE_LIBRARY_PATH, 'ggplot.mplstyle')
In [ ]:
!cat $ggplotfile
Maybe the most interesting feature of this style file is the redefinition of the color cycle using hexadecimal notation. This allows the user to define is own color palette for its multi-line plots.
There are two ways of using the matplotlib
styles.
plt.style.use(style)
plt.style.context(style):
The use
method applied at the beginning of a script will be the default choice in most cases when the style is to be set for the entire script. The only issue is that it sets the matplotlib style for the given Python session, meaning that a second call to use
with a different style will only apply new style parameters and not reset the first style. That is if the axes.grid
is set to True
by the first style and there is nothing concerning the grid in the second style config, the grid will remain set to True
which is not matplotlib
default.
On the contrary, the context
method will be useful when only one or two figures are to be set to a given style. It shall be used with the with
statement to create a context manager in which the plot will be made.
Let's illustrate this.
In [ ]:
plt.style.use('ggplot')
plt.figure()
plt.plot(x, f(x, 0))
The 'ggplot' style has been applied to the current session. One of its features that differs from standard matplotlib
configuration is to put the ticks outside the main figure (axes.axisbelow: True
)
In [ ]:
with plt.style.context('dark_background'):
plt.figure()
plt.plot(x, f(x, 1))
Now using the 'dark_background' style as a context, we can spot the main changes (background, line color, axis color) and we can also see the outside ticks, although they are not part of this particular style. This is the 'ggplot' axes.axisbelow setup that has not been overwritten by the new style. Once the with block has ended, the style goes back to its previous status, that is the 'ggplot' style.
In [ ]:
plt.figure()
plt.plot(x, f(x, 2))
Starting from these configured files, it is easy to now create our own styles for textbook figures and talk figures and switch from one to another in a single code line plt.style.use('mystyle')
at the beginning of the plotting script.
matplotlib
will look for the user style files at the following path :
In [ ]:
print(plt.style.core.USER_LIBRARY_PATHS)
Note: The directory corresponding to this path will most probably not exist so one will need to create it.
In [ ]:
styledir = plt.style.core.USER_LIBRARY_PATHS[0]
!mkdir -p $styledir
One can now copy an existing style file to serve as a boilerplate.
In [ ]:
mystylefile = os.path.join(styledir, 'mystyle.mplstyle')
!cp $ggplotfile $mystylefile
In [ ]:
!cd $styledir
In [ ]:
%%file mystyle.mplstyle
font.size: 16.0 # large font
axes.linewidth: 2
axes.grid: True
axes.titlesize: x-large
axes.labelsize: x-large
axes.labelcolor: 555555
axes.axisbelow: True
xtick.color: 555555
xtick.direction: out
ytick.color: 555555
ytick.direction: out
grid.color: white
grid.linestyle: : # dotted line
In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import mpld3
mpld3.enable_notebook()
# Scatter points
fig, ax = plt.subplots(subplot_kw=dict(axisbg='#EEEEEE'))
ax.grid(color='white', linestyle='solid')
N = 50
scatter = ax.scatter(np.random.normal(size=N),
np.random.normal(size=N),
c=np.random.random(size=N),
s = 1000 * np.random.random(size=N),
alpha=0.3,
cmap=plt.cm.jet)
ax.set_title("D3 Scatter Plot", size=18);
In [ ]:
import mpld3
mpld3.display(fig)
In [ ]:
from mpld3 import plugins
fig, ax = plt.subplots(subplot_kw=dict(axisbg='#EEEEEE'))
ax.grid(color='white', linestyle='solid')
N = 50
scatter = ax.scatter(np.random.normal(size=N),
np.random.normal(size=N),
c=np.random.random(size=N),
s = 1000 * np.random.random(size=N),
alpha=0.3,
cmap=plt.cm.jet)
ax.set_title("D3 Scatter Plot (with tooltips!)", size=20)
labels = ['point {0}'.format(i + 1) for i in range(N)]
fig.plugins = [plugins.PointLabelTooltip(scatter, labels)]
In [ ]:
%matplotlib
In [ ]:
plot_something()
In [ ]:
import seaborn
plot_something()