Version()
最新バージョン 2024-07-18 11:10
Julia でグラフ表示をする場合,Plots パッケージを使用する。バックエンドは GR を使用することにする。
using Plots
default(
fontfamily = "serif",
titlefont = (12, "times"),
guidefont = (10, "times"),
tickfont = (7, "times"),
label = "",
foreground_color_legend = nothing,
markerstrokewidth = 0,
grid = false,
tick_direction = :out,
alpha = 0.4
)
1 変量のグラフ表示には,名義尺度変数に対しては棒グラフ(bar chart),連続変数に対してはヒストグラム(histogram)が代表的なものである。
2 変量のグラフ表示では散布図が主なものである。
例示に使用するデータセット¶
カテゴリーデータ¶
HairEyeColor データセットは,学生の髪と目の色と性別の集計表である。
using DataFrames
Hair = ["Black", "Brown", "Red", "Blond"]
Eye = ["Brown", "Blue", "Hazel", "Green"]
Sex = ["Male", "Female"]
Freq = [32, 53, 10, 3, 11, 50, 10, 30, 10, 25, 7, 5, 3, 15, 7, 8, 36, 66, 16, 4, 9, 34, 7, 64, 5, 29, 7, 5, 2, 14, 7, 8];
haireyecolor = DataFrame(Base.product(Hair, Eye, Sex));
rename!(haireyecolor, [:Hair, :Eye, :Sex]);
insertcols!(haireyecolor, :Freq => Freq);
first(haireyecolor, 5)
Row | Hair | Eye | Sex | Freq |
---|---|---|---|---|
String | String | String | Int64 | |
1 | Black | Brown | Male | 32 |
2 | Brown | Brown | Male | 53 |
3 | Red | Brown | Male | 10 |
4 | Blond | Brown | Male | 3 |
5 | Black | Blue | Male | 11 |
このデータフレームから,学生一人ずつのデータフレームに展開した HEC データフレームを作成する。
HEC = DataFrame()
for row in eachrow(haireyecolor), j in 1:row.Freq
push!(HEC, row)
end
select!(HEC, Not(:Freq)); # Freq 列を除く
first(HEC, 3) |> println
size(HEC)
3×3 DataFrame Row │ Hair Eye Sex │ String String String ─────┼──────────────────────── 1 │ Black Brown Male 2 │ Black Brown Male 3 │ Black Brown Male
(592, 3)
using FreqTables
freq = freqtable(HEC.Hair)
4-element Named Vector{Int64} Dim1 │ ──────┼──── Black │ 108 Blond │ 127 Brown │ 286 Red │ 71
オプションを何も指定しないと不適切な棒グラフしか得られないことが多い。
bar(vec(freq))
GKS: could not find font serif.ttf
bar(vec(freq),
bar_width=1,
xlabel="Hair color",
xticks=(1:4, names(freq)[1]), # カテゴリーの名前
ylabel="Number of students",
title="Distribution of hair color in students.",
)
注:2024/07 現在,以下の orientations=:horizontal
では,縦軸の描画範囲 ylims を明示的に指定しないと正しく動かない
orientations=:horizontal
を指定すると水平棒グラフになる。$x$ 軸と $y$ 軸に与える内容が入れ替わるので注意が必要である。カテゴリー名が長い場合には水平棒グラフのほうが適していることもある。
bar(vec(freq),
orientations=:horizontal,
bar_width=1,
xlabel="Number of students",
xticks=0:50:250,
ylabel="Hair color",
yticks=(1:4, names(freq)[1]), # カテゴリーの名前
ylims = (0.5, 4.5),
title="Distribution of hair color in students.",
)
二標本以上の場合¶
二次元集計表により,列ごとの棒グラフを描くことができる。
freq2 = freqtable(HEC.Hair, HEC.Sex)
4×2 Named Matrix{Int64} Dim1 ╲ Dim2 │ Female Male ────────────┼─────────────── Black │ 52 56 Blond │ 81 46 Brown │ 143 143 Red │ 37 34
using StatsPlots
p1 = groupedbar(Matrix(freq2),
bar_width=0.8,
bar_position = :dodge,
xlabel = "Hair color",
xticks = (1:4, names(freq2)[1]),
ylabel = "Number of students",
label = ["Female" "Male"],
title = "Distribution of hair color in students.",
)
GKS: glyph missing from current font: 12288 GKS: glyph missing from current font: 12288
積み上げ棒グラフ¶
using StatsPlots
p3 = groupedbar(Matrix(freq2),
bar_width=0.8,
bar_position = :stack,
xlabel = "Hair color",
xticks = (1:4, names(freq2)[1]),
ylabel = "Number of students",
label = ["Female" "Male"],
title = "Distribution of hair color in students.",
)
複数のグラフを行列状にまとめて表示する方法¶
前節 1.2.1., 1.2.2. で描いた 2 つのグラフを1つにまとめることができる。
plot()
の引数として,描かれたグラフを指定する。
描かれるグラフはオブジェクトという変数のようなものに代入できる。実際,p1 = groupedbar(freq,...)
,p2 = groupedbar(freq,...)
のように,p1
, p2
に代入した。
このオブジェクトを plot()
の引数とすればよい。
using Plots.PlotMeasures # 余白の単位 mm などを有効にするために必要
plot(p1, p3,
legend=:topright, # 凡例の位置 :topright, :bottomleft などなど
size=(750, 550), # 横幅,高さをピクセル単位で指定
bottom_margin = 20px # サブプロットのボトムの余白 xxpx
)
GKS: glyph missing from current font: 12288 GKS: glyph missing from current font: 12288
include("obi.jl");
使用法は,freqtable()
の第 1 引数にグループ分けの変数,第 2 引数に分布を表示する変数として得た二重クロス表を barplot2()
に与える。
freq2 = freqtable(HEC.Hair, HEC.Sex)
4×2 Named Matrix{Int64} Dim1 ╲ Dim2 │ Female Male ────────────┼─────────────── Black │ 52 56 Blond │ 81 46 Brown │ 143 143 Red │ 37 34
obi(freq2, ylabel="Hair", title="Distribution of hair color in students")
obi(freqtable(HEC.Sex, HEC.Hair), title="Distribution of hair color in students")
モザイクプロット¶
モザイクプロットは,1.3. の帯グラフにおいて,帯の幅をグループの相対度数に反映させたものである。帯グラフ(積み上げ相対度数分布グラフ)は帯の幅を変えることができないので,以下のような関数を書く。
include("mozaicplot.jl");
てんとう虫の住んでいる場所と色についてのデータをモザイクプロットで描いてみる。
ladybirds_morph_colour.csv
https://github.com/R4All/datasets/blob/master/ladybirds_morph_colour.csv
io = IOBuffer("""
Habitat,Site,morph_colour,number
Rural,R1,black,10
Rural,R2,black,3
Rural,R3,black,4
Rural,R4,black,7
Rural,R5,black,6
Rural,R1,red,15
Rural,R2,red,18
Rural,R3,red,9
Rural,R4,red,12
Rural,R5,red,16
Industrial,U1,black,32
Industrial,U2,black,25
Industrial,U3,black,25
Industrial,U4,black,17
Industrial,U5,black,16
Industrial,U1,red,17
Industrial,U2,red,23
Industrial,U3,red,21
Industrial,U4,red,9
Industrial,U5,red,15""")
using CSV, DataFrames
dat = CSV.read(io, DataFrame);
table = freqtable(dat.morph_colour, dat.Habitat, weights=dat.number)
2×2 Named Matrix{Int64} Dim1 ╲ Dim2 │ Industrial Rural ────────────┼─────────────────────── black │ 115 30 red │ 85 70
mosaicplot(table; xlabel="Havitat", ylabel="morph_colour", color=[:black, :red])
freq2 = freqtable(HEC.Hair, HEC.Sex)
mosaicplot(freq2, xlabel="Sex", ylabel="Hair")
バルーンプロット¶
二重クロス集計表の各マス目の度数を円の面積で表現するのがバルーンプロットである。
以下の関数に freqtable()
による集計表を与えれば描画される。注意点は,円の面積が度数に対応するということ。
include("balloonplot.jl");
EyeHair = freqtable(HEC.Eye, HEC.Hair)
balloonplot(EyeHair,
xlabel="Hair color", ylabel="Eye color", color=:blue)