本人小白,没写过太多 Ruby,之前学过一点 Python
最近想试着在 Jupyter Notebook 中写点代码,有个绘制柱状图/直方图的任务,说是建议使用 matplotlib 或 Gnuplot
用过的可能知道,Jupyter Notebook 默认基于 IPython 内核提供了交互式编程环境,用来做一些计算分析和绘图,在一个记事本里展示出来,个人感觉还挺方便的
恰好前段时间发现也有个能用的 IRuby 内核,可以在记事本里面跑 Ruby,听起来还不错
因为 Python 中直接用 matplotlib 就可以轻松在记事本中绘图,故我下意识的以为这应该是个很快就能搞定的任务
前提是在 Ruby 中找到合适的库…
所用环境:
在尝试过 matplotlib.rb、gnuplotrb、numo-gnuplot、daru-view 后,最终发现 daru-view 依赖中的 nyaplot 在 5 年未更新后依然是可用的,折腾了大半天终于画出了柱状图,好耶!
因为要绘图,首先想到了 matplotlib,毕竟任务也推荐使用嘛
发现 PyCall 的作者也特地为 matplotlib 做了 Ruby 中的封装 gem,就是 matplotlib.rb,还提供了 IRuby 使用示例,当场就安装了。
起初是在require
的时候会提示 Python 那边的ImportError
,好像是 numpy 在初始化时无法找到某些 DLL,相应的 matplotlib 也无法成功导入
于是尝试在搜索引擎和 Github Issue 中寻找解决方案,numpy 的 Issue 中似乎提到这是由 Conda 安装的 numpy 才有的问题,应该和 Conda 环境有关
不像用 Python 内核时那样,即便我在启动 Notebook 前先进入 Conda 环境,PyCall 似乎也无法正确导入相应的包
在花了一些时间后,我在 PyCall 仓库一个名为 windows 的 workflow 中发现它好像在执行测试时将环境变量CONDA_DLL_SEARCH_MODIFICATION_ENABLE
设为了1
于是我这边在require
前也照做了一下,同时用PyCall.init
指定了 Python 可执行文件的的位置,确实使得ImportError
消失了,但导入仍未成功,取而代之的是从 Ruby 端执行到 C 端后产生的大量报错调试信息,感到自己没法解决这个问题,只能作罢
转而去看看能不能用上 Gnuplot,在 SourceForge 上下载并安装了,窗体程序似乎正常运行
Ruby 这边,虽然有 Star 更多的 ruby_gnuplot,但其 README 中似乎没提到任何支持 IRuby 的内容,故选择先试着用与 IRuby 同属一组织的 gnuplotrb
安装完后把它 示例记事本 的首格代码丢到这边的记事本中测试
提示参数个数有问题,应该有 1 个参数,实际给了 2 个,猜测应该是 Ruby3.0 以来关于关键字参数的修改 导致的,斗胆开 VSCode 顺着源码查了一下,把喂给参数的 Hash 按关键字参数的格式传进去了
本以为这样就能画出图了,然后代码一运行当场就卡住了(代码所在的那一格无法停止运行)
调试发现,似乎Plot.new
的执行并没有什么问题,但 IRuby 在将其返回的对象显示出来的过程中出现了问题
本以为是 IRuby 的问题,但粗略探索后发现似乎它的display
方法主要是调用了对象相应的to_xxx
方法(如to_png
),而且先前照着 IRuby 示例也成功显示过 svg
转而去看 gnuplotrb 那边,经过数次重启记事本的尝试,发现似乎是同 Gnuplot 通信时,本应用Open3.capture2e
获取输出结果,但不知为何其启动的 Gnuplot 无法结束执行,导致程序原地卡住
在 Pry 与 Irb 中都试着运行了同样的语句,均会让程序卡住
更糟的是,即使 Ctrl+C 强行终止,似乎 Gnuplot 依然会在后台运行,甚至记事本重启也不会使其结束,以至于后台运行的 Gnuplot 数量随着记事本重启而不停增加,后面想结束 Jupyter 时似乎才一并把不知多少个 Gnuplot 结束掉,控制台直接未响应了……
这还是试用 Gnuplot 不成,卸载时卸不干净才发现的
尝试把Open3.capture2e
换成了能执行命令行指令的 ` `(反引号),似乎解决了上述问题,虽然还搞不清楚它们有什么区别…
但返回去执行示例代码,程序却依然卡住,Github 上似乎也有人提到了这个问题,但却没有解决方案…
此时我已经有点疲惫了,决定先去看看其他绘图库
借助搜索引擎我找到了 ruby_gnuplot、gnuplotrb 之外的另一个 Gnuplot 库—— numo-gnuplot,本体 Numo 似乎是一个数值计算库(类似 Numpy?),也写明了支持 IRuby
虽然安装本体 Numo 没能成功,但似乎 numo-gnuplot 可以单独安装使用
然后执行了 README 中的示例代码,不出意外地又卡住了
果然在 Windows 下用 Ruby 调用 Gnuplot 会有问题吧…?这样想着,也不再太多兴趣去试着解决卡住的问题,干脆把上述几个用不了的库全都卸掉了 (╯‵□′)╯︵┻━┻
再次求助谷歌(百度搜不到什么相关内容啦…),又看到一个名为 daru-view 的,本体是 Daru(看起来像类似 pandas 的东西?)
daru-view 似乎作为 Daru 的插件使用,万幸两者都安装成功
它看起来还挺高级的,内部集成了:googlecharts
、:highcharts
、:nyaplot
三套绘图工具,安装时一下子装了十四、五个 gem,好家伙,我只是想画个柱状图而已
其中安装 nyaplot 时命令行出现了诸如欢迎使用 nyaplot 和推荐使用 IRuby 的输出,让我想起 IRuby 的示例中确实也有使用 nyaplot 绘图的内容,想必两者关系还挺密切的
但 nyaplot 仓库默认分支的最后更新日期是 2016 年,已经约莫 5 年没更新过了,看起来就是一种年久失修的状态
抱着既然都装上了就先试试看的心态,用记事本运行了一些示例代码
结果图啪地一下就出来了,我也啪地从椅子上弹了起来——折腾了大半天,终于看到了柱状图!
不知道说什么好,默默地看了一眼那个让我找到其它几个绘图库的帖子的标题——Nyaplot 在 Jupyterhub 上的 IRuby 中无输出
总而言之,没有再继续测试 daru-view 的各种用法,暂且先用 nyaplot 完成了几个简单的绘图任务
虽然绘图功能看起来不及 matplotlib 那样复杂且强大,但用起来感觉还挺相似的,而且在 IRuby 上显示出来的图还能有轻度交互(缩放、查看数值之类的),感觉还算有点小惊喜的
感觉接触 Ruby 后,像这样想用一些工具,经常会出现不好使的情况…
除了 Ruby 对 Windows 的支持确实不算很优秀之外,感觉对于一些特定任务,可能也缺少那种大家集中开发、使用,处于领导地位的库
相应地在 Python 中,绘图大概会用 matplotlib,数值计算常常需要 Numpy,数据分析有 pandas 等等…似乎大家会聚焦于几个特定的库,而这些库也因此能愈发发展,变得更加强大,因而也越能吸引更多人,比如我这样的小白去入门使用
因此看到有类似的 Numo、Daru 等出现在 Ruby 中,第一反应还挺开心的(虽然 Numo 装都没装上)
IRuby 用起来感觉还有一些小问题,比如代码提示有时候不起效,会把代码结构搞乱等,可能是我还对相关工具不太熟练吧,体验不算完美,但也没有很差,能让 Ruby 搭上 Jupyter Notebook 交互式编程这一得力工具,感觉也挺不错的了
这些库目前感觉关注的人很少,从 Github 的 Star 数也能看出来,但就像 Python 那一系列库和 Jupyter Notebook 一起被用到各种学术研究领域,感觉 Ruby 在这方面还是能有一定前景才是…
至于绘图相关的库… numo-gnuplot 的 README 中提及的参考便有 ruby_gnuplot、ruby-plot、Plotrobber(404)、gnuplotr、gnuplotter、scbi_plot、gnuplotrb、numplot,此外还能找到 rubyplot、charty 等…
再补上文中提到的,不禁让人感叹,要是只有“matplotlib”该多好…可能更多开发者能合力维护一个项目,不至于像 nyaplot 那样看起来年久失修吧…
最后需要说明的是以上内容包含大量个人见解和闲扯,萌新一枚不太懂什么规矩,如有问题还请随意指正…如果大致读完了,那真的很感谢能看我啰嗦这么多!