SciRuby / iruby

Official gem repository: Ruby kernel for Jupyter/IPython Notebook
https://github.com/SciRuby/iruby
MIT License
890 stars 27 forks source link

[Nuisance issue] Using Gnuplot prints correct graph, also throws error #321

Closed Xasin closed 2 years ago

Xasin commented 2 years ago

Dear IRuby maintainer team,

I ran into a minor issue (annoyance, does not seem to actually impact functionality) with using Gnuplot.

The issue: Gnuplot will correctly render the graph and insert output below the cell. However, IRuby also throws an error below it. The kernel continues execution as normal and the graph remains, the only issue is the fact that the error message clutters output.

Reproduction: Using the minimal gnuplot example as given in the example notebook:

require 'gnuplot'

Gnuplot::Plot.new() do |plot|

    plot.title  "Array Plot Example"
    plot.xlabel "x"
    plot.ylabel "x^2"

    x = (0..50).collect { |v| v.to_f }
    y = x.collect { |v| v ** 2 }

    plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
      ds.with = "linespoints"
      ds.notitle
    end
  end

Output: image

Execution continues as normal after this.

Versions:

No further output in the console running Jupyter was seen. As such, this is mostly a nuisance issue, but can be confusing, as it is expected that the given minimal examples work without throwing errors.

Note that the error message IS correct. Calling to_hash returns a key-value pair array. This might be a subtle version incompatibility between IRuby and the gnuplot gem that I am using. Perhaps a small check to convert the returned array ((which really should be a hash, why to_hash returns a key-value pair array is a mystery to me)) to a hash would already fix this.

The returned array looks like this: [[:set, "title", "\"Array Plot Example\""], [:set, "xlabel", "\"x\""], [:set, "ylabel", "\"x^2\""], [:set, "to_hash", ""]]

kojix2 commented 2 years ago

I tried with Ruby 3.1 but could not reproduce the relevant error message.

Lab image

Notebook image

Selected Jupyter core packages...
IPython          : 8.3.0
ipykernel        : 6.9.1
ipywidgets       : not installed
jupyter_client   : 7.2.2
jupyter_core     : 4.10.0
jupyter_server   : 1.17.1
jupyterlab       : 3.3.2
nbclient         : 0.5.13
nbconvert        : 6.4.4
nbformat         : 5.3.0
notebook         : 6.4.11
qtconsole        : not installed
traitlets        : 5.1.1
Xasin commented 2 years ago

I can confirm, the problem no longer exists when I use rvm to switch to Ruby3.0.0 Interestingly enough, the output of to_hash for the Gnuplot call is still an array. The exact same version of the gnuplot library and iruby library are used.

Perhaps there is a difference in either error type handling (i.e. the error is caught in Ruby 3.0 but not 2.7), or some form of implicit conversion that turns it into a hash properly?

Either way, using RVM to switch to Ruby 3.0 is acceptable for my use case, but it would be nice to either suppress these warnings for lower versions or add a short note to the documentation saying that there is a small issue with the lower ruby version.

kojix2 commented 2 years ago

Ok, thanks. I did confirm that the error occurs in 2.7.6.

kojix2 commented 2 years ago

I see an error when a Gnuplot class object is passed to "*args".

kernel.rb

      events.trigger(:post_run_cell, result) unless silent # result is_a Gnuplot object

event_manager.rb

    def trigger(event, *args, **kwargs)
      check_available_event(event)
      @callbacks[event].each do |fn|
        fn.call(*args, **kwargs)
      end
    end
kojix2 commented 2 years ago

Maybe if I change it like this it will work. I'm not sure if this is enough.

    def trigger(*args, **kwargs)
      event = args.shift
      check_available_event(event)
      @callbacks[event].each do |fn|
        fn.call(*args, **kwargs)
      end
    end
kojix2 commented 2 years ago

No, the above change does not solve the problem. Gnuplot::Plot uses method_missing and reacts to to_h and to_hash. This seems to be causing the problem.

kojix2 commented 2 years ago

Fixed. However, I recommend using numo-gnuplot.

https://github.com/ruby-numo/numo-gnuplot

Xasin commented 2 years ago

Thank you kindly for the fix! That just makes the behaviour a bit more consistent. Also, I appreciate the mention of Numo-Gnuplot

I have used Numo-narray before, and should look at the other tools that they offer.

Have a lovely day ^^