Skip to content

Commit 36ebf5f

Browse files
authored
fix type-2 plotting (#36)
1 parent 7562c96 commit 36ebf5f

File tree

3 files changed

+31
-18
lines changed

3 files changed

+31
-18
lines changed

docs/src/changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
- ![](https://img.shields.io/badge/new%20feature-green.svg) added semi-elliptic and singleton membership functions
99
- ![](https://img.shields.io/badge/new%20feature-green.svg) added `gensurf` to plot generating surface
1010
- ![](https://img.shields.io/badge/bugfix-purple.svg) fix plotting of systems with several rules and membership functions.
11+
- ![](https://img.shields.io/badge/bugfix-purple.svg) fix plotting of Type-2 systems
1112

1213
## v0.1.2 -- 2023-03-12
1314

src/plotting.jl

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@ end
2020
legend --> nothing
2121
@series begin
2222
fillrange := x -> mf.hi(x)
23-
fillalpha --> 1.0
24-
linealpha --> 0
23+
fillalpha --> 0.5
24+
linealpha --> 1
25+
linewidth --> 2
2526
x -> mf.lo(x), low, high
2627
end
28+
@series begin
29+
primary := false
30+
linewidth --> 2
31+
x -> mf.hi(x), low, high
32+
end
2733
end
2834

2935
@recipe f(mf::AbstractPredicate, dom::Domain) = mf, low(dom), high(dom)
@@ -91,16 +97,17 @@ end
9197
nrules = length(fis.rules)
9298
layout := (nrules, nin + nout)
9399
size --> (300 * (nin + nout), 200 * nrules)
94-
for rule in fis.rules
100+
for (i, rule) in enumerate(fis.rules)
95101
ants = leaves(rule.antecedent)
96-
for (varname, var) in pairs(fis.inputs)
102+
for (j, (varname, var)) in enumerate(pairs(fis.inputs))
97103
idx = findall(x -> subject(x) == varname, ants)
98104
length(idx) > 1 &&
99105
throw(ArgumentError("Cannot plot repeated variables in rules"))
100106

101107
@series if length(idx) == 1
102108
rel = ants[first(idx)]
103109
title := string(rel)
110+
subplot := (i - 1) * (nin + nout) + j
104111
# TODO: use own recipes for negation and relation
105112
if rel isa FuzzyNegation
106113
legend --> false
@@ -109,23 +116,26 @@ end
109116
var.mfs[predicate(rel)], var.domain
110117
end
111118
else
119+
subplot := (i - 1) * (nin + nout) + j
112120
grid --> false
113121
axis --> false
114122
legend --> false
115123
()
116124
end
117125
end
118126

119-
for (varname, var) in pairs(fis.outputs)
127+
for (j, (varname, var)) in enumerate(pairs(fis.outputs))
120128
idx = findall(x -> subject(x) == varname, rule.consequent)
121129
length(idx) > 1 &&
122130
throw(ArgumentError("Cannot plot repeated variables in rules"))
123131

124132
@series if length(idx) == 1
133+
subplot := (i - 1) * (nin + nout) + nin + j
125134
rel = rule.consequent[first(idx)]
126135
title := string(rel)
127136
var.mfs[predicate(rel)], var.domain
128137
else
138+
subplot := (i - 1) * (nin + nout) + nin + j
129139
grid --> false
130140
axis --> false
131141
legend --> false
@@ -137,7 +147,7 @@ end
137147

138148
@userplot GenSurf
139149
@recipe function f(plt::GenSurf;
140-
Npoints = 100)
150+
Npoints = 100)
141151
fis = first(plt.args)
142152

143153
if length(fis.inputs) > 2

test/test_plotting.jl

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ end
7070
(TriangularMF(10, 15, 20), dom_out),
7171
(GaussianMF(10.0, 1.5), dom_in),
7272
(TrapezoidalMF(7, 9, 10, 12), dom_in),
73-
(TriangularMF(20, 25, 30), dom_out),
73+
(TriangularMF(20, 25, 30), dom_out)
7474
]
7575

7676
titles = [
@@ -82,19 +82,19 @@ end
8282
"tip is average",
8383
"service is excellent",
8484
"food is delicious",
85-
"tip is generous",
85+
"tip is generous"
8686
]
8787

88-
for (p, d, t) in zip(rec, data, titles)
88+
for (i, (p, d, t)) in enumerate(zip(rec, data, titles))
8989
@test p.args == d
9090
if isempty(d)
9191
@test p.plotattributes == Dict(:plot_title => "tipper", :grid => false,
92-
:legend => false, :axis => false, :layout => (3, 3),
93-
:size => (900, 600))
92+
:legend => false, :axis => false, :layout => (3, 3),
93+
:size => (900, 600), :subplot => i)
9494
else
9595
@test p.plotattributes ==
9696
Dict(:plot_title => "tipper", :size => (900, 600), :title => t,
97-
:layout => (3, 3))
97+
:layout => (3, 3), :subplot => i)
9898
end
9999
end
100100
end
@@ -103,23 +103,25 @@ end
103103
mfnames = [:average, :generous]
104104
mfs = [
105105
ConstantSugenoOutput(15),
106-
LinearSugenoOutput(Dictionary([:service, :food], [2.0, 0.5]), 5.0),
106+
LinearSugenoOutput(Dictionary([:service, :food], [2.0, 0.5]), 5.0)
107107
]
108108
var = Variable(Domain(0, 30), Dictionary(mfnames, mfs))
109109
plts = RecipesBase.apply_recipe(Dict{Symbol, Any}(), var, :tip)
110110
for (plt, mfname, mf) in zip(plts, mfnames, mfs)
111111
@test plt.args == (mf, Domain(0, 30))
112112
@test plt.plotattributes == Dict(:plot_title => "tip", :legend => false,
113-
:title => string(mfname), :layout => (1, 2))
113+
:title => string(mfname), :layout => (1, 2))
114114
end
115115
end
116116

117117
@testset "Plotting type-2 membership functions" begin
118118
mf = 0.5 * TriangularMF(1, 2, 3) .. TriangularMF(0, 2, 4)
119-
plt = RecipesBase.apply_recipe(Dict{Symbol, Any}(), mf, 0, 4) |> only
120-
@test plt.args[1](0.0) == mf.lo(0.0)
121-
@test keys(plt.plotattributes) == Set([:fillrange, :legend, :fillalpha, :linealpha])
122-
@test plt.plotattributes[:fillrange](0.0) == mf.hi(0.0)
119+
plt = RecipesBase.apply_recipe(Dict{Symbol, Any}(), mf, 0, 4)
120+
@test plt[1].args[1](0.0) == mf.lo(0.0)
121+
@test keys(plt[1].plotattributes) ==
122+
Set([:fillrange, :legend, :fillalpha, :linewidth, :linealpha])
123+
@test plt[1].plotattributes[:fillrange](0.0) == mf.hi(0.0)
124+
@test plt[2].args[1](2) == 1.0
123125
end
124126

125127
# @testset "Plotting generating surface" begin

0 commit comments

Comments
 (0)