Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rubyアソシエーション開発助成成果報告会

秒速284km
September 20, 2019

 Rubyアソシエーション開発助成成果報告会

Rubyアソシエーション開発助成成果報告会
https://rubyassociation.doorkeeper.jp/events/95710

秒速284km

September 20, 2019
Tweet

More Decks by 秒速284km

Other Decks in Programming

Transcript

  1. Ruby Association Grant 2018 Report Charty.new( "Visualizing your data in

    Ruby" ) |> Grant |> RubyKaigi |> Latest |> render @284km (Kazuma Furuhashi) Speee Inc.
  2. Revert "Add pipeline operator [Feature #15799]" · ruby/ruby@2ed68d0 Charty.new( "Visualizing

    your data in Ruby" ) |> Grant |> RubyKaigi |> Latest |> render 僕が発表タイトルを提出した頃の trunk では動いてた
  3. Ruby Association Grant 2018 Report Charty.new( "Visualizing your data in

    Ruby" ) |> Grant |> RubyKaigi |> Latest |> render Charty.new( "Visualizing your data in Ruby" ).Grant.RubyKaigi.Latest.render @284km (Kazuma Furuhashi) Speee Inc.
  4. About Charty Charty is a open-source Ruby library for visualizing

    your data in a simple way. For example, Charty outputs these graphs. We can easily plot using Charty
  5. The scope in Grant is as follows (1) Create a

    thin Ruby library that can use the GR framework as an independent backend. (2) Enable GR framework as backend from Charty (use SciRuby/rubyplot as the visualization layer) (3) Implements Collection Interface corresponding to Charty's Data Abstraction Layer. (4) Implement Daru Interface corresponding to Charty's Data Abstraction Layer. そして中間報告の時点で、以下 2 つの実装を余⼒があれば実施すると加えた (a) Support rubydown (https://github.com/sciruby-jp/rubydown) (b) Support ActiveRecord Interface
  6. Characteristics of Charty Charty has 2 abstract layer Data Abstraction

    Layer (abstract data structure) Plotting Abstraction Layer (abstract backend plotting libraries) (I will explain about it later)
  7. 開発を進めると、当初の⽬論⾒どおり⾏かないことも発⽣します GR フレームワークとそれを利⽤する Ruby 向け可視化ライブラリである rubyplot の開発 状況が 予想よりも進んでいなかった rubyplot

    の他に、Python の可視化ライブラリである matplotlib を pycall.rb を介して利 ⽤し、同時に複数の可視化ライブラリのバックエンドをサポートする事を⽬指すように⽅ 針転換した 中間報告までに Plotting Abstraction Layer の仕組みを⽤意することを⽬指していたが、 報告時には matplotlib と rubyplot の他に Gruff をバックエンドとしてサポートすること ができた
  8. e.g. Pyplot backend require 'charty' charty = Charty::Plotter.new(:pyplot) scatter =

    charty.scatter do iris.group_by(:label).groups.each do |label, index| records = iris.row[*index] series records[:petal_length].to_a, records[:petal_width].to_a, label: label[0] end xlabel "Petal Length" ylabel "Petal Width" end scatter.render('pyplot.png')
  9. Gruff backend example If we want to use another backend,

    difference is only one line. require 'charty' charty = Charty::Plotter.new(:gruff) scatter = charty.scatter do iris.group_by(:label).groups.each do |label, index| records = iris.row[*index] series records[:petal_length].to_a, records[:petal_width].to_a, label: label[0] end xlabel "Petal Length" ylabel "Petal Width" end scatter.render('gruff.png')
  10. about Plotting Abstraction Layer From the previous example, the difference

    is one line to change backend Here is one of the features of Charty We can easily switch backend libraries with almost the same code
  11. More about Plotting Abstraction Layer Currently supported backends is below

    pyplot gruff Rubyplot --- 最終報告時点 --- google-chart (@indigolain) bokeh (@kantarow) plotly (@kei-s) plotly.js chart.js JFreeChart (for JRuby)
  12. Plotting Abstraction Layer 実装時のポイント 出⼒可能なグラフの種類が⼀番多い Matplotlib をリファレンス実装として、その後他の ライブラリのサポートを増やしつつ Interface を考えるという⼿順で作業を進めた。

    サポートするグラフの種類により描画に必要なデータ構造が異なるため、より多くのグラ フ出⼒に対応した Interface を考えるにあたってはこの⼿順が有効であった。 当初、GR Framework を backend に持つ rubyplot が魅⼒的であり真っ先に実装を始めた が、それに続いて Matplotlib のサポートを考えると両ライブラリに対応すること、より 多くのグラフ(データ構造)に対応することを同時に考えることとなり難易度が⾼かった が、村⽥メンターの助⾔により順序を変えることで設計の難易度を下げることが出来た。
  13. about Data Abstraction Layer Charty supports these data structures (I

    will show a demo) daru numo/narray nmatrix ActiveRecord Array Hash --- 最終報告時点 --- benchmark_driver (Charty Adapter) DataSets Thus, Charty can respond to various data structures. That's because Charty::Table is abstracted.
  14. Data Abstraction Layer 実装時のポイント Charty がサポートするデータ構造は複数あるため、各データ構造から⼀度中間データ構 造に変換し、その中間データ構造と Plotting Abstraction Layer

    とのマッピング処理を⽤ 意することにより、新たなデータ構造をサポートしたい場合には中間データ構造にさえ対 応するコードを書けばよいという状態をまず作った。 その中間データ構造が Charty::Table (この後説明します) この点では Charty と思想の近い holoviews の Interface を参考にした。 機能の拡充と共に Charty::Table の役割は増えるため、ある程度複雑になる時点で対応す るデータ構造に応じた Adapter を⽤意することを予定している。(Grant の開発期間後に adapter の仕組みを実際に⽤意した)
  15. Charty::Table 村⽥メンターのメンター報告書 の説明が⾮常にわかりやすい 可視化をする対象となるデータは tidy data 形式 (または、整然データ形式) と呼ばれる表 形式にまとめられることが多い。

    Charty は、論理的に表として解釈可能な様々なデータ構造を Charty::Table クラスで包む ことで、データ構造の実装の詳細を可視化レイヤから隠すことを⽬指している。 本プロジェクトでは、このデータ構造の詳細を隠すためのデータ抽象化レイヤを開発する ために、holoviews を参考にし、Daru::DataFrame、Numo::NArray、ActiveRecord の 関係データを抽象化することに対応した。
  16. Feature summary of Charty Charty has two abstraction layers. Data

    Abstraction Layer Plotting Abstraction Layer. Thus we can use the data structures we need We can use output libraries we want to use. We can use them in any combination we need with almost no code rewrite. こちらが提出した最終報告書
  17. Grant 期間の開発 〜 RubyKaigi へと続くことができた Charty は特に、他⾔語の可視化ツールの調査や、インターフェイスを決めるために学習 が必要なことが多かったと感じている。 たとえば Grant

    に採択されず、中間報告、最終報告といった期限も無いまま Charty の開 発を進めていたら、作業はしただろうけれど、いつ形になっていたかというのが今考えて もわからない。ずっと事前準備をしていた恐れすらあると思う。 採択して頂き、その課程を経たことにより、RubyKaigi で話せるところまで、この期間で 開発を進めることができたという事実がある。 そして RubyKaigi で RubyData Workshop セッションを企画し、発表機会を提供してく れた村⽥メンターに感謝している。
  18. RubyKaigi での発表 Charty の紹介はもちろんだが、⼀緒に開発する仲間を増やすという⽬的にフォーカスし た。 現時点での知識不⾜は開発をしながら補うことができる点を伝えたかった。これは⾃分の 経験は事実なので伝えることができた。 Charty のできることをなるべくわかりやすく伝えることを意識した。 結果的に、RubyKaigi

    期間中に 5 ⼈の⽅から合計 5 つの PR が作られマージされた。これ はうれしい。 発表後声をかけてくれた⽅々とすぐに Hack space に移動して作業開始できたり、コード 懇親会で Charty テーブルを作って頂くことができた点などにとても助けられた。このよ うなサポートのお陰で開発が進んだ事実も広くしられてほしいとも思う。
  19. 名古屋Ruby会議02 〜 RubyConf Taiwan 〜 RubyConfTH Grant 期間の成果として Charty が動く形で⾒せられるようになったため、

    名古屋Ruby会議02, RubyConf Taiwan, RubyConfTH と海外の Ruby カンファレンスも含め登 壇する機会が得られた。 Charty をより多くの⽅に知ってもらう機会 海外のカンファレンスで登壇するという経験 台湾のコード懇親会でも Charty の開発に参加してくれる⼈が現れ、その PR はマージさ れた
  20. Now Charty with JRuby is working This impression became my

    motivation. So, I implemented JFreeChart backend. Thanks to Charles, development progressed.
  21. Charty with JRuby red-data-tools/charty-backends-jfreechart Please use JRubyist. This is not

    yet complete. If you have important use cases, I can write code. I'm grad to hear everyone's thoughts.
  22. Other cases For example, google-charts, bokeh, plotly These were implemented

    by a pull request that "I'd like to use Charty if this library is supported by the backend" If there is a real User and Real-world use case exists, it depends on the priority with other work, but consider support for a new backend
  23. benchmark_driver との連携 benchmark_driver は Grant 2017 のプロジェクトで、Ruby のスゴイベンチマークライブ ラリ 実は、この

    benchmark_driver の最終報告 には、benchmark_driver の活⽤例として、僕 が 2018年3⽉に沖縄Ruby会議で発表した時の資料が参照されている という程度に benchmark_driver ユーザとしてお世話になっているツール そこで、benchmark_driver の出⼒⽤の Charty プラグインというものを作りました 実質 Grant 2 年分の成果とも⾔えるのではないでしょうか!?
  24. This combination is also possible. Because Charty has Data Abstraction

    Layer to support various data structures. benchmark_driver plugin to render with Charty benchmark-driver/benchmark_driver-output-charty This combination is also possible. Because Charty has Data Abstraction Layer to support various data structures.
  25. RubyConfTH での発表から、k0kubun さんが box plot に対応したらよさそうと PR を送って くれて、ベンチマーク結果を箱ひげ図で出⼒する機能が最近加わりました。 https://github.com/benchmark-driver/benchmark_driver-output-charty/pull/3

    Grant での開発を経て発表機会が⽣まれ、発表をきっかけに開発がまた進むという良いループ が⽣まれていて、こういう感じにまた次に続くようにしたいなということを最近は考えるよう になりました。
  26. benchmark-driver outputs as below by default. $ gem install $

    benchmark-driver examples/parse.yaml Calculating ------------------------------------- csv 3.1.1 csv 3.0.1 unquoted 61.332 38.149 i/s - 100.000 times in 1.630461s 2.621311s quoted 30.558 17.023 i/s - 100.000 times in 3.272469s 5.874313s mixed 40.932 23.047 i/s - 100.000 times in 2.443082s 4.339030s include_col_sep 11.167 10.657 i/s - 100.000 times in 8.955275s 9.383878s include_row_sep 11.180 4.339 i/s - 100.000 times in 8.944608s 23.044523s encode_utf-8 39.129 31.525 i/s - 100.000 times in 2.555671s 3.172112s encode_sjis 49.982 31.289 i/s - 100.000 times in 2.000736s 3.196026s Comparison: unquoted csv 3.1.1: 61.3 i/s csv 3.0.1: 38.1 i/s - 1.61x slower quoted csv 3.1.1: 30.6 i/s csv 3.0.1: 17.0 i/s - 1.80x slower mixed csv 3.1.1: 40.9 i/s csv 3.0.1: 23.0 i/s - 1.78x slower include_col_sep csv 3.1.1: 11.2 i/s csv 3.0.1: 10.7 i/s - 1.05x slower include_row_sep csv 3.1.1: 11.2 i/s csv 3.0.1: 4.3 i/s - 2.58x slower encode_utf-8 csv 3.1.1: 39.1 i/s csv 3.0.1: 31.5 i/s - 1.24x slower encode_sjis csv 3.1.1: 50.0 i/s csv 3.0.1: 31.3 i/s - 1.60x slower
  27. Speee という会社で働いているのですが、あるサービスの production 環境でも Charty が動いています。(production で使われるというのもまた嬉しい成果です) Recently, we introduced

    Charty in our production environment of Web Application, which is our job. This Web Application is a common Rails Application. At that time, we were asking for Charty to output json, not image file. Here is an example using plotly.js (I will show a demo)
  28. Code # controller plotlyjs = Charty::Plotter.new(:plotlyjs) plotlyjs.table = DataModel.where(foo: bar)

    json_data = plotlyjs.to_json layout_data = plotlyjs.layout # view <div id="sample"></div> # javascript import * as Plotly from 'plotly.js-dist'; Plotly.newPlot("sample", json_data, layout_data);
  29. Future plan (we aim for these) Improvement interface (Continued) Support

    red-arrow for Data Abstraction Layer because Apache Arrow is great. Release stable version Add supported dataset (red-datasets) (e.g. titanic) 発表を聞いた⼈が、より興味を持ちやすくなるようなデータで説明できるように 開発者を増やしたいから Support Unicode Plot Sixel support
  30. Acknowledgement Ruby Association Grant Various opportunities My motivation @mrkn Great

    mentor Drawing a Charty concept @kou Various implementation advice Red Data Tools org and all members All your support Speee, Inc Gave me a lot of time and support