youplot 0.3.3 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f74b6c3834757ab941924f8455f0b933af654796740e80b85da400e764e14ae
4
- data.tar.gz: 6c77e305eb5e7361be28beca3cce569458832099f47a38efa61dbfd143e6a04b
3
+ metadata.gz: 04d898a5d15b1a38a92bf3823b6c1a971d17acf6000740867c09f35fa78a2a06
4
+ data.tar.gz: 9c5353687b33c75e953458fc824b1fa7386f980fbd9b11994f94bb8f06e6a387
5
5
  SHA512:
6
- metadata.gz: 31f0a7ef9942ab7d6017ce60669ff1ca3f4ddc5b9a61ca0dd83e5c35093d8aaed725ef945bea0c9f2390fe97b2519319fc32894247d6caa136734b192e6a2287
7
- data.tar.gz: 854f725384dfb6eb27c86ced3bb53321a850a015c343fdaf7e1639de96b01e8199557fd7beedf765126f74475c2506c938d2f26aa753c1f3abd5aca148dc48c7
6
+ metadata.gz: 5677d91bdd78e7de332557434fe377d316e302abb7476ee99fef0fab3dee03a40c702c10d7e1b70cc1cb22e8c5049236408849cc3f208c8372c70ce2dcb251d6
7
+ data.tar.gz: a5948c77d03ec831357c9774e8ef3346b7684944b606b5598620e4723fd233160af6a32377436d1ef4271655cbd3078572cb5f88c14de4ddd63043778dc99c00
data/README.md CHANGED
@@ -1,16 +1,19 @@
1
- <p align="center">
2
- <img src="https://user-images.githubusercontent.com/5798442/103439598-9e952a00-4c81-11eb-881f-67c593bb7861.png" width="75%" height="75%" />
3
- </p>
4
-
5
- ![Build Status](https://github.com/kojix2/youplot/workflows/test/badge.svg)
6
- [![Gem Version](https://badge.fury.io/rb/youplot.svg)](https://badge.fury.io/rb/youplot)
7
- [![Docs Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://rubydoc.info/gems/youplot)
8
- [![The MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
9
- [![DOI](https://zenodo.org/badge/283230219.svg)](https://zenodo.org/badge/latestdoi/283230219)
10
-
11
- YouPlot is a command line tool for Unicode Plotting working with data from standard stream.
12
-
13
- :bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
1
+ <div align="center">
2
+ <img src="logo.svg" width="66%" height="66%" />
3
+
4
+ <hr>
5
+
6
+ ![Build Status](https://github.com/red-data-tools/YouPlot/workflows/test/badge.svg)
7
+ [![Gem Version](https://badge.fury.io/rb/youplot.svg)](https://badge.fury.io/rb/youplot)
8
+ [![Docs Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://rubydoc.info/gems/youplot)
9
+ [![The MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
10
+ [![DOI](https://zenodo.org/badge/283230219.svg)](https://zenodo.org/badge/latestdoi/283230219)
11
+
12
+ YouPlot is a command line tool that draws plots in a terminal.
13
+
14
+ :bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
15
+
16
+ </div>
14
17
 
15
18
  ## Installation
16
19
 
@@ -106,8 +109,8 @@ In this example, YouPlot counts the number of chromosomes where the gene is loca
106
109
 
107
110
  ```sh
108
111
  cat gencode.v35.annotation.gff3 \
109
- | grep -v '#' | grep 'gene' | cut -f1 | \
110
- uplot count -t "The number of human gene annotations per chromosome" -c blue
112
+ | grep -v '#' | grep 'gene' | cut -f1 \
113
+ | uplot count -t "The number of human gene annotations per chromosome" -c blue
111
114
  ```
112
115
 
113
116
  <p align="center">
@@ -119,7 +122,7 @@ This is fine in most cases, as long as the data size is small. If you want to vi
119
122
 
120
123
  ```sh
121
124
  cat gencode.v35.annotation.gff3 | grep -v '#' | grep 'gene' | cut -f1 \
122
- |sort | uniq -c | sort -nrk2 | awk '{print $2,$1}' \
125
+ | sort | uniq -c | sort -nrk2 | awk '{print $2,$1}' \
123
126
  | uplot bar -d ' ' -t "The number of human gene annotations per chromosome" -c blue
124
127
  ```
125
128
 
@@ -130,15 +133,15 @@ cat gencode.v35.annotation.gff3 | grep -v '#' | grep 'gene' | cut -f1 \
130
133
  Wouldn't it be a pain to have to run R, Python, Julia, gnuplot or whatever REPL just to check your data?
131
134
  YouPlot is a command line tool for this purpose. With YouPlot, you can continue working without leaving your terminal and shell.
132
135
 
133
- ### how to use YouPlot?
136
+ ### How to use YouPlot?
134
137
 
135
138
  `uplot` is the shortened form of `youplot`. You can use either.
136
139
 
137
- | | |
138
- |-----------------------------------|------------------------------------------------|
139
- | Reads data from standard input | `cat data.tsv \| uplot <command> [options]` |
140
- | Reads data from files | `uplot <command> [options] data.tsv ...` |
141
- | Outputs data from stdin to stdout | `pipeline1 \| uplot <command> -O \| pipeline2` |
140
+ | Command | Description |
141
+ |------------------------------------------------|-----------------------------------|
142
+ | `cat data.tsv \| uplot <command> [options]` | Take input from stdin |
143
+ | `uplot <command> [options] data.tsv ...` | Take input from files |
144
+ | `pipeline1 \| uplot <command> -O \| pipeline2` | Outputs data from stdin to stdout |
142
145
 
143
146
  ### Where to output the plot?
144
147
 
@@ -148,7 +151,8 @@ The output file or stream for the plot can be specified with the `-o` option.
148
151
  ### Where to output the input data?
149
152
 
150
153
  By default, the input data is not shown anywhere.
151
- The `-O` option, with no arguments, outputs the input data directly to the standard output. This is useful when passing data to a subsequent pipeline.
154
+ The `-O` option, with no arguments, outputs the input data directly to the standard output.
155
+ This is useful when passing data to a subsequent pipeline.
152
156
 
153
157
  ### What types of plots are available?
154
158
 
@@ -176,11 +180,21 @@ If your input data contains a header line, you need to specify the `-H` option.
176
180
 
177
181
  ### How to specify the delimiter?
178
182
 
179
- Use the `-d` option. To specify a blank space, you can use `uplot bar -d ' ' data.txt`. You do not need to use `-d` option for tab-delimited text since the default value is tab.
183
+ Use the `-d` option. To specify a blank space, you can use `uplot bar -d ' ' data.txt`.
184
+ You do not need to use `-d` option for tab-delimited text since the default value is tab.
180
185
 
181
186
  ### Is there a way to specify a column as the x-axis or y-axis?
182
187
 
183
- Not yet. In principle, YouPlot treats the first column as the X axis and the second column as the Y axis. When working with multiple series, the first row is the X axis, the second row is series 1, the third row is series 2, and so on. If you pass only one column of data for `line` and `bar`, YouPlot will automatically use a sequential number starting from 1 as the X-axis. The `--fmt xyy`, `--fmt xyxy` and `--fmt yx` options give you a few more choices. See `youplot <command> --help` for more details. YouPlot has limited functionalities, but you can use shell scripts such as `awk '{print $2, $1}'` to swap lines.
188
+ Not yet.
189
+ YouPlot treats the first column as the X axis and the second column as the Y axis.
190
+ When working with multiple series, the first column is the X axis, the second column is series Y1, the third column is series Y2, and so on.
191
+ If you pass only one column of data for `line` and `bar`, YouPlot will automatically use a sequential number starting from 1 as the X-axis.
192
+
193
+ * `--fmt xyy` `--fmt xyxy` `--fmt yx` options give you a few more choices.
194
+ See `youplot <command> --help` for more details.
195
+
196
+ * Use `awk '{print $2, $1}'` to swap lines.
197
+ * Use `paste` to concatenate series.
184
198
 
185
199
  ### How to plot real-time data?
186
200
 
@@ -201,7 +215,7 @@ Usage: uplot histogram [options] <in.tsv>
201
215
 
202
216
  Options for histogram:
203
217
  --symbol VAL character to be used to plot the bars
204
- --closed VAL
218
+ --closed VAL side of the intervals to be closed [left]
205
219
  -n, --nbins VAL approximate number of bins
206
220
 
207
221
  Options:
@@ -216,23 +230,31 @@ uplot colors
216
230
 
217
231
  ## Contributing
218
232
 
219
- * [Report bugs](https://github.com/kojix2/youplot/issues)
220
- * Fix bugs and [submit pull requests](https://github.com/kojix2/youplot/pulls)
233
+ YouPlot is a library under development, so even small improvements like typofix are welcome!
234
+ Please feel free to send us your pull requests.
235
+
236
+ * [Report bugs](https://github.com/red-data-tools/YouPlot/issues)
237
+ * Fix bugs and [submit pull requests](https://github.com/red-data-tools/YouPlot/pulls)
221
238
  * Write, clarify, or fix documentation
222
239
  * English corrections by native speakers are welcome.
223
240
  * Suggest or add new features
224
-
241
+ * Make a donation
225
242
 
226
243
  ### Development
227
244
 
228
245
  ```sh
229
- git clone https://github.com/your_name/GR.rb # Clone the Git repo
230
- cd GR.rb
246
+ # fork the main repository by clicking the Fork button.
247
+ git clone https://github.com/your_name/YouPlot
231
248
  bundle install # Install the gem dependencies
232
249
  bundle exec rake test # Run the test
233
250
  bundle exec rake install # Installation from source code
234
251
  ```
235
252
 
253
+ ### Acknowledgements
254
+
255
+ * [sampo grafiikka](https://jypg.net/sampo_grafiikka) - Project logo creation
256
+ * [yutaas](https://github.com/yutaas) - English proofreading
257
+
236
258
  ## License
237
259
 
238
260
  [MIT License](https://opensource.org/licenses/MIT).
data/exe/uplot CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require 'youplot'
5
5
 
6
- YouPlot::Command.new.run
6
+ YouPlot::Command.new.run_as_executable
data/exe/youplot CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require 'youplot'
5
5
 
6
- YouPlot::Command.new.run
6
+ YouPlot::Command.new.run_as_executable
data/lib/youplot.rb CHANGED
@@ -1,9 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'unicode_plot'
4
- require 'youplot/version'
5
- require 'youplot/dsv'
6
- require 'youplot/command'
3
+ require_relative 'youplot/version'
4
+ require_relative 'youplot/dsv'
5
+ require_relative 'youplot/parameters'
6
+ require_relative 'youplot/command'
7
7
 
8
8
  module YouPlot
9
+ class << self
10
+ attr_accessor :run_as_executable
11
+
12
+ def run_as_executable?
13
+ @run_as_executable
14
+ end
15
+ end
16
+ @run_as_executable = false
9
17
  end
@@ -6,18 +6,30 @@ module YouPlot
6
6
  module Processing
7
7
  module_function
8
8
 
9
- def count_values(arr)
9
+ def count_values(arr, tally: true, reverse: false)
10
10
  # tally was added in Ruby 2.7
11
- if Enumerable.method_defined? :tally
12
- arr.tally
13
- else
14
- # https://github.com/marcandre/backports
15
- arr.each_with_object(Hash.new(0)) { |item, res| res[item] += 1 }
16
- .tap { |h| h.default = nil }
11
+ result = \
12
+ if tally && Enumerable.method_defined?(:tally)
13
+ arr.tally
14
+ else
15
+ # value_counts Enumerable::Statistics
16
+ arr.value_counts(dropna: false)
17
+ end
18
+
19
+ # sorting
20
+ result = result.sort do |a, b|
21
+ # compare values
22
+ r = b[1] <=> a[1]
23
+ # If the values are the same, compare by name
24
+ r = a[0] <=> b[0] if r.zero?
25
+ r
17
26
  end
18
- .sort { |a, b| a[1] <=> b[1] }
19
- .reverse
20
- .transpose
27
+
28
+ # --reverse option
29
+ result.reverse! if reverse
30
+
31
+ # prepare for barplot
32
+ result.transpose
21
33
  end
22
34
  end
23
35
  end
@@ -1,20 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # UnicodePlot - Plot your data by Unicode characters
4
+ # https://github.com/red-data-tools/unicode_plot.rb
5
+
3
6
  require_relative 'processing'
4
7
  require 'unicode_plot'
5
8
 
6
9
  module YouPlot
7
10
  # plotting functions.
8
11
  module Backends
9
- module UnicodePlotBackend
12
+ module UnicodePlot
13
+ class Error < StandardError; end
14
+
10
15
  module_function
11
16
 
12
- def barplot(data, params, fmt = nil, count: false)
17
+ def barplot(data, params, fmt = nil, count: false, reverse: false)
13
18
  headers = data.headers
14
19
  series = data.series
15
20
  # `uplot count`
16
21
  if count
17
- series = Processing.count_values(series[0])
22
+ series = Processing.count_values(series[0], reverse: reverse)
18
23
  params.title = headers[0] if headers
19
24
  end
20
25
  if series.size == 1
@@ -37,7 +42,7 @@ module YouPlot
37
42
  labels = series[x_col]
38
43
  values = series[y_col].map(&:to_f)
39
44
  end
40
- UnicodePlot.barplot(labels, values, **params.to_hc)
45
+ ::UnicodePlot.barplot(labels, values, **params.to_hc)
41
46
  end
42
47
 
43
48
  def histogram(data, params)
@@ -45,7 +50,7 @@ module YouPlot
45
50
  series = data.series
46
51
  params.title ||= data.headers[0] if headers
47
52
  values = series[0].map(&:to_f)
48
- UnicodePlot.histogram(values, **params.to_hc)
53
+ ::UnicodePlot.histogram(values, **params.to_hc)
49
54
  end
50
55
 
51
56
  def line(data, params, fmt = nil)
@@ -55,7 +60,7 @@ module YouPlot
55
60
  # If there is only one series, it is assumed to be sequential data.
56
61
  params.ylabel ||= headers[0] if headers
57
62
  y = series[0].map(&:to_f)
58
- UnicodePlot.lineplot(y, **params.to_hc)
63
+ ::UnicodePlot.lineplot(y, **params.to_hc)
59
64
  else
60
65
  # If there are 2 or more series...
61
66
  if fmt == 'yx'
@@ -73,7 +78,7 @@ module YouPlot
73
78
  end
74
79
  x = series[x_col].map(&:to_f)
75
80
  y = series[y_col].map(&:to_f)
76
- UnicodePlot.lineplot(x, y, **params.to_hc)
81
+ ::UnicodePlot.lineplot(x, y, **params.to_hc)
77
82
  end
78
83
  end
79
84
 
@@ -90,10 +95,11 @@ module YouPlot
90
95
  params.name ||= headers[1]
91
96
  params.xlabel ||= headers[0]
92
97
  end
98
+ params.xlim ||= series[0].flatten.minmax # why need?
93
99
  params.ylim ||= series[1..-1].flatten.minmax # why need?
94
- plot = UnicodePlot.public_send(method1, series[0], series[1], **params.to_hc)
100
+ plot = ::UnicodePlot.public_send(method1, series[0], series[1], **params.to_hc)
95
101
  2.upto(series.size - 1) do |i|
96
- UnicodePlot.public_send(method2, plot, series[0], series[i], name: headers&.[](i))
102
+ ::UnicodePlot.public_send(method2, plot, series[0], series[i], name: headers&.[](i))
97
103
  end
98
104
  plot
99
105
  end
@@ -103,14 +109,15 @@ module YouPlot
103
109
  series = data.series
104
110
  method2 = get_method2(method1)
105
111
  series.map! { |s| s.map(&:to_f) }
106
- series = series.each_slice(2).to_a
112
+ series2 = series.each_slice(2).to_a
113
+ series = nil
107
114
  params.name ||= headers[0] if headers
108
- params.xlim = series.map(&:first).flatten.minmax # why need?
109
- params.ylim = series.map(&:last).flatten.minmax # why need?
110
- x1, y1 = series.shift
111
- plot = UnicodePlot.public_send(method1, x1, y1, **params.to_hc)
112
- series.each_with_index do |(xi, yi), i|
113
- UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
115
+ params.xlim ||= series2.map(&:first).flatten.minmax # why need?
116
+ params.ylim ||= series2.map(&:last).flatten.minmax # why need?
117
+ x1, y1 = series2.shift
118
+ plot = ::UnicodePlot.public_send(method1, x1, y1, **params.to_hc)
119
+ series2.each_with_index do |(xi, yi), i|
120
+ ::UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
114
121
  end
115
122
  plot
116
123
  end
@@ -148,13 +155,13 @@ module YouPlot
148
155
  series = data.series
149
156
  headers ||= (1..series.size).map(&:to_s)
150
157
  series.map! { |s| s.map(&:to_f) }
151
- UnicodePlot.boxplot(headers, series, **params.to_hc)
158
+ ::UnicodePlot.boxplot(headers, series, **params.to_hc)
152
159
  end
153
160
 
154
161
  def colors(color_names = false)
155
162
  # FIXME
156
163
  s = String.new
157
- UnicodePlot::StyledPrinter::TEXT_COLORS.each do |k, v|
164
+ ::UnicodePlot::StyledPrinter::TEXT_COLORS.each do |k, v|
158
165
  s << v
159
166
  s << k.to_s
160
167
  unless color_names
@@ -174,19 +181,25 @@ module YouPlot
174
181
  def check_series_size(data, fmt)
175
182
  series = data.series
176
183
  if series.size == 1
177
- warn 'youplot: There is only one series of input data. Please check the delimiter.'
178
- warn ''
179
- warn " Headers: \e[35m#{data.headers.inspect}\e[0m"
180
- warn " The first item is: \e[35m\"#{series[0][0]}\"\e[0m"
181
- warn " The last item is : \e[35m\"#{series[0][-1]}\"\e[0m"
182
- exit 1
184
+ warn <<~EOS
185
+ youplot: There is only one series of input data. Please check the delimiter.
186
+
187
+ Headers: \e[35m#{data.headers.inspect}\e[0m
188
+ The first item is: \e[35m\"#{series[0][0]}\"\e[0m
189
+ The last item is : \e[35m\"#{series[0][-1]}\"\e[0m
190
+ EOS
191
+ # NOTE: Error messages cannot be colored.
192
+ YouPlot.run_as_executable ? exit(1) : raise(Error)
183
193
  end
184
194
  if fmt == 'xyxy' && series.size.odd?
185
- warn 'YouPlot: In the xyxy format, the number of series must be even.'
186
- warn ''
187
- warn " Number of series: \e[35m#{series.size}\e[0m"
188
- warn " Headers: \e[35m#{data.headers.inspect}\e[0m"
189
- exit 1
195
+ warn <<~EOS
196
+ YouPlot: In the xyxy format, the number of series must be even.
197
+
198
+ Number of series: \e[35m#{series.size}\e[0m
199
+ Headers: \e[35m#{data.headers.inspect}\e[0m
200
+ EOS
201
+ # NOTE: Error messages cannot be colored.
202
+ YouPlot.run_as_executable ? exit(1) : raise(Error)
190
203
  end
191
204
  end
192
205
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'dsv'
4
- require_relative 'command/parser'
4
+ require_relative 'parser'
5
5
 
6
6
  # FIXME
7
- require_relative 'backends/unicode_plot_backend'
7
+ require_relative 'backends/unicode_plot'
8
8
 
9
9
  module YouPlot
10
10
  Data = Struct.new(:headers, :series)
@@ -19,7 +19,12 @@ module YouPlot
19
19
  @command = nil
20
20
  @params = nil
21
21
  @options = nil
22
- @backend = YouPlot::Backends::UnicodePlotBackend
22
+ @backend = YouPlot::Backends::UnicodePlot
23
+ end
24
+
25
+ def run_as_executable
26
+ YouPlot.run_as_executable = true
27
+ run
23
28
  end
24
29
 
25
30
  def run
@@ -28,17 +33,34 @@ module YouPlot
28
33
  @options ||= parser.options
29
34
  @params ||= parser.params
30
35
 
36
+ # color command
31
37
  if %i[colors color colours colour].include? @command
32
38
  plot = create_plot
33
39
  output_plot(plot)
34
- elsif options[:progressive]
40
+ return
41
+ end
42
+
43
+ # progressive mode
44
+ if options[:progressive]
35
45
  stop = false
36
46
  Signal.trap(:INT) { stop = true }
47
+
48
+ # make cursor invisible
49
+ options[:output].print "\e[?25l"
50
+
51
+ # mainloop
37
52
  while (input = Kernel.gets)
38
- main_progressive(input)
53
+ n = main_progressive(input)
39
54
  break if stop
55
+
56
+ options[:output].print "\e[#{n}F"
40
57
  end
58
+
41
59
  options[:output].print "\e[0J"
60
+ # make cursor visible
61
+ options[:output].print "\e[?25h"
62
+
63
+ # normal mode
42
64
  else
43
65
  # Sometimes the input file does not end with a newline code.
44
66
  while (input = Kernel.gets(nil))
@@ -50,13 +72,32 @@ module YouPlot
50
72
  private
51
73
 
52
74
  def main(input)
75
+ # Outputs input data to a file or stdout.
53
76
  output_data(input)
54
77
 
55
- @data = read_dsv(input)
78
+ @data = parse_dsv(input)
56
79
 
80
+ # Debug mode, show parsed results
57
81
  pp @data if options[:debug]
58
82
 
59
- plot = create_plot
83
+ # When run as a program instead of a library
84
+ if YouPlot.run_as_executable?
85
+ begin
86
+ plot = create_plot
87
+ rescue ArgumentError => e
88
+ # Show only one line of error.
89
+ warn e.backtrace[0]
90
+ # Show error message in purple
91
+ warn "\e[35m#{e}\e[0m"
92
+ # Explicitly terminated with exit code: 1
93
+ exit 1
94
+ end
95
+
96
+ # When running YouPlot as a library (e.g. for testing)
97
+ else
98
+ plot = create_plot
99
+ end
100
+
60
101
  output_plot(plot)
61
102
  end
62
103
 
@@ -76,15 +117,28 @@ module YouPlot
76
117
  @raw_data << input
77
118
 
78
119
  # FIXME
79
- @data = read_dsv(@raw_data)
120
+ @data = parse_dsv(@raw_data)
80
121
 
81
122
  plot = create_plot
82
123
  output_plot_progressive(plot)
83
124
  end
84
125
 
85
- def read_dsv(input)
86
- input = input.dup.force_encoding(options[:encoding]).encode('utf-8') if options[:encoding]
87
- DSV.parse(input, options[:delimiter], options[:headers], options[:transpose])
126
+ def parse_dsv(input)
127
+ # If encoding is specified, convert to UTF-8
128
+ if options[:encoding]
129
+ input.force_encoding(options[:encoding])
130
+ .encode!('utf-8')
131
+ end
132
+
133
+ begin
134
+ data = DSV.parse(input, options[:delimiter], options[:headers], options[:transpose])
135
+ rescue CSV::MalformedCSVError => e
136
+ warn 'Failed to parse the text. '
137
+ warn 'Please try to set the correct character encoding with --encoding option.'
138
+ raise e
139
+ end
140
+
141
+ data
88
142
  end
89
143
 
90
144
  def create_plot
@@ -92,7 +146,7 @@ module YouPlot
92
146
  when :bar, :barplot
93
147
  @backend.barplot(data, params, options[:fmt])
94
148
  when :count, :c
95
- @backend.barplot(data, params, count: true)
149
+ @backend.barplot(data, params, count: true, reverse: options[:reverse])
96
150
  when :hist, :histogram
97
151
  @backend.histogram(data, params)
98
152
  when :line, :lineplot
@@ -128,9 +182,9 @@ module YouPlot
128
182
 
129
183
  def output_plot(plot)
130
184
  case options[:output]
131
- when IO
185
+ when IO, StringIO
132
186
  plot.render(options[:output])
133
- else
187
+ when String, Tempfile
134
188
  File.open(options[:output], 'w') do |f|
135
189
  plot.render(f)
136
190
  end
@@ -139,7 +193,7 @@ module YouPlot
139
193
 
140
194
  def output_plot_progressive(plot)
141
195
  case options[:output]
142
- when IO
196
+ when IO, StringIO
143
197
  # RefactorMe
144
198
  out = StringIO.new(String.new)
145
199
  def out.tty?
@@ -154,8 +208,7 @@ module YouPlot
154
208
  end
155
209
  options[:output].print "\e[0J"
156
210
  options[:output].flush
157
- n = out.string.lines.size
158
- options[:output].print "\e[#{n}F"
211
+ out.string.lines.size
159
212
  else
160
213
  raise 'In progressive mode, output to a file is not possible.'
161
214
  end