Skip to content

Commit 4497502

Browse files
Pareto chart implementation (#431)
* Initial implementation for Pareto chart Co-authored-by: John Casagranda <[email protected]> Co-authored-by: Gauthier Segay <[email protected]> * missing files Co-authored-by: John Casagranda <[email protected]> Co-authored-by: Gauthier Segay <[email protected]> * C# has the fun too. Co-authored-by: John Casagranda <[email protected]> Co-authored-by: Gauthier Segay <[email protected]> * Confused... Co-authored-by: John Casagranda <[email protected]> Co-authored-by: Gauthier Segay <[email protected]> * Typo... Co-authored-by: John Casagranda <[email protected]> Co-authored-by: Gauthier Segay <[email protected]> * Adjustments: remove the points chart, using the markers on the line chart instead, adding overloads to take the labels and values separately, adding ShowGrid as an option. Co-authored-by: John Casagranda <[email protected]> Co-authored-by: Gauthier Segay <[email protected]> --------- Co-authored-by: John Casagranda <[email protected]>
1 parent 92f92a5 commit 4497502

File tree

5 files changed

+199
-2
lines changed

5 files changed

+199
-2
lines changed

Plotly.NET.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04_distribution-charts", "0
148148
docs\distribution-charts\point-density.fsx = docs\distribution-charts\point-density.fsx
149149
docs\distribution-charts\splom.fsx = docs\distribution-charts\splom.fsx
150150
docs\distribution-charts\violin-plots.fsx = docs\distribution-charts\violin-plots.fsx
151+
docs\distribution-charts\pareto-chart.fsx = docs\distribution-charts\pareto-chart.fsx
151152
EndProjectSection
152153
EndProject
153154
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01_chart-layout", "01_chart-layout", "{C7D0EF67-9A18-49DD-AC79-944E384BD8D0}"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
(**
2+
---
3+
title: Pareto chart
4+
category: Distribution Charts
5+
categoryindex: 5
6+
index: 9
7+
---
8+
*)
9+
10+
(*** hide ***)
11+
12+
(*** condition: prepare ***)
13+
#r "nuget: Newtonsoft.JSON, 13.0.1"
14+
#r "nuget: DynamicObj, 2.0.0"
15+
#r "nuget: Giraffe.ViewEngine.StrongName, 2.0.0-alpha1"
16+
#r "../../src/Plotly.NET/bin/Release/netstandard2.0/Plotly.NET.dll"
17+
18+
Plotly.NET.Defaults.DefaultDisplayOptions <-
19+
Plotly.NET.DisplayOptions.init (PlotlyJSReference = Plotly.NET.PlotlyJSReference.NoReference)
20+
21+
(*** condition: ipynb ***)
22+
#if IPYNB
23+
#r "nuget: Plotly.NET, {{fsdocs-package-version}}"
24+
#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}"
25+
#endif // IPYNB
26+
27+
(**
28+
# Pareto chart
29+
30+
[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/plotly.net/gh-pages?urlpath=/tree/home/jovyan/{{fsdocs-source-basename}}.ipynb)&emsp;
31+
[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb)
32+
33+
*Summary:* This example shows how to create a Pareto chart in F#.
34+
35+
Let's first create some data for the purpose of creating example charts:
36+
37+
*)
38+
39+
open Plotly.NET
40+
41+
let data =
42+
[
43+
"C#" , 420.
44+
"F#" , 10008
45+
"Smalltalk" , 777
46+
"Pascal" , 543
47+
"Perl" , 666
48+
"VB.NET" , 640
49+
"C" , 111
50+
"ChucK" , 1230
51+
"ARexx" , 4440
52+
]
53+
54+
(**
55+
56+
A Pareto chart is a type of chart that contains both bars and a line graph, where individual values are represented in descending order by bars, and the cumulative total is represented by the line.
57+
The chart is named for the Pareto principle, which, in turn, derives its name from Vilfredo Pareto, a noted Italian economist. <sup>[Source](https://en.wikipedia.org/wiki/Pareto_chart)</sup>
58+
*)
59+
60+
let pareto = Chart.Pareto(keysValues = data, Name="Language", Label="Respondents")
61+
62+
(*** condition: ipynb ***)
63+
#if IPYNB
64+
pareto
65+
#endif // IPYNB
66+
67+
(***hide***)
68+
pareto |> GenericChart.toChartHTML
69+
(***include-it-raw***)
70+

src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,48 @@ public static GenericChart Range<XType, YType, TextType>(
600600
UpperName: UpperName.ToOption(),
601601
UseDefaults: UseDefaults.ToOption()
602602
);
603+
604+
/// <summary> Creates a Pareto chart. </summary>
605+
/// <param name="keysValues">Sets the (key,value) pairs that are plotted as the size and key of each bar.</param>
606+
/// <param name="Name">Sets the trace name. The trace name appear as the legend item and on hover</param>
607+
/// <param name="Label">Sets the y axis label.</param>
608+
/// <param name="ShowGrid">Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.</param>
609+
public static GenericChart Pareto<TLabel>(
610+
IEnumerable<(TLabel,double)> keysValues
611+
, Optional<string> Name
612+
, Optional<string> Label
613+
, Optional<bool> ShowGrid
614+
)
615+
where TLabel : IConvertible
616+
=>
617+
Chart2D.Chart.Pareto(
618+
keysValues.Select(t => t.ToTuple())
619+
, Name: Name.ToOption()
620+
, Label: Label.ToOption()
621+
, ShowGrid: ShowGrid.ToOption()
622+
);
623+
/// <summary> Creates a Pareto chart. </summary>
624+
/// <param name="labels">Sets the labels that are matching the <see paramref="values"/>.</param>
625+
/// <param name="values">Sets the values that are plotted as the size of each bar.</param>
626+
/// <param name="Name">Sets the trace name. The trace name appear as the legend item and on hover</param>
627+
/// <param name="Label">Sets the y axis label.</param>
628+
/// <param name="ShowGrid">Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.</param>
629+
public static GenericChart Pareto<TLabel>(
630+
IEnumerable<TLabel> labels
631+
, IEnumerable<double> values
632+
, Optional<string> Name
633+
, Optional<string> Label
634+
, Optional<bool> ShowGrid
635+
)
636+
where TLabel : IConvertible
637+
=>
638+
Chart2D.Chart.Pareto(
639+
labels
640+
, values
641+
, Name: Name.ToOption()
642+
, Label: Label.ToOption()
643+
, ShowGrid: ShowGrid.ToOption()
644+
);
603645

604646
/// <summary> Creates an Area chart, which uses a Line plotted between the given datums in a 2D space, additionally colouring the area between the line and the Y Axis.</summary>
605647
/// <param name="x">Sets the x coordinates of the plotted data.</param>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Plotly.NET.CSharp;
2+
3+
/// <summary>
4+
/// Convenience to convert from C# struct tuple literals to the value tuple ones.
5+
/// </summary>
6+
internal static class TupleExtensions
7+
{
8+
/// <summary>
9+
/// Converts a 2 tuple.
10+
/// </summary>
11+
internal static Tuple<T1,T2> ToTuple<T1,T2>(this ValueTuple<T1,T2> t) => Tuple.Create(t.Item1, t.Item2);
12+
}

src/Plotly.NET/ChartAPI/Chart2D.fs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,8 +1547,80 @@ module Chart2D =
15471547
?UpperName = UpperName,
15481548
?UseDefaults = UseDefaults
15491549
)
1550-
1551-
1550+
1551+
/// <summary> Creates a Pareto chart. </summary>
1552+
/// <param name="keysValues">Sets the (key,value) pairs that are plotted as the size and key of each bar.</param>
1553+
/// <param name="Name">Sets the trace name. The trace name appear as the legend item and on hover</param>
1554+
/// <param name="Label">Sets the y axis label.</param>
1555+
/// <param name="ShowGrid">Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.</param>
1556+
[<Extension>]
1557+
static member Pareto
1558+
(
1559+
keysValues: seq<#IConvertible * float>
1560+
, [<Optional; DefaultParameterValue(null)>] ?Name: string
1561+
, [<Optional; DefaultParameterValue(null)>] ?Label: string
1562+
, [<Optional; DefaultParameterValue(true)>] ?ShowGrid: bool
1563+
) =
1564+
let orderedLabels, orderedValues =
1565+
keysValues
1566+
|> Seq.sortByDescending snd
1567+
|> Seq.unzip
1568+
1569+
let sum = orderedValues |> Seq.sum
1570+
let topPaddingRatio = 0.05
1571+
let cumulativeSum =
1572+
Seq.scan (+) 0. orderedValues
1573+
|> Seq.skip 1
1574+
1575+
let paretoValues =
1576+
Seq.zip orderedLabels cumulativeSum
1577+
|> Seq.map (fun (label,value) -> label, value / sum * 100.)
1578+
1579+
let bars = Chart.Column(Seq.zip orderedLabels orderedValues,?Name=Name)
1580+
1581+
let lines =
1582+
Chart.Line(
1583+
paretoValues
1584+
, Name = "Cumulative %"
1585+
, ShowLegend = true
1586+
, ShowMarkers = true
1587+
, Marker = Marker.init(Size = 8, Symbol = StyleParam.MarkerSymbol.Cross, Angle = 45.)
1588+
)
1589+
|> Chart.withAxisAnchor (Y = 2)
1590+
1591+
[bars;lines]
1592+
|> Chart.combine
1593+
|> Chart.withYAxisStyle (
1594+
?TitleText = Label
1595+
, Id = StyleParam.SubPlotId.YAxis 1
1596+
, ShowGrid = false
1597+
, MinMax = (0.,sum * (1.+topPaddingRatio))
1598+
)
1599+
|> Chart.withYAxisStyle (
1600+
TitleText = "%"
1601+
, Side = StyleParam.Side.Right
1602+
, Id = StyleParam.SubPlotId.YAxis 2
1603+
, MinMax = (0.,100. * (1.+topPaddingRatio))
1604+
, Overlaying = StyleParam.LinearAxisId.Y 1
1605+
, ?ShowGrid = ShowGrid
1606+
)
1607+
1608+
/// <summary> Creates a Pareto chart. </summary>
1609+
/// <param name="labels">Sets the labels that are matching the <see paramref="values"/>.</param>
1610+
/// <param name="values">Sets the values that are plotted as the size of each bar.</param>
1611+
/// <param name="Name">Sets the trace name. The trace name appear as the legend item and on hover</param>
1612+
/// <param name="Label">Sets the y axis label.</param>
1613+
/// <param name="ShowGrid">Determines whether or not grid lines are drawn. If "true", the grid lines are drawn for the pareto distribution figure; defaults to true.</param>
1614+
static member Pareto
1615+
(
1616+
labels: seq<#IConvertible>
1617+
, values: seq<float>
1618+
, [<Optional; DefaultParameterValue(null)>] ?Name: string
1619+
, [<Optional; DefaultParameterValue(null)>] ?Label: string
1620+
, [<Optional; DefaultParameterValue(true)>] ?ShowGrid: bool
1621+
) =
1622+
Chart.Pareto(Seq.zip labels values, ?Name=Name, ?Label=Label, ?ShowGrid=ShowGrid)
1623+
15521624
/// <summary> Creates an Area chart, which uses a Line plotted between the given datums in a 2D space, additionally colouring the area between the line and the Y Axis.</summary>
15531625
/// <param name="x">Sets the x coordinates of the plotted data.</param>
15541626
/// <param name="y">Sets the y coordinates of the plotted data.</param>

0 commit comments

Comments
 (0)