Scalaでデータの可視化をしたいならWISPがいいかもよ


とりあえず引用からスタート

[WISP](https://github.com/quantifind/wisp): ![Qiita](https://camo.githubusercontent.com/181b4ce7b533ed86df811645bad742bcc8af7145/68747470733a2f2f7261772e6769746875622e636f6d2f7175616e746966696e642f776973702f6d61737465722f696d616765732f776973705f6c6f676f5f6d61726b4f6e6c795f636f6c6f722e706e67 "Qiita")

>Wisp : Wisp Is Scala Plotting is a console-centric plotting library for scala. It focuses on existing web-based plotting libraries, and strives to bring the power and flexibility of web-based plotting tools to the scala console, while preserving an at-your-finger-tips feel readily found in matlab, R, and many other languages.

以前までは[breeze-viz](https://github.com/scalanlp/breeze-viz)を使って可視化していましたが，WISPに乗り換えてみました．

Breezeの可視化はこんな感じ↓
![3周目12回目.png](https://qiita-image-store.s3.amazonaws.com/0/84299/890ee61e-bfd4-2cd3-62aa-8cf909e3c24d.png "3周目12回目.png")

WISPの可視化はこんな感じ↓
![Screenshot 2016-07-31 05.00.41.png](https://qiita-image-store.s3.amazonaws.com/0/84299/401940be-3c4e-2b5a-6245-7ba5b4de81a7.png "Screenshot 2016-07-31 05.00.41.png")

下の項目はクリックすると表示/非表示の切り替えが可能です．
詳しくは後述


## 環境
|項目|バージョン|
|:---:|:---:|
|sbt|0.14.0|
|scala|2.11.8|
|OS|OS X EI Capitan ver 10.11.6|

## 導入

```sbt:build.sbt
name := "WispSample"

version := "1.0"

scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.quantifind" %% "wisp" % "0.0.4"
)

```

最小限しか書いていないので適時必要なものを追加してください．
とりあえずこのサンプルはこの構成で動きます．

構成は以下

```
.
├── build.sbt
├── project
│   └── target
├── src
│   └── main
│       └── scala
│           └── Wisp.scala

```

```scala:/src/main/scala/Wisp.scala
import com.quantifind.charts.Highcharts._

object Wisp{

  def main(args:Array[String]){
    // ここにいろいろ追加していく
  }
}
```


## 使い方

まずはどんな図が書けるのか見てみます．

```
scala> help

Available Plot Types: Takes an Iterable, an Iterable of pairs, a pair of Iterables, or an Iterable and a Function

	area
	areaspline
	bar
	column
	line
	pie
	scatter
	spline
	regression
	
Other plotting options:

	histogram                          Iterable of Numerics or Pairs
```

[GitHubのWiki](https://github.com/quantifind/wisp/wiki/Highcharts)にて，`areaspline`，`pie`，`regression`，`histogram`，`bar`の使い方は画像付きで紹介されていてわかりやすいです．

なので，今回は紹介されていないものを中心に紹介したいと思います．

### Plot

#### コード
```scala:/src/main/scala/Wisp.scala
import com.quantifind.charts.Highcharts._

object Wisp{

  def main(args:Array[String]){
    //第1引数がx軸，第2引数がy軸
    area(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    column(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    line(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    scatter(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    spline(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
  }
}

```

```sbt run```するとブラウザが起動して図が作成される．

#### 図
area:
![Screenshot 2016-08-01 01.30.49.png](https://qiita-image-store.s3.amazonaws.com/0/84299/9b2e89bb-a849-9faa-bd52-27b087995926.png "Screenshot 2016-08-01 01.30.49.png")

column:![Screenshot 2016-08-01 01.40.10.png](https://qiita-image-store.s3.amazonaws.com/0/84299/4cb276af-96f4-cdc9-e990-cf1b85fde601.png "Screenshot 2016-08-01 01.40.10.png")

line:
![Screenshot 2016-08-01 01.40.50.png](https://qiita-image-store.s3.amazonaws.com/0/84299/8627d2a1-920c-fef3-7435-1a49456f223a.png "Screenshot 2016-08-01 01.40.50.png")

scatter:
![Screenshot 2016-08-01 01.41.16.png](https://qiita-image-store.s3.amazonaws.com/0/84299/cf8291e7-d6c4-2578-5d51-043943c89792.png "Screenshot 2016-08-01 01.41.16.png")

spline:
![Screenshot 2016-08-01 01.41.41.png](https://qiita-image-store.s3.amazonaws.com/0/84299/10602c63-37ed-9920-2807-cf6831cbafb7.png "Screenshot 2016-08-01 01.41.41.png")

説明のため，わけて載せましたが，ブラウザが起動した際に同じページに載っています．

引数で使用することが可能なのは

>an Iterable[Numeric]
an Iterable[(Numeric, Numeric)]
an (Iterable[Numeric], Iterable[Numeric])
an (Iterable[Numeric], Numeric => Numeric)
an (Numeric => Numeric, Iterable[Numeric])

だそうです

### Style調整を絡めて実践してみる
スタイルについてのオプションもいくつか用意されています．

```
Stylistic changes:

	hold                               plots the next plot on top of the existing plot
	unhold                             plots the next plot in a new chart
	title(String)                      add a title to the most recent plot
	xAxis(String)                      adds a label to the x-axis
	xAxisType([                        updates the x-axis type
	  "linear", "logarithmic",
	  "datetime", "category"
	])
	yAxis(String)                      adds a label to y-axis
	yAxisType([                        updates the y-axis type
	  "linear", "logarithmic",
	  "datetime", "category"
	])
	legend(Iterable[String])           adds a legend to the most recent plot
	stack(["normal", "percent"])       stacks bars, columns, and lines relative to each other
	unstack                            remove stacking
```

今回は先頭でのっけた図っぽいものを作ってみようと思います．
(計算とか一切しないでただ見た目だけ真似してみます．)

#### Step1 データをPlot

```scala:/src/main/scala/Wisp.scala
import com.quantifind.charts.Highcharts._

object Wisp{

  def main(args:Array[String]){
    //第1引数がx軸，第2引数がy軸
    // area(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // column(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // line(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // scatter(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // spline(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))

    //第1象限のデータ
    //第1象限のデータ
    val xFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    val yFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    scatter(xFirstQuadrant,yFirstQuadrant)

    //第3象限データ
    val xThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    val yThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    scatter(xThirdQuadrant,yThirdQuadrant)  
    }
}

```

このままPlotすると2つグラフができてしまって狙いどおりにいかない．
なので，どんどん上書きしたいときは`hold`を使う

```scala:/src/main/scala/Wisp.scala
import com.quantifind.charts.Highcharts._

object Wisp{

  def main(args:Array[String]){
    //第1引数がx軸，第2引数がy軸
    // area(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // column(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // line(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // scatter(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // spline(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))

    //第1象限のデータ
    //第1象限のデータ
    val xFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    val yFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    scatter(xFirstQuadrant,yFirstQuadrant)
    hold

    //第3象限データ
    val xThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    val yThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    scatter(xThirdQuadrant,yThirdQuadrant)  
    }
}

```

![Screenshot 2016-08-01 02.07.16.png](https://qiita-image-store.s3.amazonaws.com/0/84299/550b6a02-c658-ec0b-5c7b-30d8ed945735.png "Screenshot 2016-08-01 02.07.16.png")


#### Step2 境界線を引いてみる

```scala:/src/main/scala/Wisp.scala
import com.quantifind.charts.Highcharts._

object Wisp{

  def main(args:Array[String]){
    //第1引数がx軸，第2引数がy軸
    // area(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // column(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // line(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // scatter(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // spline(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))

    //第1象限のデータ
    //第1象限のデータ
    val xFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    val yFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    scatter(xFirstQuadrant,yFirstQuadrant)
    hold

    //第3象限データ
    val xThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    val yThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    scatter(xThirdQuadrant,yThirdQuadrant)  
    hold
    line((-1 to 1).map(x => x -> -x))
    }
}

```

mapを使うと引数は1つでも大丈夫です．

![Screenshot 2016-08-01 02.17.07.png](https://qiita-image-store.s3.amazonaws.com/0/84299/d73319a1-384f-e01e-cd19-921263ee326d.png "Screenshot 2016-08-01 02.17.07.png")

#### Step3 エイリアスを付ける

上記の図のままだと何が何を表しているのかわからないのでエイリアスをつけていきましょう

|スタイルオプション|説明|
|:---:|:---:|
|title|タイトル|
|xAxis|x軸のラベル|
|yAxis|y軸のラベル|
|legend|データのラベル|

となっています．

```scala:/src/main/scala/Wisp.scala
import com.quantifind.charts.Highcharts._

object Wisp{

  def main(args:Array[String]){
    //第1引数がx軸，第2引数がy軸
    // area(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // column(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // line(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // scatter(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))
    // spline(List(1, 2, 3, 4, 5), List(4, 1, 3, 2, 6))

    //第1象限のデータ
    //第1象限のデータ
    val xFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    val yFirstQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / 10.0}
    scatter(xFirstQuadrant,yFirstQuadrant)
    hold

    //第3象限データ
    val xThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    val yThirdQuadrant:List[Double] = List.fill(15)(Random.nextInt(10)).map{_ / -10.0}
    scatter(xThirdQuadrant,yThirdQuadrant)  
    hold
    line((-1 to 1).map(x => x -> -x))
    
    title("サンプルです")
    xAxis("x")
    yAxis("y")
    legend(List("Class1", "Class2", "境界線"))
    }
}

```
![Screenshot 2016-08-01 02.21.19.png](https://qiita-image-store.s3.amazonaws.com/0/84299/fc49102e-a944-8eef-2e9c-6809de85912b.png "Screenshot 2016-08-01 02.21.19.png")


これでそれっぽくなりましたね．

#### Step4: ブラウザでみてみる

![wispsample.gif](https://qiita-image-store.s3.amazonaws.com/0/84299/e9cc1e40-850f-ff5b-9e9b-f0007b1a5273.gif "wispsample.gif")


ブラウザでみると上の動画のように必要なものだけ表示したり，いろいろな形式でダウンロードすることができます．