charty
charty copied to clipboard
Stop instance_eval in RenderContext
The following code doesn't work with the current instance_eval
based implementation.
require "charty"
class MyApp
def initialize
@dataset = [
[[1, 2, 3], [4, 2, 1]],
[[1, 2, 3], [1, 5, 8]],
]
end
def run
plotter = Charty::Plotter.new(:google_chart)
figure = plotter.curve do
@dataset.each do |data|
series data[0], data[1]
end
end
puts figure.render
end
end
MyApp.new.run
Because @dataset.each do
is evaluated in RenderContext
. It should be evaluated in MyApp
context.
I'm designing the new plotting API.
One of the candidates is following holoviews' overlay system, which uses *
operator to overlay two or more plots. In this API, the above example can be written in the code below.
figure = @datasets.map {|data| Charty.line_plot(data[0], data[1]) }.inject(:*)
figure.render
Or, the other candidate is following matplotlib's convention, which reuses the axes object.
figure = @datasets.inject(nil) do |figure, data|
Charty.line_plot(data[0], data[1], figure: figure)
end
figure.render
This can be written in a more procedural programming style.
figure = nil
@datasets.each do |data|
figure = Charty.line_plot(data[0], data[1], figure: figure)
end
figure.render
Moreover, I think we should support plotting by tidy table data like seaborn.
table = {
x: @dataset.map(&:first).flatten,
y: @dataset.map(&:last).flatten,
row: @dataset.map.with_index {|row, i| [i] * row[0].length }.flatten
}
figure = Charty.line_plot(:x, :y, color: :row, data: table)
@kou, which do you like?