matplotlib 0.1.0.alpha.20170311 → 1.2.0

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
- 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