Skip to content

Commit 56c935f

Browse files
committed
Add support for multiple axis
1 parent b0e2e23 commit 56c935f

File tree

11 files changed

+262
-60
lines changed

11 files changed

+262
-60
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.2010
3+
VisualStudioVersion = 15.0.27004.2002
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}"
66
ProjectSection(SolutionItems) = preProject
@@ -36,6 +36,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D
3636
docs\content\box-plots.fsx = docs\content\box-plots.fsx
3737
docs\content\bubble-charts.fsx = docs\content\bubble-charts.fsx
3838
docs\content\contour-plots.fsx = docs\content\contour-plots.fsx
39+
docs\content\extensions.fsx = docs\content\extensions.fsx
3940
docs\content\getting-started.fsx = docs\content\getting-started.fsx
4041
docs\content\heatmaps.fsx = docs\content\heatmaps.fsx
4142
docs\content\histograms.fsx = docs\content\histograms.fsx

docs/content/extensions.fsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
(*** hide ***)
2+
// This block of code is omitted in the generated HTML documentation. Use
3+
// it to define helpers that you do not want to show in the documentation.
4+
#r "../../bin/Newtonsoft.Json.dll"
5+
#r "../../lib/FSharp.Care.dll"
6+
7+
(**
8+
Getting started...
9+
==================
10+
11+
FSharp.Plotly implements charting suitable for use from F# scripting. Once you load the library as followed, you can use the members of the `Chart` type to easily build charts.
12+
13+
The library provides a complete mapping for the configuration options of the underlying library but empowers you to use the comfortable style known from the beautiful library [F# Charting](http://fslab.org/FSharp.Charting/). So you get a nice F# interface support with the full power of Plotly.
14+
*)
15+
16+
#r "../../bin/FSharp.Plotly.dll"
17+
open FSharp.Plotly
18+
19+
// Functional F# scripting style for Two Y-Axes
20+
21+
[
22+
Chart.Scatter ([1; 2; 3; 4],[12; 9; 15; 12],StyleParam.Mode.Lines_Markers,Name="anchor 1")
23+
|> Chart.withAxisAnchor(Y=1);
24+
Chart.Line([1; 2; 3; 4],[90; 110; 190; 120],Name="anchor 2")
25+
|> Chart.withAxisAnchor(Y=2);
26+
]
27+
|> Chart.Combine
28+
|> Chart.withY_AxisStyle("first",Side=StyleParam.Side.Left,Id=1)
29+
|> Chart.withY_AxisStyle("second",Side=StyleParam.Side.Right,Id=2,Overlaying=StyleParam.AxisAnchorId.Y 1)
30+
|> Chart.Show
31+
32+
33+
34+
// Functional F# scripting style for Two Y-Axes same side
35+
36+
[
37+
Chart.Scatter ([1; 2; 3; 4],[12; 9; 15; 12],StyleParam.Mode.Lines_Markers,Name="anchor 1")
38+
|> Chart.withAxisAnchor(Y=1);
39+
Chart.Line([1; 2; 3; 4],[90; 110; 190; 120],Name="anchor 2")
40+
|> Chart.withAxisAnchor(Y=2);
41+
]
42+
|> Chart.Combine
43+
|> Chart.withX_AxisStyle("x-axis",Domain=(0.3, 1.0))
44+
|> Chart.withY_AxisStyle("first y-axis")
45+
|> Chart.withY_AxisStyle("second y-axis",Side=StyleParam.Side.Left,Id=2,Overlaying=StyleParam.AxisAnchorId.Y 1,Position=0.15,Anchor=StyleParam.AxisAnchorId.Free)
46+
|> Chart.Show
47+
48+
49+
50+
// Simple Subplot
51+

docs/content/parallel-coords.fsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ open FSharp.Plotly
1818
let data =
1919
['A',[|1.;4.;|]; 'B',[|3.;1.5;|]; 'C',[|2.;4.;|]; 'D',[|4.;2.;|];]
2020

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)
2321

2422
(*** define-output:parcoords1 ***)
25-
Chart.ParallelCoord(data,Color="blue",Ranges=dataRange)
23+
Chart.ParallelCoord(data,Color="blue",Ranges=StyleParam.Range.MinMax (1.,5.))
2624
(*** include-it:parcoords1 ***)
2725

2826

src/FSharp.Plotly/Axis.fs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,11 @@ module Axis =
163163
?Zeroline,
164164
?Zerolinecolor,
165165
?Zerolinewidth,
166-
?Anchor,
167-
?Side,
168-
?Overlaying,
166+
?Anchor :StyleParam.AxisAnchorId,
167+
?Side :StyleParam.Side,
168+
?Overlaying :StyleParam.AxisAnchorId,
169169
?Domain,
170-
?Position,
170+
?Position : float,
171171
?IsSubplotObj,
172172
?Tickvalssrc,
173173
?Ticktextsrc,
@@ -217,10 +217,10 @@ module Axis =
217217
Gridwidth |> DynObj.setValueOpt axis "gridwidth"
218218
Zeroline |> DynObj.setValueOpt axis "zeroline"
219219
Zerolinecolor |> DynObj.setValueOpt axis "zerolinecolor"
220-
Zerolinewidth |> DynObj.setValueOpt axis "zerolinewidth"
221-
Anchor |> DynObj.setValueOpt axis "anchor"
220+
Zerolinewidth |> DynObj.setValueOpt axis "zerolinewidth"
221+
Anchor |> DynObj.setValueOptBy axis "anchor" StyleParam.AxisAnchorId.convert
222222
Side |> DynObj.setValueOptBy axis "side" StyleParam.Side.convert
223-
Overlaying |> DynObj.setValueOpt axis "overlaying"
223+
Overlaying |> DynObj.setValueOptBy axis "overlaying" StyleParam.AxisAnchorId.convert
224224
Domain |> DynObj.setValueOptBy axis "domain" StyleParam.Range.convert
225225
Position |> DynObj.setValueOpt axis "position"
226226
IsSubplotObj |> DynObj.setValueOpt axis "_isSubplotObj"

src/FSharp.Plotly/Chart.fs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ type Chart =
261261
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
262262
|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont)
263263
|> GenericChart.ofTraceObject
264-
|> GenericChart.setLayout (Layout.init (Layout.style(Barmode=StyleParam.Barmode.Stack)))
264+
//|> GenericChart.setLayout (Layout.init (Layout.style(Barmode=StyleParam.Barmode.Stack)))
265+
|> GenericChart.setLayout (Layout.init (Barmode=StyleParam.Barmode.Stack))
265266

266267

267268
/// Displays series of column chart type as stacked columns.
@@ -298,7 +299,8 @@ type Chart =
298299
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
299300
|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont)
300301
|> GenericChart.ofTraceObject
301-
|> GenericChart.setLayout (Layout.init (Layout.style(Barmode=StyleParam.Barmode.Stack)))
302+
//|> GenericChart.setLayout (Layout.init (Layout.style(Barmode=StyleParam.Barmode.Stack)))
303+
|> GenericChart.setLayout (Layout.init (Barmode=StyleParam.Barmode.Stack))
302304

303305

304306
/// Displays series of tcolumn chart type as stacked bars.
@@ -435,21 +437,26 @@ type Chart =
435437

436438

437439
/// 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) =
440+
static member ParallelCoord(dims:seq<'key*#seq<'values>>,?Range,?Constraintrange,?Color,?Colorscale,?Width,?Dash,?Domain,?Labelfont,?Tickfont,?Rangefont) =
439441
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))
442+
dims |> Seq.map (fun (k,vals) ->
443+
Dimensions.init(vals)
444+
|> Dimensions.style(vals,?Range=Range,?Constraintrange=Constraintrange,Label=k)
445+
)
448446
Trace.initParallelCoord (
449447
TraceStyle.ParallelCoord (Dimensions=dims',?Domain=Domain,?Labelfont=Labelfont,?Tickfont=Tickfont,?Rangefont=Rangefont)
450448
)
451449
|> TraceStyle.Line(?Width=Width,?Color=Color,?Dash=Dash,?Colorscale=Colorscale)
452450
|> GenericChart.ofTraceObject
451+
452+
453+
/// Computes the parallel coordinates plot
454+
static member ParallelCoord(dims:seq<Dimensions>,?Color,?Colorscale,?Width,?Dash,?Domain,?Labelfont,?Tickfont,?Rangefont) =
455+
Trace.initParallelCoord (
456+
TraceStyle.ParallelCoord (Dimensions=dims,?Domain=Domain,?Labelfont=Labelfont,?Tickfont=Tickfont,?Rangefont=Rangefont)
457+
)
458+
|> TraceStyle.Line(?Width=Width,?Color=Color,?Dash=Dash,?Colorscale=Colorscale)
459+
|> GenericChart.ofTraceObject
453460

454461

455462

src/FSharp.Plotly/ChartExtensions.fs

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ open GenericChart
1111
module ChartExtensions =
1212

1313
open Trace
14+
//open StyleParam
1415

1516
/// Provides a set of static methods for creating charts.
1617
type Chart with
@@ -27,7 +28,20 @@ module ChartExtensions =
2728
|> TraceStyle.TraceInfo(?Name=(naming i Name),?Showlegend=Showlegend,?Legendgroup=Legendgroup,?Visible=Visible)
2829
)
2930
)
30-
31+
32+
/// Set the axis anchor id the trace is belonging to
33+
static member withAxisAnchor(?X,?Y,?Z) =
34+
let idx = if X.IsSome then Some (StyleParam.AxisAnchorId.X X.Value) else None
35+
let idy = if Y.IsSome then Some (StyleParam.AxisAnchorId.Y Y.Value) else None
36+
let idz = if Z.IsSome then Some (StyleParam.AxisAnchorId.Z Z.Value) else None
37+
38+
(fun (ch:GenericChart) ->
39+
ch |> mapTrace (fun trace ->
40+
trace
41+
|> TraceStyle.SetAxisAnchor(?X=idx,?Y=idy,?Z=idz)
42+
)
43+
)
44+
3145
/// Apply styling to the Marker(s) of the chart as Object.
3246
static member withMarker(marker:Marker) =
3347
(fun (ch:GenericChart) ->
@@ -94,7 +108,7 @@ module ChartExtensions =
94108
// ####################### Apply to layout
95109

96110
// Sets x-Axis of 2d and 3d- Charts
97-
static member withX_Axis(xAxis:Axis.LinearAxis) =
111+
static member withX_Axis(xAxis:Axis.LinearAxis,?Id) =
98112
(fun (ch:GenericChart) ->
99113
let contains3d =
100114
ch
@@ -106,8 +120,9 @@ module ChartExtensions =
106120
match contains3d with
107121
| false ->
108122
let layout =
123+
let id = if Id.IsSome then StyleParam.AxisId.X Id.Value else StyleParam.AxisId.X 1
109124
GenericChart.getLayout ch
110-
|> Layout.style (xAxis=xAxis)
125+
|> Layout.AddLinearAxis(id,axis=xAxis)
111126
GenericChart.setLayout layout ch
112127
| true ->
113128
let layout =
@@ -119,14 +134,16 @@ module ChartExtensions =
119134

120135

121136
// Sets x-Axis of 2d and 3d- Charts
122-
static member withX_AxisStyle(title,?MinMax,?Showgrid,?Showline) =
123-
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
124-
let xaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline)
125-
Chart.withX_Axis(xaxis)
137+
static member withX_AxisStyle(title,?MinMax,?Showgrid,?Showline,?Side,?Overlaying,?Id,?Domain,?Position,?Anchor) =
138+
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
139+
let domain = if Domain.IsSome then Some (StyleParam.Range.MinMax (Domain.Value)) else None
140+
let xaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline,
141+
?Anchor=Anchor,?Side=Side,?Domain=domain,?Overlaying=Overlaying,?Position=Position)
142+
Chart.withX_Axis(xaxis,?Id=Id)
126143

127144

128145
// Sets y-Axis of 2d and 3d- Charts
129-
static member withY_Axis(yAxis:Axis.LinearAxis) =
146+
static member withY_Axis(yAxis:Axis.LinearAxis,?Id) =
130147
(fun (ch:GenericChart) ->
131148
let contains3d =
132149
ch
@@ -138,8 +155,9 @@ module ChartExtensions =
138155
match contains3d with
139156
| false ->
140157
let layout =
158+
let id = if Id.IsSome then StyleParam.AxisId.Y Id.Value else StyleParam.AxisId.Y 1
141159
GenericChart.getLayout ch
142-
|> Layout.style(yAxis=yAxis)
160+
|> Layout.AddLinearAxis(id,axis=yAxis)
143161
GenericChart.setLayout layout ch
144162
| true ->
145163
let layout =
@@ -149,10 +167,12 @@ module ChartExtensions =
149167
)
150168

151169
// Sets y-Axis of 3d- Charts
152-
static member withY_AxisStyle(title,?MinMax,?Showgrid,?Showline) =
153-
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
154-
let yaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline)
155-
Chart.withY_Axis(yaxis)
170+
static member withY_AxisStyle(title,?MinMax,?Showgrid,?Showline,?Side,?Overlaying,?Id,?Domain,?Position,?Anchor) =
171+
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
172+
let domain = if Domain.IsSome then Some (StyleParam.Range.MinMax (Domain.Value)) else None
173+
let yaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,
174+
?Showline=Showline,?Anchor=Anchor,?Side=Side,?Domain=domain,?Overlaying=Overlaying,?Position=Position)
175+
Chart.withY_Axis(yaxis,?Id=Id)
156176

157177

158178

@@ -166,12 +186,46 @@ module ChartExtensions =
166186
)
167187

168188
// Sets z-Axis style with ...
169-
static member withZ_AxisStyle(title,?MinMax,?Showgrid,?Showline) =
170-
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
171-
let zaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline)
189+
static member withZ_AxisStyle(title,?MinMax,?Showgrid,?Showline,?Domain,?Anchor) =
190+
let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
191+
let domain = if Domain.IsSome then Some (StyleParam.Range.MinMax (Domain.Value)) else None
192+
let zaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline,?Anchor=Anchor,?Domain=domain)
172193
Chart.withZ_Axis(zaxis)
173194

174195

196+
//// Sets second x-Axis of 2d- Charts
197+
//static member withX_Axis2(xAxis2:Axis.LinearAxis) =
198+
// (fun (ch:GenericChart) ->
199+
// let layout =
200+
// GenericChart.getLayout ch
201+
// |> Layout.style (xAxis2=xAxis2)
202+
// GenericChart.setLayout layout ch
203+
// )
204+
205+
206+
// // Sets second x-Axis of 2d- Charts
207+
//static member withX_Axis2Style(title,?MinMax,?Showgrid,?Showline) =
208+
// let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
209+
// let xaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline,Side=StyleParam.Side.Top)
210+
// Chart.withX_Axis2(xaxis)
211+
212+
213+
//// Sets second y-Axis of 2d- Charts
214+
//static member withY_Axis2(yAxis2:Axis.LinearAxis) =
215+
// (fun (ch:GenericChart) ->
216+
// let layout =
217+
// GenericChart.getLayout ch
218+
// |> Layout.style (yAxis2=yAxis2)
219+
// GenericChart.setLayout layout ch
220+
// )
221+
222+
223+
// // Sets second x-Axis of 2d- Charts
224+
//static member withY_Axis2Style(title,?MinMax,?Showgrid,?Showline) =
225+
// let range = if MinMax.IsSome then Some (StyleParam.Range.MinMax (MinMax.Value)) else None
226+
// let yaxis = Axis.LinearAxis.init(Title=title,?Range=range,?Showgrid=Showgrid,?Showline=Showline,Side=StyleParam.Side.Right)
227+
// Chart.withY_Axis2(yaxis)
228+
175229

176230
// Set the Layout options of a Chart
177231
static member withLayout(layout:Layout) =

src/FSharp.Plotly/Dimensions.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type Dimensions () =
1010
/// Initialized Dimensions object
1111
static member init
1212
(
13-
values,
13+
?Values,
1414
?Range,
1515
?Constraintrange,
1616
?Visible,
@@ -22,7 +22,7 @@ type Dimensions () =
2222
Dimensions ()
2323
|> Dimensions.style
2424
(
25-
values = values ,
25+
?Values = Values ,
2626
?Range = Range ,
2727
?Constraintrange = Constraintrange,
2828
?Visible = Visible,
@@ -36,7 +36,7 @@ type Dimensions () =
3636
// Applies the styles to Dimensions()
3737
static member style
3838
(
39-
values : seq<#IConvertible>,
39+
?Values : seq<#IConvertible>,
4040
?Range : StyleParam.Range,
4141
?Constraintrange : StyleParam.Range,
4242
?Visible,
@@ -46,7 +46,7 @@ type Dimensions () =
4646
?TickFormat
4747
) =
4848
(fun (dims:Dimensions) ->
49-
values |> DynObj.setValue dims "values"
49+
Values |> DynObj.setValueOpt dims "values"
5050
Range |> DynObj.setValueOptBy dims "range" StyleParam.Range.convert
5151
Constraintrange |> DynObj.setValueOptBy dims "constraintrange" StyleParam.Range.convert
5252
Visible |> DynObj.setValueOpt dims "Visible"

0 commit comments

Comments
 (0)