-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ternary diagram support #65
Comments
Thanks for the interest in the package. These are very cool plots! Let me read a bit on them. I do think Vizagrams can reproduce them, but it will take a bit of coding in order to compute the position with respect to the three axis. Let me think a bit about it, and I'll try to come up with something. |
OK thanks a lot, any hints in where to start are super welcome! Re the plots:
|
Vizagrams has the grammar specification and the diagramming operations. At the moment, there is no specification implemented for the case of this ternary plot, but it seems like a nice example to port. So, at the moment, an easy to use implementation for a ternary plot is not actually available. But, I've sketched a working solution using the diagramming tools, which is actually quite similar to how one would implement it in the package itself. The only thing missing would be to tie it to the plot specification. I intend to do it in the upcoming days, it shouldn't take very long (I think). In the mean time, here is how you could plot it using the tools available now. First, the triangular grid using Vizagrams
using DataFrames
using CSV
using StatsBase
# Producing the triangular grid
trigside = 200
n = 6
d = S(:stroke=>"black",:fillOpacity=>0)Polygon([-trigside/2,0,trigside/2]⊗[0,sin(π/3)*trigside,0])
ax1 = mapreduce(+,range(0,1,n)⊗range(0,trigside,n)) do x
w = 3
T(cos(π/3)*x[2],sin(π/3)*x[2])*(
S(:fill=>:grey)T(-w/2,0)Rectangle(h=0.5,w=w) ←
(T(-2,0),TextMark(text=x[1],fontsize=5,anchor=:w))
)
end
ax2 = mapreduce(+,range(1,0,n)⊗range(0,trigside,n)) do x
w = 3
T(-cos(π/3)*x[2],sin(π/3)*x[2])*
R(π/3)*(S(:fill=>:grey)T(w/2,0)Rectangle(h=0.5,w=w) → (T(2,0),TextMark(text=x[1],fontsize=5,anchor=:e)))
end
ax3 = mapreduce(+,range(1,0,n)⊗range(0,trigside,n)) do x
w = 3
T(x[2],0)*
R(-π/3)*(S(:fill=>:grey)T(w/2,0)Rectangle(h=0.5,w=w) → (T(2,0),TextMark(text=x[1],fontsize=5,anchor=:e)))
end
d = T(-trigside/2,0)ax1+
T(trigside/2,0)ax2+
T(-trigside/2,0)ax3+
d
grid = T(-trigside/2,0)mapreduce(+,range(0,1,n)[2:end-1]⊗range(0,trigside,n)[2:end-1]) do x
w = 3
h = trigside*(1-x[1])
a = cos(π/3)*h * 2
T(cos(π/3)*x[2],sin(π/3)*x[2])*
S(:stroke=>:grey)Line([[0,0],[a,0]])
end
l = trigside/2
grid = grid +
T(cos(π/3)*l,sin(π/3)*l)M(0)R(π/3)grid +
T(-cos(π/3)*l,sin(π/3)*l)M(0)R(-π/3)grid
tguide = grid + d
draw(tguide) The next step is to adjust the dataset using the clr transformation and the softmax in order to compute the x-y coordinates. df = DataFrame(CSV.File("plotly_election.csv"))
df = df[!,Not(:Column1)]
df = mapreduce((x,y)->hcat(x,y,makeunique=true),["Joly", "Coderre", "Bergeron"],init=df) do c
values = map(eachrow(df[!,["Joly", "Coderre", "Bergeron"]])) do row
log(row[c]/geomean(row))
end
DataFrame(("clr_"*c=>values))
end
df = mapreduce((x,y)->hcat(x,y,makeunique=true),names(df[!,[:clr_Joly,:clr_Coderre,:clr_Bergeron]]),init=df) do c
values = map(eachrow(df[!,[:clr_Joly,:clr_Coderre,:clr_Bergeron]])) do row
exp(row[c]) / sum(exp.(collect(row)))
end
DataFrame(("sft_"*c=>values))
end
df = sort(df,:sft_clr_Bergeron)
function clr_scale(xs::Vector,trigside)
w = map(x->exp(x) / sum(exp.(xs)),xs)
v = [[0,sin(π/3)*trigside],[-trigside/2,0],[trigside/2,0]]
mean(v,weights(w))
end
function clr_scale(xs::DataFrameRow,trigside)
xs = collect(xs)
clr_scale(xs,trigside)
end
data = map(eachrow(df)) do row
clr_scale(row[[:clr_Joly,:clr_Coderre,:clr_Bergeron]],trigside)
end
df = hcat(df,DataFrame(x = [row[1] for row in data], y = [row[2] for row in data]))
sizescale = Linear(domain=(minimum(df[!,:total]),maximum(df[!,:total])), codomain=(2,7))
colorscale = Vizagrams.Categorical(domain=unique(df.winner),codomain=[:red,:blue,:green])
d = tguide + mapreduce(+,eachrow(df)) do row
T(row[:x],row[:y])*
U(sizescale(row[:total]))*
S(:stroke=>:white,:fillOpacity=>0.5,:fill=>colorscale(row[:winner]))*
Circle()
end
draw(d) |
Hello!
first, thanks for a great and lightweight package!
I was wondering to add support for ternary diagrams (mainly to plot stuff on Aitchison simplices), as seen e.g. here: https://yutannihilation.github.io/allYourFigureAreBelongToUs/ggtern/ . I saw some extension guides in documentation (esp. with the rose diagram) but I don't see how to extend the coordinate system to allow the x+y+z coords required for ternary plots.
Is there some good starting point/docs/recommendation for that?
Thanks!
-mk
The text was updated successfully, but these errors were encountered: