Skip to content

Commit b0e2e23

Browse files
committed
Add new chart: ParallelCoord
1 parent ae100d2 commit b0e2e23

File tree

11 files changed

+186
-18
lines changed

11 files changed

+186
-18
lines changed

FSharp.Plotly.sln

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Microsoft Visual Studio Solution File, Format Version 12.00
22
# Visual Studio 15
3-
VisualStudioVersion = 15.0.27004.2002
3+
VisualStudioVersion = 15.0.27004.2010
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}"
66
ProjectSection(SolutionItems) = preProject
@@ -41,6 +41,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D
4141
docs\content\histograms.fsx = docs\content\histograms.fsx
4242
docs\content\index.fsx = docs\content\index.fsx
4343
docs\content\line-scatter-plots.fsx = docs\content\line-scatter-plots.fsx
44+
docs\content\parallel-coords.fsx = docs\content\parallel-coords.fsx
4445
docs\content\pie-daughnut-charts.fsx = docs\content\pie-daughnut-charts.fsx
4546
docs\content\plotly-wpf.fsx = docs\content\plotly-wpf.fsx
4647
docs\content\polar-charts.fsx = docs\content\polar-charts.fsx

docs/content/parallel-coords.fsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
(*** hide ***)
2+
#r "../../bin/Newtonsoft.Json.dll"
3+
#r "../../bin/FSharp.Plotly.dll"
4+
5+
(**
6+
# FSharp.Plotly: Parallel Coordinates Plot
7+
8+
*Summary:* This example shows how to create parallel coordinates plot in F#.
9+
10+
Parallel coordinates are a common way of visualizing high-dimensional geometry and analyzing multivariate data.
11+
To show a set of points in an n-dimensional space, a backdrop is drawn consisting of n parallel lines, typically
12+
vertical and equally spaced. A point in n-dimensional space is represented as a polyline with vertices on the parallel axes;
13+
the position of the vertex on the i-th axis corresponds to the i-th coordinate of the point.
14+
*)
15+
16+
open FSharp.Plotly
17+
18+
let data =
19+
['A',[|1.;4.;|]; 'B',[|3.;1.5;|]; 'C',[|2.;4.;|]; 'D',[|4.;2.;|];]
20+
21+
let dataRange =
22+
[StyleParam.Range.MinMax (1.,5.);StyleParam.Range.MinMax (1.,5.);StyleParam.Range.MinMax (1.,5.);StyleParam.Range.MinMax (1.,5.);] |> Seq.map (fun b -> Some b)
23+
24+
(*** define-output:parcoords1 ***)
25+
Chart.ParallelCoord(data,Color="blue",Ranges=dataRange)
26+
(*** include-it:parcoords1 ***)
27+
28+
29+
// Dynanic object version
30+
let parcoords =
31+
let v = [|
32+
Dimensions.init([|1.;4.;|], StyleParam.Range.MinMax (1.,5.),StyleParam.Range.MinMax (1.,2.),Label='A');
33+
Dimensions.init([|3.;1.5;|], StyleParam.Range.MinMax (1.,5.),Label='B',Tickvals=[|1.5;3.;4.;5.;|]);
34+
Dimensions.init([|2.;4.;|], StyleParam.Range.MinMax (1.,5.),Label='C',Tickvals=[|1.;2.;4.;5.;|],TickText=[|"text 1";"text 2";"text 4";"text 5";|]);
35+
Dimensions.init([|4.;2.;|], StyleParam.Range.MinMax (1.,5.),Label='D');
36+
|]
37+
let dyn = Trace("parcoords")
38+
dyn?dimensions <- v
39+
dyn?line <- Line.init(Color = "blue")
40+
dyn
41+
42+
(*** define-output:parcoords2 ***)
43+
parcoords
44+
|> GenericChart.ofTraceObject
45+
(*** include-it:parcoords2 ***)
46+
47+
48+

src/FSharp.Plotly/Axis.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ module Axis =
185185

186186
Autorange |> DynObj.setValueOptBy axis "autorange" StyleParam.AutoRange.convert
187187
Rangemode |> DynObj.setValueOptBy axis "rangemode" StyleParam.RangeMode.convert
188-
Range |> DynObj.setValueOptBy axis "range" StyleParam.RangeValues.convert
188+
Range |> DynObj.setValueOptBy axis "range" StyleParam.Range.convert
189189
Fixedrange |> DynObj.setValueOpt axis "fixedrange"
190190
Tickmode |> DynObj.setValueOptBy axis "tickmode" StyleParam.TickMode.convert
191191
nTicks |> DynObj.setValueOpt axis "nticks"
@@ -221,7 +221,7 @@ module Axis =
221221
Anchor |> DynObj.setValueOpt axis "anchor"
222222
Side |> DynObj.setValueOptBy axis "side" StyleParam.Side.convert
223223
Overlaying |> DynObj.setValueOpt axis "overlaying"
224-
Domain |> DynObj.setValueOptBy axis "domain" StyleParam.RangeValues.convert
224+
Domain |> DynObj.setValueOptBy axis "domain" StyleParam.Range.convert
225225
Position |> DynObj.setValueOpt axis "position"
226226
IsSubplotObj |> DynObj.setValueOpt axis "_isSubplotObj"
227227
Tickvalssrc |> DynObj.setValueOpt axis "tickvalssrc"

src/FSharp.Plotly/Chart.fs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ open System.IO
77
open GenericChart
88
open Trace
99
open Trace3d
10+
open StyleParam
1011

1112

1213
// ###########
@@ -74,7 +75,7 @@ type Chart =
7475
let isShowMarker =
7576
match ShowMarkers with
7677
| Some isShow -> isShow
77-
| None -> false
78+
| Option.None -> false
7879
StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome)
7980
>> StyleParam.ModeUtils.showMarker (isShowMarker)
8081

@@ -97,7 +98,7 @@ type Chart =
9798
let isShowMarker =
9899
match ShowMarkers with
99100
| Some isShow -> isShow
100-
| None -> false
101+
| Option.None -> false
101102
StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome)
102103
>> StyleParam.ModeUtils.showMarker (isShowMarker)
103104

@@ -142,7 +143,7 @@ type Chart =
142143
let isShowMarker =
143144
match ShowMarkers with
144145
| Some isShow -> isShow
145-
| None -> false
146+
| Option.None -> false
146147
StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome)
147148
>> StyleParam.ModeUtils.showMarker (isShowMarker)
148149

@@ -185,7 +186,7 @@ type Chart =
185186
let isShowMarker =
186187
match ShowMarkers with
187188
| Some isShow -> isShow
188-
| None -> false
189+
| Option.None -> false
189190
StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome)
190191
>> StyleParam.ModeUtils.showMarker (isShowMarker)
191192

@@ -211,7 +212,7 @@ type Chart =
211212
let isShowMarker =
212213
match ShowMarkers with
213214
| Some isShow -> isShow
214-
| None -> false
215+
| Option.None -> false
215216
StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome)
216217
>> StyleParam.ModeUtils.showMarker (isShowMarker)
217218

@@ -235,7 +236,7 @@ type Chart =
235236
let marker =
236237
match Marker with
237238
| Some marker -> marker |> FSharp.Plotly.Marker.style(?Color=Color)
238-
| None -> FSharp.Plotly.Marker.init (?Color=Color)
239+
| Option.None -> FSharp.Plotly.Marker.init (?Color=Color)
239240

240241
Trace.initBar (TraceStyle.Bar(X = keys,Y = values,Marker=marker))
241242
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
@@ -254,7 +255,7 @@ type Chart =
254255
let marker =
255256
match Marker with
256257
| Some marker -> marker |> FSharp.Plotly.Marker.style(?Color=Color)
257-
| None -> FSharp.Plotly.Marker.init (?Color=Color)
258+
| Option.None -> FSharp.Plotly.Marker.init (?Color=Color)
258259

259260
Trace.initBar (TraceStyle.Bar(X = keys,Y = values,Marker=marker))
260261
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
@@ -274,7 +275,7 @@ type Chart =
274275
let marker =
275276
match Marker with
276277
| Some marker -> marker |> FSharp.Plotly.Marker.style(?Color=Color)
277-
| None -> FSharp.Plotly.Marker.init (?Color=Color)
278+
| Option.None -> FSharp.Plotly.Marker.init (?Color=Color)
278279
Trace.initBar (TraceStyle.Bar(X = keys,Y = values,Marker=marker,Orientation = StyleParam.Orientation.Horizontal))
279280
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
280281
|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont)
@@ -292,7 +293,7 @@ type Chart =
292293
let marker =
293294
match Marker with
294295
| Some marker -> marker |> FSharp.Plotly.Marker.style(?Color=Color)
295-
| None -> FSharp.Plotly.Marker.init (?Color=Color)
296+
| Option.None -> FSharp.Plotly.Marker.init (?Color=Color)
296297
Trace.initBar (TraceStyle.Bar(X = values,Y = keys,Marker=marker,Orientation = StyleParam.Orientation.Horizontal))
297298
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
298299
|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont)
@@ -432,6 +433,25 @@ type Chart =
432433
//|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
433434
|> GenericChart.ofTraceObject
434435

436+
437+
/// Computes the parallel coordinates plot
438+
static member ParallelCoord(dims:seq<'key*#seq<'values>>,?Ranges:seq<StyleParam.Range option>,?Color,?Colorscale,?Width,?Dash,?Domain,?Labelfont,?Tickfont,?Rangefont) =
439+
let dims' =
440+
if Ranges.IsSome then
441+
Seq.zip dims Ranges.Value
442+
|> Seq.map (fun ((k,vals),r) ->
443+
if r.IsSome then Dimensions.init(values=vals,Label=k,Range=r.Value)
444+
else Dimensions.init(values=vals,Label=k)
445+
)
446+
else
447+
dims |> Seq.map (fun (k,vals) -> Dimensions.init(values=vals,Label=k))
448+
Trace.initParallelCoord (
449+
TraceStyle.ParallelCoord (Dimensions=dims',?Domain=Domain,?Labelfont=Labelfont,?Tickfont=Tickfont,?Rangefont=Rangefont)
450+
)
451+
|> TraceStyle.Line(?Width=Width,?Color=Color,?Dash=Dash,?Colorscale=Colorscale)
452+
|> GenericChart.ofTraceObject
453+
454+
435455

436456
// ---------------------------------------------------------------------------------------------------------------------------------------------------
437457
// 3d - Chart --->

src/FSharp.Plotly/ChartExtensions.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ module ChartExtensions =
120120

121121
// Sets x-Axis of 2d and 3d- Charts
122122
static member withX_AxisStyle(title,?MinMax,?Showgrid,?Showline) =
123-
let range = if MinMax.IsSome then Some (StyleParam.RangeValues.MinMax (MinMax.Value)) else None
123+
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
124124
let xaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline)
125125
Chart.withX_Axis(xaxis)
126126

@@ -150,7 +150,7 @@ module ChartExtensions =
150150

151151
// Sets y-Axis of 3d- Charts
152152
static member withY_AxisStyle(title,?MinMax,?Showgrid,?Showline) =
153-
let range = if MinMax.IsSome then Some (StyleParam.RangeValues.MinMax (MinMax.Value)) else None
153+
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
154154
let yaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline)
155155
Chart.withY_Axis(yaxis)
156156

@@ -167,7 +167,7 @@ module ChartExtensions =
167167

168168
// Sets z-Axis style with ...
169169
static member withZ_AxisStyle(title,?MinMax,?Showgrid,?Showline) =
170-
let range = if MinMax.IsSome then Some (StyleParam.RangeValues.MinMax (MinMax.Value)) else None
170+
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
171171
let zaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline)
172172
Chart.withZ_Axis(zaxis)
173173

src/FSharp.Plotly/Dimensions.fs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace FSharp.Plotly
2+
3+
open System
4+
5+
6+
/// Dimensions type inherits from dynamic object
7+
type Dimensions () =
8+
inherit DynamicObj ()
9+
10+
/// Initialized Dimensions object
11+
static member init
12+
(
13+
values,
14+
?Range,
15+
?Constraintrange,
16+
?Visible,
17+
?Label,
18+
?Tickvals,
19+
?TickText,
20+
?TickFormat
21+
) =
22+
Dimensions ()
23+
|> Dimensions.style
24+
(
25+
values = values ,
26+
?Range = Range ,
27+
?Constraintrange = Constraintrange,
28+
?Visible = Visible,
29+
?Label = Label,
30+
?Tickvals = Tickvals,
31+
?TickText = TickText,
32+
?TickFormat = TickFormat
33+
)
34+
35+
36+
// Applies the styles to Dimensions()
37+
static member style
38+
(
39+
values : seq<#IConvertible>,
40+
?Range : StyleParam.Range,
41+
?Constraintrange : StyleParam.Range,
42+
?Visible,
43+
?Label,
44+
?Tickvals,
45+
?TickText,
46+
?TickFormat
47+
) =
48+
(fun (dims:Dimensions) ->
49+
values |> DynObj.setValue dims "values"
50+
Range |> DynObj.setValueOptBy dims "range" StyleParam.Range.convert
51+
Constraintrange |> DynObj.setValueOptBy dims "constraintrange" StyleParam.Range.convert
52+
Visible |> DynObj.setValueOpt dims "Visible"
53+
Label |> DynObj.setValueOpt dims "label"
54+
Tickvals |> DynObj.setValueOpt dims "tickvals"
55+
TickText |> DynObj.setValueOpt dims "ticktext"
56+
TickFormat |> DynObj.setValueOpt dims "tickformat"
57+
58+
// out ->
59+
dims
60+
)
61+
62+
63+
64+

src/FSharp.Plotly/DynamicObj.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ module DynObj =
240240
| _ -> first.SetValue(kv.Key,kv.Value)
241241
first
242242

243+
let setValue (dyn:DynamicObj) propName o =
244+
dyn.SetValue(propName,o)
243245

244246
let setValueOpt (dyn:DynamicObj) propName =
245247
function

src/FSharp.Plotly/FSharp.Plotly.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<Compile Include="Colorbar.fs" />
6464
<Compile Include="Light.fs" />
6565
<Compile Include="Contours.fs" />
66+
<Compile Include="Dimensions.fs" />
6667
<Compile Include="Line.fs" />
6768
<Compile Include="Marker.fs" />
6869
<Compile Include="Font.fs" />

src/FSharp.Plotly/StyleParams.fs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,11 +567,13 @@ module StyleParam =
567567
static member convert = Barmode.toString >> box
568568

569569
/// Defines a Range between min and max value
570-
type RangeValues =
570+
type Range =
571571
| MinMax of float * float
572+
| Values of array<float>
572573

573574
static member convert = function
574575
| MinMax (min,max) -> box [|min;max|]
576+
| Values arr -> box arr
575577

576578

577579

src/FSharp.Plotly/Trace.fs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ module Trace =
5555
let initHistogram2dContour (applyStyle:Trace->Trace) =
5656
Trace("histogram2dcontour") |> applyStyle
5757

58+
/// Init trace for a parallel coordinates plot
59+
let initParallelCoord (applyStyle:Trace->Trace) =
60+
Trace("parcoords") |> applyStyle
61+
62+
5863
/// Functions provide the styling of the Chart objects
5964
type TraceStyle() =
6065

@@ -792,4 +797,29 @@ module Trace =
792797
)
793798

794799

800+
// Applies the styles of parallel coordinates plot to TraceObjects
801+
static member ParallelCoord
802+
(
803+
?Dimensions : seq<Dimensions>,
804+
?Line ,
805+
?Domain ,
806+
?Labelfont ,
807+
?Tickfont : Font,
808+
?Rangefont : Font
809+
) =
810+
(fun (parcoords:('T :> Trace)) ->
811+
812+
Dimensions |> DynObj.setValueOpt parcoords "dimensions"
813+
Line |> DynObj.setValueOpt parcoords "line"
814+
Domain |> DynObj.setValueOpt parcoords "domain"
815+
Labelfont |> DynObj.setValueOpt parcoords "labelfont"
816+
Tickfont |> DynObj.setValueOpt parcoords "tickfont"
817+
Rangefont |> DynObj.setValueOpt parcoords "rangefont"
818+
819+
// out ->
820+
parcoords
821+
)
822+
823+
824+
795825

0 commit comments

Comments
 (0)