Boxplot

Boxplot

Boxplot

Wat gaan we maken?

We gaan een boxplot maken. Als je niet weet wat een boxplot is lees dan de uitleg op:

http://www.dr-aart.nl/Statistiek-boxplot.html

Start het elm programma boxplotdatadraw.elm. Je ziet het volgende

In het vakje links boven kun je de waardes voor een boxplot invullen. Vul daar de volgende waardes in uit het voorbeeld van Dr. Aart:

7,3,8,6,8,5,4,5,3,6,2,6,9,1,2,7,5,8,7,6 (Let op zet geen spaties na de komma’s).

Druk op Enter en je ziet deze boxplot:

 

 

Hoe pakken we het aan?

We gaan het vorige programma in Elm programmeren. Dit doen we met de volgende stappen.

  1. Maak een recursieve functie mergesort om de lijst te sorteren.
  2. Maak functie boxplotdata om de gegevens voor een boxplot te bepalen
  3. Maak functie boxplotdatadraw om op basis van de gegevens van een boxplot een boxplot te tekenen

Maak mergesort functie

Je gaat een recursie functie mergesort maken.  Deze functie mergesort heeft als invoer een lijst en als uitvoer een gesorteerde lijst. Je gebruikt de functie mergesort later om de gegevens voor een boxplot te bepalen. Start het elm programma mergesort.elm. Vul in het vakje links boven het volgende in:

7,3,8,6,8,5,4,5,3,6,2,6,9,1,2,7,5,8,7,6

Als uitkomst zie je nu een gesorteerde lijst.

Start het elm programma mymergesort.elm dat je gekregen hebt. Elm geeft als foutmelding dat de functie mergesort ontbreekt. Dat klopt want dat is nu juist de functie die je zelf moet schrijven.

Voeg de functie mergesort toe aan mymergesort.elm. Op de site elm-lang.org vind je bij Examples een voorbeeld van een mergesort functie.

Je moet deze als volgt aanpassen:

  • Verander de naam van de functie split in divide

Bekijk ook de functies checkedStringToFloat en listStringToListFloat.

De functie checkedStringToFloat heeft als input een String en geeft als output een Float terug.  Als  de String niet omgezet kan worden geeft de functie 0 terug.

De functie listStringToListFloat heeft als input een List van Strings en geeft als output een List van Floats terug. Daarbij maakt de functie gebruik van de standaard elm functie map. Deze functie past een functie die als parameter meegegeven wordt toe op alle elementen in een als parameter meegegeven List. In dit geval is dit de functie checkedStringToFloat.

Maak boxplotdata

Je gaat een functie boxplotdata maken.  Deze functie boxplotdata heeft als invoer een String met getallen gescheiden door komma’s en als uitvoer  een List van Floats met getallen gescheiden door komma’s op basis waarvan je een boxplot kunt tekenen.  Je gebruikt de functie boxplotdata later om  een boxplot te tekenen.

Start het elm programma boxplotdata.elm. Vul in het vakje links boven het volgende in:

7,3,8,6,8,5,4,5,3,6,2,6,9,1,2,7,5,8,7,6

Als uitkomst zie je nu een lijst met de gegevens voor de boxplot. Hierin staan achtereenvolgens:

  • kleinste getal
  • eerste quartiel
  • tweede quartiel (mediaan)
  • derde quartiel
  • grootste getal

Start het elm programma myboxplotdata.elm dat je gekregen hebt. Elm geeft als foutmelding dat de functie boxplotdata ontbreekt. Dat klopt want dat is nu juist de functie die je zelf moet schrijven.

Voeg de functie boxplotdata  toe aan myboxplotdata.elm. Deze functie boxplotdata heeft als invoer een String en als uitvoer een  lijst van Floats op basis waarvan je een boxplot kunt tekenen. In deze lijst staan achtereenvolgens het kleinste getal, het eerste kwartiel, het tweede kwartiel(mediaan), het derde kwartiel en het grootste getal.

Je kunt dit als volgt aanpakken.  Maak met split een lijst van de String die je als invoer krijgt. Zet deze lijst van Strings om naar een lijst van Floats en sorteer deze lijst. Maak van deze lijst een Array. Je kunt nu op basis van dit Array de kleinste een de grootste bepalen. Schrijf aparte functies om op basis van het Array het eerste, tweede en derde kwartiel te bepalen.  Zet de resultaten in een lijst van Floats en geef deze terug.

Maak boxplotdatadraw

Kopieer je bestand myboxplotdata.elm naar myboxplotdatadraw.elm.

Voeg  bovenaan in myboxplotdatadraw.elm het volgende toe:

 

import Svg exposing (..)

import Svg.Attributes exposing (..)

 

Vervang in boxplotdatadraw.elm:

 

view model =

  div []

  [ input [onKeyDown KeyDown, onInput Input] []

  , div [] [ text (toString model.outputData) ]

  ]

 

door:

 

view model =

  let

  a  = Array.fromList model.outputData

  kl = withDefault 0 (Array.get 0 a)

  k1 = withDefault 0 (Array.get 1 a)

  k2 = withDefault 0 (Array.get 2 a)

  k3 = withDefault 0 (Array.get 3 a)

  gr = withDefault 0 (Array.get 4 a)

  s = 200/(gr-kl)

  h = 12

  line1 = pointsListToString [kl*s, 100, k1*s, 100]

  box1 = pointsListToString [k1*s, 100-(s*((gr-kl)/h)), k2*s, 100-(s*((gr-kl)/h)), k2*s, 100+(s*((gr-kl)/h)), k1*s, 100+(s*((gr-kl)/h)), k1*s, 100-(s*((gr-kl)/h))]

  box2 = pointsListToString [k2*s, 100-(s*((gr-kl)/h)), k3*s, 100-(s*((gr-kl)/h)), k3*s, 100+(s*((gr-kl)/h)), k2*s, 100+(s*((gr-kl)/h)), k2*s, 100-(s*((gr-kl)/h))]

  line2 = pointsListToString [k3*s, 100, gr*s , 100]

  in

  div []

  [ input [onKeyDown KeyDown, onInput Input] []

  , div [] [ Html.text ("kl: " ++ toString kl) ]

  , div [] [ Html.text ("q1: " ++ toString k1) ]

  , div [] [ Html.text ("q2: " ++ toString k2) ]

  , div [] [ Html.text ("q3: " ++ toString k3) ]

  , div [] [ Html.text ("gr: " ++ toString gr) ]

  , svg [ viewBox "0 0 500 400", width "800px" ]

     [

       polyline [ fill "none", stroke "black", points line1 ] [],

       polyline [ fill "none", stroke "black", points box1 ] [],

       polyline [ fill "none", stroke "black", points box2 ] [],

       polyline [ fill "none", stroke "black", points line2 ] []

     ]

  ]

Uitleg

De gegevens voor de boxplot staan in model. outputData. Deze gegevens worden hier uit gehaald en in de volgende Floats gezet:

  • kl, kleinste
  • k1, eerste quartiel
  • k2, tweede quartiel
  • k3, derde quartiel
  • gr, grootste

Deze Floats worden gebruikt om binnen een svg tag de volgende polylines aan te maken:

  • line1
  • box1
  • box2
  • line2

 

Zie https://www.w3schools.com/graphics/svg_polyline.asp als je meer over svg en polyline wilt weten.