-
Notifications
You must be signed in to change notification settings - Fork 69
/
PlotRecipes.jl
90 lines (72 loc) · 2.51 KB
/
PlotRecipes.jl
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
module PlotRecipesModule
using RecipesBase: @recipe, @series
using DynamicExpressions: Node, string_tree
using ..CoreModule: Options
using ..HallOfFameModule: HallOfFame, format_hall_of_fame
using ..MLJInterfaceModule: SRFitResult, SRRegressor
@recipe function default_sr_plot(fitresult::SRFitResult{<:SRRegressor})
return fitresult.state[2], fitresult.options
end
# TODO: Add variable names
@recipe function default_sr_plot(hall_of_fame::HallOfFame, options::Options)
out = format_hall_of_fame(hall_of_fame, options)
return (out.trees, out.losses, out.complexities, options)
end
@recipe function default_sr_plot(
trees::Vector{N}, losses::Vector{L}, complexities::Vector{Int}, options::Options
) where {T,L,N<:Node{T}}
tree_strings = [string_tree(tree, options) for tree in trees]
log_losses = @. log10(losses + eps(L))
log_complexities = @. log10(complexities)
# Add an upper right corner to this for the convex hull calculation:
push!(log_losses, maximum(log_losses))
push!(log_complexities, maximum(log_complexities))
xy = cat(log_complexities, log_losses; dims=2)
log_hull = convex_hull(xy)
# Add the first point again to close the hull:
push!(log_hull, log_hull[1])
# Then remove the first two points for visualization
log_hull = log_hull[3:end]
hull = [10 .^ row for row in log_hull]
xlabel --> "Complexity"
ylabel --> "Loss"
xlims --> (0.5, options.maxsize + 1)
xscale --> :log10
yscale --> :log10
# Main complexity/loss plot:
@series begin
label --> "Pareto Front"
complexities, losses
end
# Add on a convex hull:
@series begin
label --> "Convex Hull"
color --> :lightgray
first.(hull), last.(hull)
end
end
"""Uses gift wrapping algorithm to create a convex hull."""
function convex_hull(xy)
cur_point = xy[sortperm(xy[:, 1])[1], :]
hull = typeof(cur_point)[]
while true
push!(hull, cur_point)
end_point = xy[1, :]
for candidate_point in eachrow(xy)
if end_point == cur_point || isleftof(candidate_point, (cur_point, end_point))
end_point = candidate_point
end
end
cur_point = end_point
if end_point == hull[1]
break
end
end
return hull
end
function isleftof(point, line)
(start_point, end_point) = line
return (end_point[1] - start_point[1]) * (point[2] - start_point[2]) -
(end_point[2] - start_point[2]) * (point[1] - start_point[1]) > 0
end
end