# 1011 – Matplotlib in Julia

research |

programming | Julia | plotting | Matplotlib |

Matplotlib has long been my favorite plotting engine behind Python for many years. See a beautiful galary here. After I turned to Julia several months ago, I have been a big fan of the fine lady for its elegance and power, especially how fast and efficiently she processes her jobs (well, let’s face it: Python is SLOW). I didn’t realize it until a few days ago that Matplotlib is fully functional in Julia as well, with some syntax change, and most likely that is the only difference. Hence this blog, in which I plan to share some of my favorite tricks in making beautiful graphs in Matplotlib under Julia. (Again, if you compare, Julia renders Matplotlib graphs much faster than Python does.)

To begin with, PyPlot must be installed in Julia. Simply run

1

Pkg.add(“PyPlot”)

in Julia will do the trick. Refer to the installation guide here for more details.

Then, we are ready to go.

## 1. Arrowed spines

I am old fashioned on this aspect. Whenever I draw a graph, I insist to have the arrows on the axes, just like what my middle school math teacher insisted. Here is how to do that in Matplotlib in Julia. First, you need the following auxiliary function to “draw an arrow”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

## arrowed_spines for plots: https://gist.github.com/joferkington/3845684
function arrowed_spines(ax; arrow_length=20, labels=(“”, “”), arrowprops=[])
xlabel, ylabel = labels
if isempty(arrowprops)
arrowprops = {:arrowstyle=>“<|-”, :facecolor=>“black”}
end
t = 0; xy = 0; xycoords = 0; xytext = “”; textcoords = 0; ha = 0; va = 0
for (i,spine) in enumerate([“left”, “bottom”])
# Set up the annotation parameters
t = ax[:spines][spine]:get_transform
xy, xycoords = [.98, 0], (“axes fraction”, t)
xytext, textcoords = [arrow_length, 0], (“offset points”, t)
ha, va = “left”, “bottom”
if spine == “bottom”
xarrow = ax[:annotate](xlabel, xy, xycoords=xycoords, xytext=xytext,
textcoords=textcoords, ha=ha, va=“center”, arrowprops=arrowprops)
else
yarrow = ax[:annotate](ylabel, xy[end:-1:1], xycoords=xycoords[end:-1:1],
xytext=xytext[end:-1:1], textcoords=textcoords[end:-1:1],
ha=“center”, va=va, arrowprops=arrowprops)
end
end
end

Note I have adopted this technique from joferkington and rewritten it into Her Elegance’s tongue (i.e. in Julia).

Once this auxiliary function has been defined, you can use it after creating a plot.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

### Example 1
## matplotlib settings: allow for LaTeX
PyPlot.matplotlib[:rc](“text”, usetex=true) # allow tex rendering

## compute
x = 0.0:0.1:5.0
y = exp(sin(x))

## set up canvas
fig = PyPlot.figure(figsize=(6,4.5), facecolor=“w”, dpi=120) # create figure
fig[:subplots_adjust](left=.1, right=.9, bottom=0.1, top=.9) # reduce white spaces
ax = fig[:add_subplot](111) # create axis

## plot
ax[:plot](x,y,ls=“-”,lw=1.2,c=“b”) # ls: linestyle, lw: lineweight, c: color, b: blue

## format axis
ax[:spines][“right”][:set_visible](false)
ax[:spines][“top”][:set_visible](false)
ax[:yaxis][:set_ticks_position](“left”) # only show vertical ticks on left
ax[:xaxis][:set_ticks_position](“bottom”) # only show horizontal ticks on bottom
arrowed_spines(ax,arrow_length=15) # add arrows to spines
ax[:annotate](L"\shortstack[l]{y-axis label, $y$}“,xy=(0.03,1.0),xycoords="axes fraction”) # y label
ax[:annotate](L"\shortstack[r]{x-axis\label, $\chi$}“,xy=(0.87,0.04),xycoords="axes fraction”) # x label

And the result should look like the following: (Note that you should have a running LaTeX engine behind all these. Otherwise Matplotlib would not be able to parse LaTeX codes.)

## 2. Fonts: Serif v.s. Sans-serif

Over the years, I learned that fonts matter a lot. For example, in a presentation, sans-serif fonts are preferred when prejected through an overhead. In print, however, serif fonts are preferred. How to adjust fonts, and which fonts, in Matlplotlib?

I have a preference for newtxsf and newtxmath. (This is just a suggestoin and you can actually choose whatever fonts you want, provided they are supported in your LaTeX system.)

Below is the script I have at the **beginning** of my Julia script, before running any plotting functions.

1
2
3
4
5
6
7
8
9
10
11
12
13

fonttype = “serif”
# fonttype = “sansserif”
PyPlot.matplotlib[:rc](“text”, usetex=true) # allow tex rendering
PyPlot.matplotlib[:rcParams][“text.latex.unicode”] = true
if fonttype==“serif” # use serif math font
PyPlot.matplotlib[:rc](“font”, family=“serif”, serif=“Times”, size=16)
PyPlot.matplotlib[:rc](“text.latex”,preamble=“\usepackage{newtxmath}”)
else # use sans serif math font
PyPlot.matplotlib[:rc](“font”, family=“sans-serif”, size=16)
PyPlot.matplotlib[:rc](“text.latex”,preamble=“\usepackage{newtxsf}”)
end
PyPlot.matplotlib[:rcParams][“text.latex.unicode”] = false

On lines 1 and 2, I can switch whether I want all graphs later to be generated in (sans-)serif. For example, with the beautiful newtx fonts, the figure in example 1 now looks like: And instead, with sans-serif font:

bzy@Fontainebleau