matplotlib 0.1.0.alpha.20170311 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 95a6ad2151fb6e66094399b36f7cc6786fcbd67a
4
- data.tar.gz: c9c0b297ad01c6fe1f773ea2ce831731ba4c35c4
2
+ SHA256:
3
+ metadata.gz: 16136e1e95a540d319e3bad7168e37ee5d6207ce8cdd029becc8586cdb696873
4
+ data.tar.gz: d9d5286651db26478890d6e33673b2740fb600a7f9f92190502914438486138e
5
5
  SHA512:
6
- metadata.gz: 14640bf62fe74e99d65fac51e9fed03f7cbebb5468c378c30796c8d9acfc8747cd65388e22e1275709788ce3123609b4012e8df187490a4bfc183323b4437381
7
- data.tar.gz: 1a8f6630b4bc2da2aa857225377d562d481cdc87408b666894f61e1e3eaf2b12b51d160f6497430ac4fad2e7b3c2cfe7db3f8feda46d7ff7d7101b5768500a55
6
+ metadata.gz: bf5e6af1f4683a8f547b2371779bbb9e5441f05f8a4cca3b2e5c7f16a628fa1a92e204038125bdf700bf7e922181590a357732140ca9623d30a09885f2efa345
7
+ data.tar.gz: 9f07a63560098806d0c570915daa39bde833713be2568d0bbee79fcd4cd93fa43d8670fc1386ec5b2f03471027c674efecb66cfebe26307f1e108fbe5d6508b1
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in matplotlib.gemspec
4
4
  gemspec
5
-
6
- gem 'pycall', github: 'mrkn/pycall'
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Matplotlib
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/matplotlib`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ This library enables to directly call [matplotlib](https://matplotlib.org/) from Ruby language.
4
+ This is built on top of [pycall](https://github.com/mrkn/pycall).
6
5
 
7
6
  ## Installation
8
7
 
@@ -18,11 +17,35 @@ And then execute:
18
17
 
19
18
  Or install it yourself as:
20
19
 
21
- $ gem install matplotlib
20
+ $ gem install --pre matplotlib
22
21
 
23
22
  ## Usage
24
23
 
25
- TODO: Write usage instructions here
24
+ ### Using pyplot in irb console or standalone scripts
25
+
26
+ Example usage:
27
+
28
+ require 'matplotlib/pyplot'
29
+ plt = Matplotlib::Pyplot
30
+
31
+ xs = [*1..100].map {|x| (x - 50) * Math::PI / 100.0 }
32
+ ys = xs.map {|x| Math.sin(x) }
33
+
34
+ plt.plot(xs, ys)
35
+ plt.show()
36
+
37
+ ### IRuby integration
38
+
39
+ `matplotlib/iruby` provides integration between IRuby notebook and matplotlib.
40
+ This functionality can be enabled by calling `Matplotlib::IRuby.activate`.
41
+
42
+ require 'matplotlib/iruby'
43
+ Matplotlib::IRuby.activate
44
+
45
+ `matplotlib/iruby` also loads `matplotlib/pyplot`, so you can use `Matplotlib::Pyplot` module without explicitly requiring `matplotlib/pyplot`.
46
+ And this introduces a post execution hook which put figures that are created in a cell just below the execution result of the cell.
47
+
48
+ See ipynb files in [examples](examples) to see example usages.
26
49
 
27
50
  ## Development
28
51
 
@@ -38,4 +61,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/mrkn/m
38
61
  ## License
39
62
 
40
63
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
-
data/lib/matplotlib.rb CHANGED
@@ -1,41 +1,26 @@
1
- require "matplotlib/version"
2
- require 'pycall/import'
1
+ require 'matplotlib/version'
2
+ require 'pycall'
3
3
 
4
- module Matplotlib
5
- @matplotlib = PyCall.import_module('matplotlib')
6
- PyCall.dir(@matplotlib).each do |name|
7
- obj = PyCall.getattr(@matplotlib, name)
8
- next unless obj.kind_of?(PyCall::PyObject) || obj.kind_of?(PyCall::PyObjectWrapper)
9
- next unless PyCall.callable?(obj)
10
-
11
- define_singleton_method(name) do |*args, **kwargs|
12
- obj.(*args, **kwargs)
13
- end
14
- end
4
+ Matplotlib = PyCall.import_module('matplotlib')
15
5
 
16
- class << self
17
- def __pyobj__
18
- @matplotlib
19
- end
20
-
21
- def method_missing(name, *args, **kwargs)
22
- return super unless PyCall.hasattr?(@matplotlib, name)
23
- PyCall.getattr(@matplotlib, name)
24
- end
25
- end
6
+ module Matplotlib
7
+ VERSION = MATPLOTLIB_VERSION
8
+ Object.class_eval { remove_const :MATPLOTLIB_VERSION }
26
9
 
27
10
  # FIXME: MacOSX backend is unavailable via pycall.
28
11
  # I don't know why it is.
29
- if Matplotlib.get_backend() == 'MacOSX'
30
- Matplotlib.use('TkAgg')
12
+ if get_backend == 'MacOSX'
13
+ use('TkAgg')
31
14
  end
32
15
 
33
16
  class Error < StandardError
34
17
  end
35
18
  end
36
19
 
20
+ require 'matplotlib/axis'
37
21
  require 'matplotlib/axes'
38
22
  require 'matplotlib/polar_axes'
39
23
  require 'matplotlib/figure'
24
+ require 'matplotlib/spines'
40
25
 
41
- PyCall.append_sys_path(File.expand_path('../matplotlib/python', __FILE__))
26
+ PyCall.sys.path.insert(0, File.expand_path('../matplotlib/python', __FILE__))
@@ -1,6 +1,4 @@
1
1
  module Matplotlib
2
- class Axes
3
- include PyCall::PyObjectWrapper
4
- wrap_class PyCall.import_module('matplotlib.axes').Axes
5
- end
2
+ Axes = PyCall.import_module('matplotlib.axes').Axes
3
+ Axes.__send__ :register_python_type_mapping
6
4
  end
@@ -1,6 +1,4 @@
1
1
  module Matplotlib
2
- class Axes3D
3
- include PyCall::PyObjectWrapper
4
- wrap_class PyCall.import_module('mpl_toolkits.mplot3d').Axes3D
5
- end
2
+ Axes3D = PyCall.import_module('mpl_toolkits.mplot3d').Axes3D
3
+ Axes3D.__send__ :register_python_type_mapping
6
4
  end
@@ -0,0 +1,16 @@
1
+ module Matplotlib
2
+ Axis = PyCall.import_module('matplotlib.axis')
3
+ module Axis
4
+ XTick = self.XTick
5
+ XTick.__send__ :register_python_type_mapping
6
+
7
+ YTick = self.YTick
8
+ YTick.__send__ :register_python_type_mapping
9
+
10
+ XAxis = self.XAxis
11
+ XAxis.__send__ :register_python_type_mapping
12
+
13
+ YAxis = self.YAxis
14
+ YAxis.__send__ :register_python_type_mapping
15
+ end
16
+ end
@@ -1,28 +1,4 @@
1
1
  module Matplotlib
2
- class Figure
3
- include PyCall::PyObjectWrapper
4
-
5
- @__pyobj__ = PyCall.import_module('matplotlib.figure').Figure
6
-
7
- PyCall.dir(@__pyobj__).each do |name|
8
- obj = PyCall.getattr(@__pyobj__, name)
9
- next unless obj.kind_of?(PyCall::PyObject) || obj.kind_of?(PyCall::PyObjectWrapper)
10
- next unless PyCall.callable?(obj)
11
-
12
- define_method(name) do |*args, **kwargs|
13
- PyCall.getattr(__pyobj__, name).(*args, **kwargs)
14
- end
15
- end
16
-
17
- class << self
18
- attr_reader :__pyobj__
19
-
20
- def method_missing(name, *args, **kwargs)
21
- return super unless PyCall.hasattr?(__pyobj__, name)
22
- PyCall.getattr(__pyobj__, name)
23
- end
24
- end
25
-
26
- PyCall::Conversions.python_type_mapping(__pyobj__, self)
27
- end
2
+ Figure = PyCall.import_module('matplotlib.figure').Figure
3
+ Figure.__send__ :register_python_type_mapping
28
4
  end
@@ -1,4 +1,4 @@
1
- require 'pycall'
1
+ require 'matplotlib'
2
2
 
3
3
  module Matplotlib
4
4
  module IRuby
@@ -61,17 +61,20 @@ module Matplotlib
61
61
  rescue SystemExit
62
62
  content[:payload] << { source: :ask_exit }
63
63
  rescue Exception => e
64
- content = error_message(e)
64
+ content = error_content(e)
65
65
  @session.send(:publish, :error, content)
66
66
  end
67
67
 
68
+ unless result.nil? || msg[:content]['silent']
69
+ @session.send(:publish, :execute_result,
70
+ data: ::IRuby::Display.display(result),
71
+ metadata: {},
72
+ execution_count: @execution_count)
73
+ end
74
+
68
75
  trigger_event(:post_execute)
69
76
 
70
77
  @session.send(:reply, :execute_reply, content)
71
- @session.send(:publish, :execute_result,
72
- data: ::IRuby::Display.display(result),
73
- metadata: {},
74
- execution_count: @execution_count) unless result.nil? || msg[:content]['silent']
75
78
  end
76
79
  end
77
80
 
@@ -85,17 +88,18 @@ module Matplotlib
85
88
  }.freeze
86
89
 
87
90
  module Helper
91
+ BytesIO = PyCall.import_module('io').BytesIO
92
+
88
93
  def register_formats
89
- bytes_io = PyCall.import_module('io').BytesIO
90
94
  type { Figure }
91
95
  AGG_FORMATS.each do |mime, format|
92
96
  format mime do |fig|
93
- unless fig.canvas.get_supported_filetypes.().has_key?(format)
97
+ unless fig.canvas.get_supported_filetypes.has_key?(format)
94
98
  raise Error, "Unable to display a figure in #{format} format"
95
99
  end
96
- io = bytes_io.()
97
- fig.canvas.print_figure.(io, format: format, bbox_inches: 'tight')
98
- io.getvalue.()
100
+ io = BytesIO.new
101
+ fig.canvas.print_figure(io, format: format, bbox_inches: 'tight')
102
+ io.getvalue
99
103
  end
100
104
  end
101
105
  end
@@ -119,7 +123,7 @@ module Matplotlib
119
123
  nbagg: :nbAgg,
120
124
  notebook: :nbAgg,
121
125
  agg: :agg,
122
- inline: 'module://ruby.matplotlib.backend_inline',
126
+ inline: 'module://matplotlib_rb.backend_inline',
123
127
  }.freeze
124
128
 
125
129
  BACKEND_GUI_MAP = Hash[GUI_BACKEND_MAP.select {|k, v| v }].freeze
@@ -210,13 +214,24 @@ module Matplotlib
210
214
  # Temporally monky-patching IRuby kernel to enable flushing and closing figures.
211
215
  # TODO: Make this feature a pull-request for sciruby/iruby.
212
216
  kernel = ::IRuby::Kernel.instance
213
- kernel.extend HookExtension
217
+ kernel.extend HookExtension unless kernel.respond_to?(:events)
214
218
  if backend == GUI_BACKEND_MAP[:inline]
215
- kernel.register_event(:post_execute, method(:flush_figures))
219
+ if kernel.respond_to?(:register_event)
220
+ kernel.register_event(:post_execute, method(:flush_figures))
221
+ else
222
+ @post_execute_func = kernel.events.register(:post_execute, &method(:flush_figures))
223
+ end
224
+
216
225
  # TODO: save original rcParams and overwrite rcParams with IRuby-specific configuration
217
226
  new_backend_name = :inline
218
227
  else
219
- kernel.unregister_event(:post_execute, method(:flush_figures))
228
+ if kernel.respond_to?(:unregister_event)
229
+ kernel.unregister_event(:post_execute, method(:flush_figures))
230
+ elsif @post_execute_func
231
+ kernel.events.unregister(:post_execute, @post_execute_func)
232
+ @post_execute_func = nil
233
+ end
234
+
220
235
  # TODO: restore saved original rcParams
221
236
  new_backend_name = :not_inline
222
237
  end
@@ -237,17 +252,14 @@ module Matplotlib
237
252
  # @param [true, false] close If true, a `plt.close('all')` call is automatically issued after sending all the figures.
238
253
  def show_figures(close=false)
239
254
  _pylab_helpers = PyCall.import_module('matplotlib._pylab_helpers')
240
- gcf = PyCall.getattr(_pylab_helpers, :Gcf)
255
+ gcf = _pylab_helpers.Gcf
241
256
  kernel = ::IRuby::Kernel.instance
242
- gcf.get_all_fig_managers.().each do |fig_manager|
257
+ gcf.get_all_fig_managers.each do |fig_manager|
243
258
  data = ::IRuby::Display.display(fig_manager.canvas.figure)
244
- kernel.session.send(:publish, :execute_result,
245
- data: data,
246
- metadata: {},
247
- execution_count: kernel.instance_variable_get(:@execution_count))
259
+ kernel.session.send(:publish, :display_data, data: data, metadata: {})
248
260
  end
249
261
  ensure
250
- unless gcf.get_all_fig_managers.().none?
262
+ unless gcf.get_all_fig_managers.nil?
251
263
  Matplotlib::Pyplot.close('all')
252
264
  end
253
265
  end
@@ -1,6 +1,4 @@
1
1
  module Matplotlib
2
- class PolarAxes
3
- include PyCall::PyObjectWrapper
4
- wrap_class PyCall.import_module('matplotlib.projections.polar').PolarAxes
5
- end
2
+ PolarAxes = PyCall.import_module('matplotlib.projections.polar').PolarAxes
3
+ PolarAxes.__send__ :register_python_type_mapping
6
4
  end
@@ -1,27 +1,11 @@
1
1
  require 'matplotlib'
2
2
 
3
3
  module Matplotlib
4
+ Pyplot = PyCall.import_module('matplotlib.pyplot')
4
5
  module Pyplot
5
- @pyplot = PyCall.import_module('matplotlib.pyplot')
6
- PyCall.dir(@pyplot).each do |name|
7
- obj = PyCall.getattr(@pyplot, name)
8
- next unless obj.kind_of?(PyCall::PyObject) || obj.kind_of?(PyCall::PyObjectWrapper)
9
- next unless PyCall.callable?(obj)
10
-
11
- define_singleton_method(name) do |*args, **kwargs|
12
- obj.(*args, **kwargs)
13
- end
14
- end
15
-
16
- class << self
17
- def __pyobj__
18
- @pyplot
19
- end
20
-
21
- def method_missing(name, *args, **kwargs)
22
- return super unless PyCall.hasattr?(@pyplot, name)
23
- PyCall.getattr(@pyplot, name)
24
- end
6
+ def self.xkcd(scale: 1, length: 100, randomness: 2, &block)
7
+ ctx = super(scale: scale, length: length, randomness: randomness)
8
+ PyCall.with(ctx, &block)
25
9
  end
26
10
  end
27
11
  end
File without changes
@@ -0,0 +1,4 @@
1
+ module Matplotlib
2
+ Spine = PyCall.import_module('matplotlib.spines').Spine
3
+ Spine.__send__ :register_python_type_mapping
4
+ end
@@ -1,3 +1 @@
1
- module Matplotlib
2
- VERSION = "0.1.0.alpha.20170311"
3
- end
1
+ MATPLOTLIB_VERSION = "1.2.0"
data/matplotlib.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'matplotlib/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "matplotlib"
8
- spec.version = Matplotlib::VERSION
8
+ spec.version = MATPLOTLIB_VERSION
9
9
  spec.authors = ["Kenta Murata"]
10
10
  spec.email = ["mrkn@mrkn.jp"]
11
11
 
@@ -21,10 +21,10 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_dependency "pycall", ">= 0.1.0.alpha.20170311"
24
+ spec.add_dependency "pycall", ">= 1.0.0"
25
25
 
26
- spec.add_development_dependency "bundler", "~> 1.13"
27
- spec.add_development_dependency "rake", "~> 10.0"
28
- spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency "bundler", ">= 1.17.2"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
29
  spec.add_development_dependency "pry"
30
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: matplotlib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha.20170311
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-11 00:00:00.000000000 Z
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pycall
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.0.alpha.20170311
19
+ version: 1.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.0.alpha.20170311
26
+ version: 1.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.13'
33
+ version: 1.17.2
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.13'
40
+ version: 1.17.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '3.0'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -96,20 +96,18 @@ files:
96
96
  - Rakefile
97
97
  - bin/console
98
98
  - bin/setup
99
- - examples/classifier_comparison.ipynb
100
- - examples/forest_importances.ipynb
101
- - examples/iruby_integration.ipynb
102
- - examples/lorenz_attractor.ipynb
103
99
  - examples/noisy_sin.rb
104
- - examples/polar_axes.ipynb
105
100
  - lib/matplotlib.rb
106
101
  - lib/matplotlib/axes.rb
107
102
  - lib/matplotlib/axes_3d.rb
103
+ - lib/matplotlib/axis.rb
108
104
  - lib/matplotlib/figure.rb
109
105
  - lib/matplotlib/iruby.rb
110
106
  - lib/matplotlib/polar_axes.rb
111
107
  - lib/matplotlib/pyplot.rb
112
- - lib/matplotlib/python/ruby/matplotlib/backend_inline.py
108
+ - lib/matplotlib/python/matplotlib_rb/__init__.py
109
+ - lib/matplotlib/python/matplotlib_rb/backend_inline.py
110
+ - lib/matplotlib/spines.rb
113
111
  - lib/matplotlib/version.rb
114
112
  - matplotlib.gemspec
115
113
  homepage: https://github.com/mrkn/matplotlib.rb
@@ -127,12 +125,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
125
  version: '0'
128
126
  required_rubygems_version: !ruby/object:Gem::Requirement
129
127
  requirements:
130
- - - ">"
128
+ - - ">="
131
129
  - !ruby/object:Gem::Version
132
- version: 1.3.1
130
+ version: '0'
133
131
  requirements: []
134
- rubyforge_project:
135
- rubygems_version: 2.6.8
132
+ rubygems_version: 3.2.3
136
133
  signing_key:
137
134
  specification_version: 4
138
135
  summary: matplotlib wrapper for Ruby