Skip to content

Commit d80378c

Browse files
committed
WIP plotting notebook
1 parent ead27a3 commit d80378c

File tree

3 files changed

+247
-47
lines changed

3 files changed

+247
-47
lines changed

lib/exgboost/plotting.ex

+31-34
Original file line numberDiff line numberDiff line change
@@ -413,69 +413,58 @@ defmodule EXGBoost.Plotting do
413413
align: :center,
414414
baseline: :middle,
415415
font_size: 13,
416-
font: "Calibri",
417-
fill: :black
416+
font: "Calibri"
418417
]
419418

420419
@default_leaf_rect [
421420
corner_radius: 2,
422-
fill: :teal,
423421
opacity: 1
424422
]
425423

426424
@default_split_text [
427425
align: :center,
428426
baseline: :middle,
429427
font_size: 13,
430-
font: "Calibri",
431-
fill: :black
428+
font: "Calibri"
432429
]
433430

434431
@default_split_rect [
435432
corner_radius: 2,
436-
fill: :teal,
437433
opacity: 1
438434
]
439435

440436
@default_split_children [
441437
align: :right,
442438
baseline: :middle,
443-
fill: :black,
444439
font: "Calibri",
445440
font_size: 13
446441
]
447442

448-
@default_yes_path [
449-
stroke: :red
450-
]
443+
@default_yes_path []
451444

452445
@default_yes_text [
453446
align: :center,
454447
baseline: :middle,
455448
font_size: 13,
456449
font: "Calibri",
457-
fill: :black,
458450
text: "yes"
459451
]
460452

461-
@default_no_path [
462-
stroke: :black
463-
]
453+
@default_no_path []
464454

465455
@default_no_text [
466456
align: :center,
467457
baseline: :middle,
468458
font_size: 13,
469459
font: "Calibri",
470-
fill: :black,
471460
text: "no"
472461
]
473462

474463
@plotting_params [
475464
style: [
476465
doc:
477466
"The style to use for the visualization. Refer to `EXGBoost.Plotting.Styles` for a list of available styles.",
478-
default: Application.compile_env(:exgboost, [:plotting, :style], :solarized_light),
467+
default: Application.compile_env(:exgboost, [:plotting, :style], :dracula),
479468
type: {:or, [{:in, Keyword.keys(@styles)}, {:in, [nil, false]}, :keyword_list]}
480469
],
481470
rankdir: [
@@ -948,12 +937,13 @@ defmodule EXGBoost.Plotting do
948937
opts
949938

950939
Keyword.keyword?(opts[:style]) ->
951-
deep_merge_kw(opts, opts[:style])
940+
deep_merge_kw(opts[:style], opts, @defaults)
952941

953942
true ->
954943
style = apply(__MODULE__, opts[:style], [])
955-
deep_merge_kw(opts, style)
944+
deep_merge_kw(style, opts, @defaults)
956945
end
946+
|> then(&deep_merge_kw(@defaults, &1))
957947

958948
%{
959949
"$schema" => "https://vega.github.io/schema/vega/v5.json",
@@ -1278,32 +1268,31 @@ defmodule EXGBoost.Plotting do
12781268
opts
12791269

12801270
Keyword.keyword?(opts[:style]) ->
1281-
deep_merge_kw(opts, opts[:style])
1271+
deep_merge_kw(opts[:style], opts, @defaults)
12821272

12831273
true ->
12841274
style = apply(__MODULE__, opts[:style], [])
1285-
deep_merge_kw(opts, style)
1275+
deep_merge_kw(style, opts, @defaults)
12861276
end
1287-
1288-
defaults = get_defaults()
1277+
|> then(&deep_merge_kw(@defaults, &1))
12891278

12901279
# Try to account for non-default node height / width to adjust spacing
12911280
# between nodes and levels as a quality of life improvement
12921281
# If they provide their own spacing, don't adjust it
12931282
opts =
12941283
cond do
12951284
opts[:rankdir] in [:lr, :rl] and
1296-
opts[:space_between][:levels] == defaults[:space_between][:levels] ->
1285+
opts[:space_between][:levels] == @defaults[:space_between][:levels] ->
12971286
put_in(
12981287
opts[:space_between][:levels],
1299-
defaults[:space_between][:levels] + (opts[:node_width] - defaults[:node_width])
1288+
@defaults[:space_between][:levels] + (opts[:node_width] - @defaults[:node_width])
13001289
)
13011290

13021291
opts[:rankdir] in [:tb, :bt] and
1303-
opts[:space_between][:levels] == defaults[:space_between][:levels] ->
1292+
opts[:space_between][:levels] == @defaults[:space_between][:levels] ->
13041293
put_in(
13051294
opts[:space_between][:levels],
1306-
defaults[:space_between][:levels] + (opts[:node_height] - defaults[:node_height])
1295+
@defaults[:space_between][:levels] + (opts[:node_height] - @defaults[:node_height])
13071296
)
13081297

13091298
true ->
@@ -1313,17 +1302,17 @@ defmodule EXGBoost.Plotting do
13131302
opts =
13141303
cond do
13151304
opts[:rankdir] in [:lr, :rl] and
1316-
opts[:space_between][:nodes] == defaults[:space_between][:nodes] ->
1305+
opts[:space_between][:nodes] == @defaults[:space_between][:nodes] ->
13171306
put_in(
13181307
opts[:space_between][:nodes],
1319-
defaults[:space_between][:nodes] + (opts[:node_height] - defaults[:node_height])
1308+
@defaults[:space_between][:nodes] + (opts[:node_height] - @defaults[:node_height])
13201309
)
13211310

13221311
opts[:rankdir] in [:tb, :bt] and
1323-
opts[:space_between][:nodes] == defaults[:space_between][:nodes] ->
1312+
opts[:space_between][:nodes] == @defaults[:space_between][:nodes] ->
13241313
put_in(
13251314
opts[:space_between][:nodes],
1326-
defaults[:space_between][:nodes] + (opts[:node_width] - defaults[:node_width])
1315+
@defaults[:space_between][:nodes] + (opts[:node_width] - @defaults[:node_width])
13271316
)
13281317

13291318
true ->
@@ -1381,15 +1370,19 @@ defmodule EXGBoost.Plotting do
13811370
%{
13821371
"encode" => %{
13831372
"update" =>
1384-
Map.merge(
1373+
deep_merge_maps(
13851374
%{
13861375
"x" => %{
13871376
"signal" =>
1388-
"(scale('xscale', datum.source.x+(nodeWidth/3)) + scale('xscale', datum.target.x)) / 2"
1377+
"(scale('xscale', datum.source.x#{cond do
1378+
opts[:rankdir] in [:tb, :bt, :lr] -> ~c"-nodeWidth/4"
1379+
opts[:rankdir] in [:rl] -> ~c"+nodeWidth/4"
1380+
true -> ~c""
1381+
end}) + scale('xscale', datum.target.x)) / 2"
13891382
},
13901383
"y" => %{
13911384
"signal" =>
1392-
"(scale('yscale', datum.source.y) + scale('yscale', datum.target.y)) / 2 - (scaledNodeHeight/2)"
1385+
"(scale('yscale', datum.source.y#{if opts[:rankdir] in [:lr, :rl], do: ~c"-nodeWidth/3", else: ~c""}) + scale('yscale', datum.target.y)) / 2 - (scaledNodeHeight/2)"
13931386
}
13941387
},
13951388
format_mark(opts[:yes][:text])
@@ -1405,7 +1398,11 @@ defmodule EXGBoost.Plotting do
14051398
%{
14061399
"x" => %{
14071400
"signal" =>
1408-
"(scale('xscale', datum.source.x+(nodeWidth/3)) + scale('xscale', datum.target.x)) / 2"
1401+
"(scale('xscale', datum.source.x#{cond do
1402+
opts[:rankdir] in [:tb, :bt, :lr] -> ~c"-nodeWidth/4"
1403+
opts[:rankdir] in [:rl] -> ~c"+nodeWidth/4"
1404+
true -> ~c""
1405+
end}) + scale('xscale', datum.target.x)) / 2"
14091406
},
14101407
"y" => %{
14111408
"signal" =>

lib/exgboost/plotting/style.ex

+19-1
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,31 @@ defmodule EXGBoost.Plotting.Style do
77
end
88
end
99

10-
def deep_merge_kw(a, b) do
10+
def deep_merge_kw(a, b, ignore_set \\ []) do
1111
Keyword.merge(a, b, fn
1212
_key, val_a, val_b when is_list(val_a) and is_list(val_b) ->
1313
deep_merge_kw(val_a, val_b)
1414

1515
key, val_a, val_b ->
1616
if Keyword.has_key?(b, key) do
17+
if Keyword.has_key?(ignore_set, key) and Keyword.get(ignore_set, key) == val_b do
18+
val_a
19+
else
20+
val_b
21+
end
22+
else
23+
val_a
24+
end
25+
end)
26+
end
27+
28+
def deep_merge_maps(b, a) do
29+
Map.merge(a, b, fn
30+
_key, val_a, val_b when is_map(val_a) and is_map(val_b) ->
31+
deep_merge_maps(val_a, val_b)
32+
33+
key, val_a, val_b ->
34+
if Map.has_key?(b, key) do
1735
val_b
1836
else
1937
val_a

0 commit comments

Comments
 (0)