Skip to content

Commit fef4b8c

Browse files
authored
Merge pull request #13 from matplotlib/nicolas
Nicolas
2 parents 5e2bdd6 + 7c43639 commit fef4b8c

9 files changed

+394
-7
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88

99
![](./handout-beginner.png)
1010

11+
![](./handout-intermediate.png)
12+
1113
# How to compile
1214

1315
1. You need to create a `fonts` repository with:
1416

1517
* `fonts/roboto/*` : See https://fonts.google.com/specimen/Roboto
18+
* `fonts/roboto-slab/*` : See https://fonts.google.com/specimen/Roboto+Slab
1619
* `fonts/source-code-pro/*` : See https://fonts.google.com/specimen/Source+Code+Pro
1720
* `fonts/source-sans-pro/*` : See https://fonts.google.com/specimen/Source+Sans+Pro
1821
* `fonts/source-serif-pro/*` : See https://fonts.google.com/specimen/Source+Serif+Pro

handout-beginner.tex

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
showtabs=false,
3535
tabsize=2,
3636
%
37-
emph = { plot, scatter, imshow, bar, contourf, pie,
37+
emph = { plot, scatter, imshow, bar, contourf, pie, subplots,
3838
errorbar, boxplot, hist, title, xlabel, ylabel, suptitle },
3939
emphstyle = {\ttfamily\bfseries}
4040
}
@@ -295,7 +295,7 @@ \subsection*{\rmfamily Save \mdseries (bitmap or vector format)}
295295
%
296296
\vfill
297297
%
298-
{\scriptsize Matplotlib handout for beginners. Copyright (c)
298+
{\scriptsize Matplotlib 3.2 handout for beginners. Copyright (c)
299299
2020 Nicolas P. Rougier. Released under a CC-BY International 4.0
300300
License. Supported by NumFocus Grant \#12345.\par}
301301

handout-intermediate.pdf

114 KB
Binary file not shown.

handout-intermediate.png

466 KB
Loading

handout-intermediate.tex

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
\documentclass[10pt,landscape,a4paper]{article}
2+
\usepackage[right=10mm, left=10mm, top=10mm, bottom=10mm]{geometry}
3+
\usepackage[utf8]{inputenc}
4+
\usepackage[T1]{fontenc}
5+
\usepackage[english]{babel}
6+
\usepackage[rm,light]{roboto}
7+
\usepackage{xcolor}
8+
\usepackage{graphicx}
9+
\graphicspath{{./figures/}}
10+
\usepackage{multicol}
11+
\usepackage{colortbl}
12+
\usepackage{array}
13+
\setlength\parindent{0pt}
14+
\setlength{\tabcolsep}{2pt}
15+
\baselineskip=0pt
16+
\setlength\columnsep{1em}
17+
\definecolor{Gray}{gray}{0.85}
18+
19+
% --- Listing -----------------------------------------------------------------
20+
\usepackage{listings}
21+
\lstset{
22+
frame=tb, framesep=4pt, framerule=0pt,
23+
backgroundcolor=\color{black!5},
24+
basicstyle=\ttfamily,
25+
commentstyle=\ttfamily\color{black!50},
26+
breakatwhitespace=false,
27+
breaklines=true,
28+
extendedchars=true,
29+
keepspaces=true,
30+
language=Python,
31+
rulecolor=\color{black},
32+
showspaces=false,
33+
showstringspaces=false,
34+
showtabs=false,
35+
tabsize=2,
36+
%
37+
emph = { plot, scatter, imshow, bar, contourf, pie, subplots, spines,
38+
add_gridspec, add_subplot, set_xscale, set_minor_locator,
39+
annotate, set_minor_formatter, tick_params, fill_betweenx, text, legend,
40+
errorbar, boxplot, hist, title, xlabel, ylabel, suptitle },
41+
emphstyle = {\ttfamily\bfseries}
42+
}
43+
44+
% --- Fonts -------------------------------------------------------------------
45+
\usepackage{fontspec}
46+
\usepackage[babel=true]{microtype}
47+
\defaultfontfeatures{Ligatures = TeX, Mapping = tex-text}
48+
\setsansfont{Roboto} [ Path = fonts/roboto/Roboto-,
49+
Extension = .ttf,
50+
UprightFont = Light,
51+
ItalicFont = LightItalic,
52+
BoldFont = Regular,
53+
BoldItalicFont = Italic ]
54+
\setromanfont{RobotoSlab} [ Path = fonts/roboto-slab/RobotoSlab-,
55+
Extension = .ttf,
56+
UprightFont = Light,
57+
BoldFont = Bold ]
58+
\setmonofont{RobotoMono} [ Path = fonts/roboto-mono/RobotoMono-,
59+
Extension = .ttf,
60+
Scale = 0.90,
61+
UprightFont = Light,
62+
ItalicFont = LightItalic,
63+
BoldFont = Regular,
64+
BoldItalicFont = Italic ]
65+
\renewcommand{\familydefault}{\sfdefault}
66+
67+
% -----------------------------------------------------------------------------
68+
\begin{document}
69+
\thispagestyle{empty}
70+
71+
\section*{\LARGE \rmfamily
72+
Matplotlib \textcolor{orange}{\mdseries for intermediate users}}
73+
74+
\begin{multicols*}{3}
75+
76+
A matplotlib figure is composed of a hierarchy of elements that forms
77+
the actual figure. Each element can be modified. \medskip
78+
79+
\includegraphics[width=\linewidth]{anatomy-cropped.pdf}
80+
81+
\subsection*{\rmfamily Figure, axes \& spines}
82+
83+
% -----------------------------------------------------------------------------
84+
\begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
85+
\begin{lstlisting}[belowskip=-\baselineskip]
86+
fig, axs = plt.subplots((3,3))
87+
axs[0,0].set_facecolor("#ddddff")
88+
axs[2,2].set_facecolor("#ffffdd")
89+
\end{lstlisting}
90+
& \raisebox{-0.75em}{\includegraphics[width=\linewidth]{layout-subplot-color.pdf}}
91+
\end{tabular}
92+
93+
% -----------------------------------------------------------------------------
94+
\begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
95+
\begin{lstlisting}[belowskip=-\baselineskip]
96+
gs = fig.add_gridspec(3, 3)
97+
ax = fig.add_subplot(gs[0, :])
98+
ax.set_facecolor("#ddddff")
99+
\end{lstlisting}
100+
& \raisebox{-0.75em}{\includegraphics[width=\linewidth]{layout-gridspec-color.pdf}}
101+
\end{tabular}
102+
103+
% -----------------------------------------------------------------------------
104+
\begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
105+
\begin{lstlisting}[belowskip=-\baselineskip]
106+
fig, ax = plt.subplots()
107+
ax.spines["top"].set_color("None")
108+
ax.spines["right"].set_color("None")
109+
\end{lstlisting}
110+
& \raisebox{-0.75em}{\includegraphics[width=\linewidth]{layout-spines.pdf}}
111+
\end{tabular}
112+
113+
114+
115+
% -----------------------------------------------------------------------------
116+
\subsection*{\rmfamily Ticks \& labels}
117+
118+
\begin{lstlisting}[basicstyle=\ttfamily\small]
119+
from mpl.ticker import MultipleLocator as ML
120+
from mpl.ticker import ScalarFormatter as SF
121+
ax.xaxis.set_minor_locator(ML(0.2))
122+
ax.xaxis.set_minor_formatter(SF())
123+
ax.tick_params(axis='x',which='minor',rotation=90)
124+
\end{lstlisting}
125+
\includegraphics[width=\linewidth]{tick-multiple-locator.pdf}
126+
127+
% -----------------------------------------------------------------------------
128+
\subsection*{\rmfamily Lines \& markers}
129+
130+
\begin{lstlisting}
131+
X = np.linspace(0.1, 10*np.pi, 1000)
132+
Y = np.sin(X)
133+
ax.plot(X, Y, "C1o:", markevery=25, mec="1.0")
134+
\end{lstlisting}
135+
\includegraphics[width=\linewidth]{sine-marker.pdf}
136+
137+
% -----------------------------------------------------------------------------
138+
\subsection*{\rmfamily Scales \& Projections}
139+
140+
\begin{lstlisting}
141+
fig, ax = plt.subplots()
142+
ax.set_xscale("log")
143+
ax.plot(X, Y, "C1o-", markevery=25, mec="1.0")
144+
\end{lstlisting}
145+
\includegraphics[width=\linewidth]{sine-logscale.pdf}
146+
147+
\subsection*{\rmfamily Text \& Ornaments}
148+
\begin{lstlisting}[]
149+
ax.fill_betweenx([-1,1],[0],[2*np.pi])
150+
ax.text(0, -1, r" Period $\Phi$")
151+
\end{lstlisting}
152+
\includegraphics[width=\linewidth]{sine-period.pdf}
153+
154+
155+
% -----------------------------------------------------------------------------
156+
\subsection*{\rmfamily Legend}
157+
\begin{lstlisting}[]
158+
ax.plot(X, np.sin(X), "C0", label="Sine")
159+
ax.plot(X, np.cos(X), "C1", label="Cosine")
160+
ax.legend(bbox_to_anchor=(0,1,1,.1),ncol=2,
161+
mode="expand", loc="lower left")
162+
\end{lstlisting}
163+
\includegraphics[width=\linewidth]{sine-legend.pdf}
164+
165+
% -----------------------------------------------------------------------------
166+
\subsection*{\rmfamily Annotation}
167+
\begin{lstlisting}[]
168+
ax.annotate("A", (X[250],Y[250]),(X[250],-1),
169+
ha="center", va="center",arrowprops =
170+
{"arrowstyle" : "->", "color": "C1"})
171+
\end{lstlisting}
172+
\includegraphics[width=\linewidth]{sine-annotate.pdf}
173+
174+
% -----------------------------------------------------------------------------
175+
\subsection*{\rmfamily Colors}
176+
177+
Any color can be used but Matplotlib offers sets of colors:\\
178+
\includegraphics[width=\linewidth]{colors-cycle.pdf} \smallskip
179+
\includegraphics[width=\linewidth]{colors-grey.pdf}\\
180+
%As well as nice colormaps (viridis an magma):\\
181+
%\includegraphics[width=\linewidth]{colormap-viridis.pdf} \smallskip
182+
%\includegraphics[width=\linewidth]{colormap-magma.pdf} \medskip
183+
184+
% -----------------------------------------------------------------------------
185+
\subsection*{\rmfamily Size \& DPI}
186+
187+
Consider a square figure to be included in a two-columns A4 paper with
188+
2cm margins on each side and a column separation of 1cm. The width of
189+
a figure is (21 - 2*2 - 1)/2 = 8cm. One inch being 2.54cm, figure size
190+
should be 3.15$\times$3.15 in.
191+
\begin{lstlisting}[]
192+
fig = plt.figure(figsize=(3.15,3.15), dpi=50)
193+
plt.savefig("figure.pdf", dpi=600)
194+
\end{lstlisting}
195+
196+
197+
\vfill
198+
%
199+
{\scriptsize Matplotlib 3.2 handout for intermediate users. Copyright
200+
(c) 2020 Nicolas P. Rougier. Released under a CC-BY 4.0
201+
License. Supported by NumFocus Grant \#12345.\par}
202+
203+
204+
205+
\end{multicols*}
206+
\end{document}
207+

scripts/layouts.py

+31
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,25 @@
2020
plt.savefig("../figures/layout-subplot.pdf")
2121
fig.clear()
2222

23+
# Subplots (colored)
24+
# -----------------------------------------------------------------------------
25+
nrows, ncols = 3,3
26+
for i in range(nrows*ncols):
27+
ax = plt.subplot(ncols, nrows, i+1)
28+
ax.set_xticks([]), ax.set_yticks([])
29+
if i == 0: ax.set_facecolor("#ddddff")
30+
if i == 8: ax.set_facecolor("#ffdddd")
31+
plt.savefig("../figures/layout-subplot-color.pdf")
32+
fig.clear()
33+
34+
# Spines
35+
# -----------------------------------------------------------------------------
36+
ax = fig.add_subplot(1,1,1, xticks=[], yticks=[])
37+
ax.spines["top"].set_color("None")
38+
ax.spines["right"].set_color("None")
39+
plt.savefig("../figures/layout-spines.pdf")
40+
fig.clear()
41+
2342

2443
# Gridspec
2544
# -----------------------------------------------------------------------------
@@ -32,6 +51,18 @@
3251
plt.savefig("../figures/layout-gridspec.pdf")
3352
fig.clear()
3453

54+
# Gridspec (colored)
55+
# -----------------------------------------------------------------------------
56+
gs = fig.add_gridspec(3, 3)
57+
ax1 = fig.add_subplot(gs[0, :], xticks=[], yticks=[])
58+
ax1.set_facecolor("#ddddff")
59+
ax2 = fig.add_subplot(gs[1, :-1], xticks=[], yticks=[])
60+
ax3 = fig.add_subplot(gs[1:, -1], xticks=[], yticks=[])
61+
ax4 = fig.add_subplot(gs[-1, 0], xticks=[], yticks=[])
62+
ax5 = fig.add_subplot(gs[-1, -2], xticks=[], yticks=[])
63+
plt.savefig("../figures/layout-gridspec-color.pdf")
64+
fig.clear()
65+
3566
# Inset axes
3667
# -----------------------------------------------------------------------------
3768
mpl.rc('axes', linewidth=.5)

scripts/sine.py

+61-5
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,68 @@
55
import numpy as np
66
import matplotlib.pyplot as plt
77

8-
X = np.linspace(0, 10*np.pi, 1000)
8+
X = np.linspace(0.1, 10*np.pi, 10000)
99
Y = np.sin(X)
1010

11-
plt.figure = plt.figure(figsize=(8,2))
12-
plt.plot(X, Y, color="orange", linewidth=2)
11+
# fig = plt.figure(figsize=(8,2))
12+
# plt.plot(X, Y, color="orange", linewidth=2)
1313
# plt.xticks([]), plt.yticks([])
1414
# plt.tight_layout()
15-
plt.savefig("../figures/sine.pdf", dpi=100)
16-
plt.show()
15+
# plt.savefig("../figures/sine.pdf", dpi=100)
16+
17+
# fig = plt.figure(figsize=(7,1.5))
18+
# plt.plot(X, Y, "C1o:", markevery=500, mec="1.0", lw=2, ms=8.5, mew=2)
19+
# # plt.xticks([]), plt.yticks([])
20+
# plt.ylim(-1.5, 1.5)
21+
# plt.tight_layout()
22+
# plt.savefig("../figures/sine-marker.pdf", dpi=100)
23+
24+
# fig, ax = plt.subplots(figsize=(7,1.5))
25+
# ax.set_xscale("log")
26+
# ax.plot(X, Y, "-")
27+
# plt.plot(X, Y, "C1o-", markevery=500, mec="1.0", lw=2, ms=8.5, mew=2)
28+
# #plt.xticks([]), plt.yticks([])
29+
# plt.ylim(-1.5, 1.5)
30+
# plt.tight_layout()
31+
# plt.savefig("../figures/sine-logscale.pdf", dpi=100)
32+
33+
34+
# fig = plt.figure(figsize=(7,1.5))
35+
# plt.plot(X, Y, "C1", lw=2)
36+
# plt.fill_betweenx([-1.5,1.5],[0],[2*np.pi], color=".9")
37+
# plt.text(0, -1, r" Period $\Phi$")
38+
# # plt.xticks([]), plt.yticks([])
39+
# plt.ylim(-1.5, 1.5)
40+
# plt.tight_layout()
41+
# plt.savefig("../figures/sine-period.pdf", dpi=100)
42+
# plt.show()
43+
44+
45+
# fig = plt.figure(figsize=(7,1.5))
46+
# plt.plot(X, np.sin(X), "C0", lw=2, label="Sine")
47+
# plt.plot(X, np.cos(X), "C1", lw=2, label="Cosine")
48+
# plt.legend(bbox_to_anchor = (0.0, .9, 1.02, 0.1),
49+
# frameon=False, mode="expand", ncol=2, loc="lower left")
50+
# plt.title("Sine and Cosine")
51+
# plt.xticks([]), plt.yticks([])
52+
# plt.ylim(-1.25, 1.25)
53+
# plt.tight_layout()
54+
# plt.savefig("../figures/sine-legend.pdf", dpi=100)
55+
# plt.show()
56+
57+
58+
fig = plt.figure(figsize=(7,1.5))
59+
X = np.linspace(0, 10*np.pi, 1000)
60+
Y = np.sin(X)
61+
plt.plot(X, Y, "C1o-", markevery=50, mec="1.0", lw=2, ms=8.5, mew=2)
62+
# plt.xticks([]), plt.yticks([])
63+
plt.ylim(-1.5, 1.5)
64+
plt.annotate(" ", (X[200],Y[200]), (X[250], -1), ha="center", va="center",
65+
arrowprops = {"arrowstyle" : "->", "color": "C1"})
66+
plt.annotate("A", (X[250],Y[250]), (X[250], -1), ha="center", va="center",
67+
arrowprops = {"arrowstyle" : "->", "color": "C1"})
68+
plt.annotate(" ", (X[300],Y[300]), (X[250], -1), ha="center", va="center",
69+
arrowprops = {"arrowstyle" : "->", "color": "C1"})
70+
plt.tight_layout()
71+
plt.savefig("../figures/sine-annotate.pdf", dpi=100)
72+
# plt.show()

scripts/tick-locators-single.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# ----------------------------------------------------------------------------
2+
# Title: Scientific Visualisation - Python & Matplotlib
3+
# Author: Nicolas P. Rougier
4+
# License: BSD
5+
# ----------------------------------------------------------------------------
6+
import numpy as np
7+
import matplotlib.pyplot as plt
8+
import matplotlib.ticker as ticker
9+
10+
# Setup a plot such that only the bottom spine is shown
11+
def setup(ax):
12+
ax.spines['right'].set_color('none')
13+
ax.spines['left'].set_color('none')
14+
ax.yaxis.set_major_locator(ticker.NullLocator())
15+
ax.spines['top'].set_color('none')
16+
ax.xaxis.set_ticks_position('bottom')
17+
ax.tick_params(which='major', width=1.00)
18+
ax.tick_params(which='major', length=5)
19+
ax.tick_params(which='minor', width=0.75)
20+
ax.tick_params(which='minor', length=2.5)
21+
ax.set_xlim(0, 5)
22+
ax.set_ylim(0, 1)
23+
ax.patch.set_alpha(0.0)
24+
25+
26+
fig = plt.figure(figsize=(5, .5))
27+
fig.patch.set_alpha(0.0)
28+
n = 1
29+
30+
fontsize = 18
31+
family = "Source Code Pro"
32+
33+
# Null Locator
34+
ax = plt.subplot(n, 1, 1)
35+
setup(ax)
36+
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
37+
ax.xaxis.set_minor_locator(ticker.MultipleLocator(.1))
38+
plt.savefig("../figures/tick-multiple-locator.pdf", transparent=True)
39+
plt.show()

0 commit comments

Comments
 (0)