Skip to content

Commit 05f551e

Browse files
add series type introduction pages (#322)
1 parent b93df44 commit 05f551e

File tree

3 files changed

+277
-0
lines changed

3 files changed

+277
-0
lines changed

docs/make.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ const PAGES = Any[
111111
"Installation" => "install.md",
112112
"Basics" => "basics.md",
113113
"Tutorial" => "tutorial.md",
114+
"Series Types" => [
115+
"Contour Plots" => "series_types/contour.md",
116+
"Histograms" => "series_types/histogram.md",
117+
],
114118
],
115119
"Manual" => [
116120
"Input Data" => "input_data.md",

docs/src/series_types/contour.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
```@setup contour
2+
using Plots
3+
Plots.reset_defaults()
4+
```
5+
6+
# [Contour Plots](@id contour)
7+
8+
The easiest way to get started with contour plots is to use the PyPlot backend. PyPlot requires the `PyPlot.jl`
9+
package which can be installed by typing `]` and then `add PyPlot` into the REPL. The first time you call `pyplot()`,
10+
Julia may install matplotlib for you. All of the plots generated on this page use PyPlot, although the code will work
11+
for the default GR backend as well.
12+
13+
Let's define some ranges and a function `f(x, y)` to plot. Notice the `'` in the line defining `z`.
14+
This is the adjoint operator and makes `x` a row vector. You can check the shape of `x'` by typing `size(x')`. In the
15+
tutorial, we mentioned that the `@.` macro evaluates whatever is to the right of it in an element-wise manner. More
16+
precisely, the dot `.` is shorthand for broadcasting; since `x'` is of size `(1, 100)` and y is of size `(50, )`,
17+
`z = @. f(x', y)` will broadcast the function `f` over `x'` and `y` and yield a matrix of size `(50, 100)`.
18+
19+
```@example contour
20+
using Plots; pyplot()
21+
22+
f(x, y) = (3x + y^2) * abs(sin(x) + cos(y))
23+
24+
x = range(0, 5, length=100)
25+
y = range(0, 3, length=50)
26+
z = @. f(x', y)
27+
contour(x, y, z)
28+
```
29+
30+
Much like with `plot!` and `scatter!`, the `contour` function also has a mutating version `contour!` which can be
31+
used to modify the plot after it has been generated.
32+
33+
With the PyPlot backend, `contour` can also take in a row vector for `x`, so alternatively, you can define `x` as
34+
a row vector as shown below and PyPlot will know how to plot it correctly. Beware that this will NOT work for other
35+
backends such as the default GR backend, which require `x` and `y` to both be column vectors.
36+
37+
```julia
38+
x = range(0, 5, length=100)'
39+
y = range(0, 3, length=50)
40+
z = @. f(x, y)
41+
contour(x, y, z)
42+
```
43+
44+
## Common Attributes
45+
46+
Let's make this plot more presentable with the following attributes:
47+
48+
1. The number of levels can be changed with `levels`.
49+
2. Besides the title and axes labels, we can also add contour labels via the attribute `contour_labels`, which has the
50+
alias `clabels`. We'll use the LaTeXStrings.jl package to write the function expression in the title. (To install this
51+
package, type `]` and then `add LaTeXStrings` into the REPL.)
52+
3. The colormap can be changed using `seriescolor`, which has the alias `color`, or even `c`. The default colormap is
53+
`:inferno`, from matplotlib. A full list of colormaps can be found in the ColorSchemes section of the manual.
54+
4. The colorbar location can be changed with the attribute `colorbar`, alias `cbar`. We can remove it by setting
55+
`cbar=false`.
56+
5. The widths of the isocontours can be changed using `linewidth`, or `lw`.
57+
58+
Note that `levels`, `color`, and `contour_labels` need to be specified in `contour`.
59+
60+
```@example contour
61+
using LaTeXStrings
62+
63+
f(x, y) = (3x + y^2) * abs(sin(x) + cos(y))
64+
65+
x = range(0, 5, length=100)
66+
y = range(0, 3, length=50)
67+
z = @. f(x', y)
68+
69+
contour(x, y, z, levels=10, color=:turbo, clabels=true, cbar=false, lw=1)
70+
title!(L"Plot of $(3x + y^2)|\sin(x) + \cos(y)|$")
71+
xlabel!(L"x")
72+
ylabel!(L"y")
73+
```
74+
75+
If only black lines are desired, you can set the `color` attribute like so:
76+
77+
```julia
78+
contour(x, y, z, color=[:black])
79+
```
80+
81+
and for alternating black and red lines of a specific hex value, you could type `color=[:black, "#E52B50"]`, and so on.
82+
83+
To get a full list of the available values that an attribute can take, type `plotattr("attribute")` into the REPL. For
84+
example, `plotattr("cbar")` shows that it can take either symbols from a predefined list (e.g. `:left` and `:top`),
85+
which move the colorbar from its default location; or a boolean `true` or `false`, the latter of which hides the
86+
colorbar.
87+
88+
## Filled Contours
89+
90+
We can also specify that the contours should be filled in. One way to do this is by using the attribute `fill`:
91+
92+
```julia
93+
contour(x, y, z, fill=true)
94+
```
95+
96+
Another way is to use the function `contourf`, along with its mutating version `contourf!`:
97+
98+
```@example contour
99+
contourf(x, y, z, levels=20, color=:turbo)
100+
title!(L"(3x + y^2)|\sin(x) + \cos(y)|")
101+
xlabel!(L"x")
102+
ylabel!(L"y")
103+
```
104+
105+
If you are using the GR backend to plot filled contours, there will be black lines separating the filled regions. If
106+
these lines are undesirable, you can set the line width to 0: `lw=0`.
107+
108+
## Logarithmic Contour Plots
109+
110+
Much like with line and scatter plots, the X and Y axes can be made logarithmic through the `xscale` and `yscale`
111+
attributes. If both axes need to be logarithmic, then you can set `scale=:log10`.
112+
113+
It will be easier for the backend to generate the plot if the attributes are specified in the `contourf` command
114+
directly instead of using their mutating versions.
115+
116+
```@example contour
117+
g(x, y) = log(x*y)
118+
119+
x = 10 .^ range(0, 6, length=100)
120+
y = 10 .^ range(0, 6, length=100)
121+
z = @. g(x', y)
122+
contourf(x, y, z, color=:plasma, scale=:log10,
123+
title=L"\log(xy)", xlabel=L"x", ylabel=L"y")
124+
```
125+
126+
It is often desired that the colorbar be logarithmic. The process to get this working correctly is a bit more involved
127+
and will require some manual tweaking. First, we define a function `h(x, y) = exp(x^2 + y^2)`, which we will plot the
128+
logarithm of. Then we adjust the `levels` and `colorbar_ticks` attributes.
129+
130+
The `colorbar_ticks` attribute can take in a tuple of two vectors `(tickvalues, ticklabels)`. Since `h(x, y)` varies
131+
from 10<sup>0</sup> to 10<sup>8</sup> over the prescribed domain, tickvalues will be a vector `tv = 0:8`. We can format
132+
the labels with superscripts by using LaTeXStrings again. Note that the string interpolation operator changes from `$`
133+
to `%$` when working within `L"..."` to avoid clashing with `$` as normally used in LaTeX.
134+
135+
```@example contour
136+
h(x, y) = exp(x^2 + y^2)
137+
138+
x = range(-3, 3, length=100)
139+
y = range(-3, 3, length=100)
140+
z = @. h(x', y)
141+
142+
tv = 0:8
143+
tl = [L"10^{%$i}" for i in tv]
144+
contourf(x, y, log10.(z), color=:turbo, levels=8,
145+
colorbar_ticks=(tv, tl), aspect_ratio=:equal,
146+
title=L"\exp(x^{2} + y^{2})", xlabel=L"x", ylabel=L"y")
147+
```
148+
149+
If you want the fill boundaries to correspond to the orders of magnitude, `levels=8`. Depending on the data, this
150+
number may require some tweaking. If you want a smoother plot, then you can set `levels` to a much larger number.

docs/src/series_types/histogram.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
```@setup histogram
2+
using Plots; gr()
3+
Plots.reset_defaults()
4+
```
5+
6+
# [Histograms](@id histogram)
7+
8+
One-dimensional histograms are accessed through the function `histogram` and its mutating variant `histogram!`. We
9+
will use the default GR backend on this page.
10+
11+
The most basic plot of a histogram is that of a vector of random numbers sampled from the unit normal distribution.
12+
13+
```@example histogram
14+
using Plots
15+
16+
x = randn(10^3)
17+
histogram(x)
18+
```
19+
20+
The default number of bins is determined by the
21+
[Freedman-Diaconis rule](https://en.wikipedia.org/wiki/Histogram#Freedman%E2%80%93Diaconis'_choice). You can select
22+
other bin algorithms using the attribute `bins`, which can take on values like `:sqrt`, or `:scott` for
23+
[Scott's rule](https://en.wikipedia.org/wiki/Histogram#Scott's_normal_reference_rule). Alternatively, you can pass
24+
in a range to more precisely control the number of bins and their minimum and maximum. For example, to plot 20 bins
25+
from -5 to +5, type
26+
27+
```julia
28+
range(-5, 5, length=21)
29+
```
30+
31+
where we have to add 1 to the length because the length counts the number of bin boundaries. Finally, you can also pass
32+
in an integer, like `bins=15`, but this will only be an approximation and the actual number of bins may vary.
33+
34+
## Normalization
35+
36+
It is often desirable to normalize the histogram in some way. To do this, the `normalize` attribute is used, and
37+
we want `normalize=:pdf` (or `:true`) to normalize the total area of the bins to 1. Since we sampled from the normal
38+
distribution, we may as well plot it too. Of course, other common attributes like the title, axis labels, and colors
39+
can be changed as well.
40+
41+
```@example histogram
42+
p(x) = 1/sqrt(2pi) * exp(-x^2/2)
43+
b_range = range(-5, 5, length=21)
44+
45+
histogram(x, label="Experimental", bins=b_range, normalize=:pdf, color=:gray)
46+
plot!(p, label="Analytical", lw=3, color=:red)
47+
xlims!(-5, 5)
48+
ylims!(0, 0.4)
49+
title!("Normal distribution, 1000 samples")
50+
xlabel!("x")
51+
ylabel!("P(x)")
52+
```
53+
54+
`normalize` can take on other values, including:
55+
56+
* `:probability`, which sums all the bin heights to 1
57+
* `:density`, which makes the area of each bin equal to the counts
58+
59+
## Weighted Histograms
60+
61+
Another common feature is to weight the values in `x`. Say that `x` consists of data sampled from a uniform
62+
distribution and we wanted to weight the values according to an exponential function. We would pass in a vector of
63+
weights of the same length as `x`. To check that the weighting is done correctly, we plot the exponential function
64+
multiplied by a normalization factor.
65+
66+
```@example histogram
67+
f_exp(x) = exp(x)/(exp(1)-1)
68+
69+
x = rand(10^4)
70+
w = exp.(x)
71+
72+
histogram(x, label="Experimental", bins=:scott, weights=w, normalize=:pdf, color=:gray)
73+
plot!(f_exp, label="Analytical", lw=3, color=:red)
74+
plot!(legend=:topleft)
75+
xlims!(0, 1.0)
76+
ylims!(0, 1.6)
77+
title!("Uniform distribution, weighted by exp(x)")
78+
xlabel!("x")
79+
ylabel!("P(x)")
80+
```
81+
82+
## Other Variations
83+
84+
* Histogram scatter plots can be made via `scatterhist` and `scatterhist!`, where points substitute in for bars.
85+
* Histogram step plots can be made via `stephist` and `stephist!`, where an outline substitutes in for bars.
86+
87+
```@example histogram
88+
p1 = histogram(x, title="Bar")
89+
p2 = scatterhist(x, title="Scatter")
90+
p3 = stephist(x, title="Step")
91+
plot(p1, p2, p3, layout=(1, 3), legend=false)
92+
```
93+
94+
## 2D Histograms
95+
96+
Two-dimensional histograms are accessed through the function `histogram2d` and its mutating variant `histogram2d!`.
97+
To plot them, two vectors `x` and `y` of the same length are needed.
98+
99+
The histogram is plotted in 2D as a heatmap instead of as 3D bars. The default colormap is `:inferno`, as with contour
100+
plots and heatmaps. Bins without any count are not plotted at all by default.
101+
102+
```@example histogram
103+
x = randn(10^4)
104+
y = randn(10^4)
105+
histogram2d(x, y)
106+
```
107+
108+
Things like custom bin numbers, weights, and normalization work in 2D, along with changing things like the
109+
colormap. However, the bin numbers need to be passed in via tuples; if only one number is passed in for
110+
the bins, for example, it is assumed that both axes will set the same number of bins. Additionally, the weights
111+
only accept a single vector for the `x` values.
112+
113+
Not plotting the bins at all may not be visually appealing, especially if a colormap is used with dark colors on the
114+
low end. To rectify this, use the attribute `show_empty_bins=true`.
115+
116+
```@example histogram
117+
w = exp.(x)
118+
histogram2d(x, y, bins=(40, 20), show_empty_bins=true,
119+
normalize=:pdf, weights=w, color=:plasma)
120+
title!("Normalized 2D Histogram")
121+
xlabel!("x")
122+
ylabel!("y")
123+
```

0 commit comments

Comments
 (0)