<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>liggest (liggest)</title>
    <link>https://ruby-china.org/liggest</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>没想到在 IRuby 中绘个图这么难…</title>
      <description>&lt;h3 id="前情提要"&gt;前情提要&lt;/h3&gt;
&lt;p&gt;本人小白，没写过太多 Ruby，之前学过一点 Python&lt;/p&gt;

&lt;p&gt;最近想试着在 &lt;a href="https://jupyter.org/index.html" rel="nofollow" target="_blank" title=""&gt;Jupyter Notebook&lt;/a&gt; 中写点代码，有个绘制柱状图/直方图的任务，说是建议使用 matplotlib 或 Gnuplot&lt;/p&gt;

&lt;p&gt;用过的可能知道，Jupyter Notebook 默认基于 IPython 内核提供了交互式编程环境，用来做一些计算分析和绘图，在一个记事本里展示出来，个人感觉还挺方便的&lt;/p&gt;

&lt;p&gt;恰好前段时间发现也有个能用的 &lt;a href="https://github.com/SciRuby/iruby" rel="nofollow" target="_blank" title=""&gt;IRuby&lt;/a&gt; 内核，可以在记事本里面跑 Ruby，听起来还不错&lt;/p&gt;

&lt;p&gt;因为 Python 中直接用 matplotlib 就可以轻松在记事本中绘图，故我下意识的以为这应该是个很快就能搞定的任务&lt;/p&gt;

&lt;p&gt;&lt;del&gt;前提是在 Ruby 中找到合适的库…&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;所用环境：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows 10&lt;/li&gt;
&lt;li&gt;Ruby 3.0.2&lt;/li&gt;
&lt;li&gt;Python 3.7.2（用 Anaconda 装的）&lt;/li&gt;
&lt;li&gt;IRuby 0.7.4&lt;/li&gt;
&lt;li&gt;Pry 0.14.1（因为用 &lt;a href="https://github.com/pry/pry" rel="nofollow" target="_blank" title=""&gt;Pry&lt;/a&gt; 做的 IRuby 后台）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="太长不看"&gt;太长不看&lt;/h3&gt;
&lt;p&gt;在尝试过 &lt;a href="https://github.com/mrkn/matplotlib.rb" rel="nofollow" target="_blank" title=""&gt;matplotlib.rb&lt;/a&gt;、&lt;a href="https://github.com/SciRuby/gnuplotrb" rel="nofollow" target="_blank" title=""&gt;gnuplotrb&lt;/a&gt;、&lt;a href="https://github.com/ruby-numo/numo-gnuplot" rel="nofollow" target="_blank" title=""&gt;numo-gnuplot&lt;/a&gt;、&lt;a href="https://github.com/SciRuby/daru-view" rel="nofollow" target="_blank" title=""&gt;daru-view&lt;/a&gt; 后，最终发现 &lt;a href="https://github.com/SciRuby/daru-view" rel="nofollow" target="_blank" title=""&gt;daru-view&lt;/a&gt; 依赖中的 &lt;a href="https://github.com/domitry/nyaplot" rel="nofollow" target="_blank" title=""&gt;nyaplot&lt;/a&gt; 在 5 年未更新后依然是可用的，折腾了大半天终于画出了柱状图，好耶！&lt;/p&gt;
&lt;h3 id="踩坑"&gt;踩坑&lt;/h3&gt;&lt;h4 id="matplotlib.rb"&gt;matplotlib.rb&lt;/h4&gt;
&lt;p&gt;因为要绘图，首先想到了 matplotlib，毕竟任务也推荐使用嘛&lt;/p&gt;

&lt;p&gt;发现 &lt;a href="https://github.com/mrkn/pycall.rb" rel="nofollow" target="_blank" title=""&gt;PyCall&lt;/a&gt; 的作者也特地为 matplotlib 做了 Ruby 中的封装 gem，就是 &lt;a href="https://github.com/mrkn/matplotlib.rb" rel="nofollow" target="_blank" title=""&gt;matplotlib.rb&lt;/a&gt;，还提供了 IRuby 使用示例，当场就安装了。&lt;/p&gt;

&lt;p&gt;起初是在&lt;code&gt;require&lt;/code&gt;的时候会提示 Python 那边的&lt;code&gt;ImportError&lt;/code&gt;，好像是 numpy 在初始化时无法找到某些 DLL，相应的 matplotlib 也无法成功导入&lt;/p&gt;

&lt;p&gt;于是尝试在搜索引擎和 Github Issue 中寻找解决方案，numpy 的 Issue 中似乎提到这是由 Conda 安装的 numpy 才有的问题，应该和 Conda 环境有关&lt;/p&gt;

&lt;p&gt;不像用 Python 内核时那样，即便我在启动 Notebook 前先进入 Conda 环境，PyCall 似乎也无法正确导入相应的包&lt;/p&gt;

&lt;p&gt;在花了一些时间后，我在 PyCall 仓库一个&lt;a href="https://github.com/mrkn/pycall.rb/blob/master/.github/workflows/windows.yml" rel="nofollow" target="_blank" title=""&gt;名为 windows 的 workflow&lt;/a&gt; 中发现它好像在执行测试时将环境变量&lt;code&gt;CONDA_DLL_SEARCH_MODIFICATION_ENABLE&lt;/code&gt;设为了&lt;code&gt;1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;于是我这边在&lt;code&gt;require&lt;/code&gt;前也照做了一下，同时用&lt;code&gt;PyCall.init&lt;/code&gt;指定了 Python 可执行文件的的位置，确实使得&lt;code&gt;ImportError&lt;/code&gt;消失了，但导入仍未成功，取而代之的是从 Ruby 端执行到 C 端后产生的大量报错调试信息，感到自己没法解决这个问题，只能作罢&lt;/p&gt;
&lt;h4 id="gnuplotrb"&gt;gnuplotrb&lt;/h4&gt;
&lt;p&gt;转而去看看能不能用上 Gnuplot，在 &lt;a href="https://sourceforge.net/projects/gnuplot/files/gnuplot/5.4.2/" rel="nofollow" target="_blank" title=""&gt;SourceForge&lt;/a&gt; 上下载并安装了，窗体程序似乎正常运行&lt;/p&gt;

&lt;p&gt;Ruby 这边，虽然有 Star 更多的 &lt;a href="https://github.com/rdp/ruby_gnuplot" rel="nofollow" target="_blank" title=""&gt;ruby_gnuplot&lt;/a&gt;，但其 README 中似乎没提到任何支持 IRuby 的内容，故选择先试着用与 IRuby 同属一组织的 &lt;a href="https://github.com/SciRuby/gnuplotrb" rel="nofollow" target="_blank" title=""&gt;gnuplotrb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;安装完后把它 &lt;a href="https://nbviewer.jupyter.org/github/sciruby/gnuplotrb/blob/master/notebooks/basic_usage.ipynb" rel="nofollow" target="_blank" title=""&gt;示例记事本&lt;/a&gt; 的首格代码丢到这边的记事本中测试&lt;/p&gt;

&lt;p&gt;提示参数个数有问题，应该有 1 个参数，实际给了 2 个，猜测应该是 Ruby3.0 以来&lt;a href="https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/" rel="nofollow" target="_blank" title=""&gt;关于关键字参数的修改&lt;/a&gt; 导致的，斗胆开 VSCode 顺着源码查了一下，把喂给参数的 Hash 按关键字参数的格式传进去了&lt;/p&gt;

&lt;p&gt;本以为这样就能画出图了，然后代码一运行当场就卡住了（代码所在的那一格无法停止运行）&lt;/p&gt;

&lt;p&gt;调试发现，似乎&lt;code&gt;Plot.new&lt;/code&gt;的执行并没有什么问题，但 IRuby 在将其返回的对象显示出来的过程中出现了问题&lt;/p&gt;

&lt;p&gt;本以为是 IRuby 的问题，但粗略探索后发现似乎它的&lt;code&gt;display&lt;/code&gt;方法主要是调用了对象相应的&lt;code&gt;to_xxx&lt;/code&gt;方法（如&lt;code&gt;to_png&lt;/code&gt;），而且先前照着 &lt;a href="https://nbviewer.jupyter.org/github/SciRuby/sciruby-notebooks/blob/master/getting_started.ipynb" rel="nofollow" target="_blank" title=""&gt;IRuby 示例&lt;/a&gt;也成功显示过 svg&lt;/p&gt;

&lt;p&gt;转而去看 gnuplotrb 那边，经过数次重启记事本的尝试，发现似乎是同 Gnuplot 通信时，本应用&lt;code&gt;Open3.capture2e&lt;/code&gt;获取输出结果，但不知为何其启动的 Gnuplot 无法结束执行，导致程序原地卡住&lt;/p&gt;

&lt;p&gt;在 Pry 与 Irb 中都试着运行了同样的语句，均会让程序卡住&lt;/p&gt;

&lt;p&gt;更糟的是，即使 Ctrl+C 强行终止，似乎 Gnuplot 依然会在后台运行，甚至记事本重启也不会使其结束，以至于后台运行的 Gnuplot 数量随着记事本重启而不停增加，后面想结束 Jupyter 时似乎才一并把不知多少个 Gnuplot 结束掉，控制台直接未响应了……&lt;/p&gt;

&lt;p&gt;这还是试用 Gnuplot 不成，卸载时卸不干净才发现的&lt;/p&gt;

&lt;p&gt;尝试把&lt;code&gt;Open3.capture2e&lt;/code&gt;换成了能执行命令行指令的 ` `（反引号），似乎解决了上述问题，虽然还搞不清楚它们有什么区别…&lt;/p&gt;

&lt;p&gt;但返回去执行示例代码，程序却依然卡住，Github 上似乎也有人提到了&lt;a href="https://github.com/SciRuby/gnuplotrb/issues/20" rel="nofollow" target="_blank" title=""&gt;这个问题&lt;/a&gt;，但却没有解决方案…&lt;/p&gt;

&lt;p&gt;此时我已经有点疲惫了，决定先去看看其他绘图库&lt;/p&gt;
&lt;h4 id="numo-gnuplot"&gt;numo-gnuplot&lt;/h4&gt;
&lt;p&gt;借助搜索引擎我找到了 ruby_gnuplot、gnuplotrb 之外的另一个 Gnuplot 库—— &lt;a href="https://github.com/ruby-numo/numo-gnuplot" rel="nofollow" target="_blank" title=""&gt;numo-gnuplot&lt;/a&gt;，本体 &lt;a href="https://github.com/ruby-numo/numo" rel="nofollow" target="_blank" title=""&gt;Numo&lt;/a&gt; 似乎是一个数值计算库（类似 Numpy？），也写明了支持 IRuby&lt;/p&gt;

&lt;p&gt;虽然安装本体 Numo 没能成功，但似乎 numo-gnuplot 可以单独安装使用&lt;/p&gt;

&lt;p&gt;然后执行了 README 中的示例代码，不出意外地又卡住了&lt;/p&gt;

&lt;p&gt;果然在 Windows 下用 Ruby 调用 Gnuplot 会有问题吧…？这样想着，也不再太多兴趣去试着解决卡住的问题，干脆把上述几个用不了的库全都卸掉了 (╯‵□′)╯︵┻━┻&lt;/p&gt;
&lt;h3 id="解决"&gt;解决&lt;/h3&gt;
&lt;p&gt;再次求助谷歌（百度搜不到什么相关内容啦…），又看到一个名为 &lt;a href="https://github.com/SciRuby/daru-view" rel="nofollow" target="_blank" title=""&gt;daru-view&lt;/a&gt; 的，本体是 &lt;a href="https://github.com/SciRuby/daru" rel="nofollow" target="_blank" title=""&gt;Daru&lt;/a&gt;（看起来像类似 pandas 的东西？）&lt;/p&gt;

&lt;p&gt;daru-view 似乎作为 Daru 的插件使用，万幸两者都安装成功&lt;/p&gt;

&lt;p&gt;它看起来还挺高级的，内部集成了&lt;code&gt;:googlecharts&lt;/code&gt;、&lt;code&gt;:highcharts&lt;/code&gt;、&lt;code&gt;:nyaplot&lt;/code&gt;三套绘图工具，安装时一下子装了十四、五个 gem，好家伙，我只是想画个柱状图而已&lt;/p&gt;

&lt;p&gt;其中安装 &lt;a href="https://github.com/domitry/nyaplot" rel="nofollow" target="_blank" title=""&gt;nyaplot&lt;/a&gt; 时命令行出现了诸如欢迎使用 nyaplot 和推荐使用 IRuby 的输出，让我想起 IRuby 的示例中确实也有使用 nyaplot 绘图的内容，想必两者关系还挺密切的&lt;/p&gt;

&lt;p&gt;但 nyaplot 仓库默认分支的最后更新日期是 2016 年，已经约莫 5 年没更新过了，看起来就是一种年久失修的状态&lt;/p&gt;

&lt;p&gt;抱着既然都装上了就先试试看的心态，用记事本运行了一些&lt;a href="https://nbviewer.jupyter.org/github/domitry/nyaplot/blob/master/examples/notebook/Getting_Started_with_Nyaplot.ipynb" rel="nofollow" target="_blank" title=""&gt;示例代码&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;结果图啪地一下就出来了，我也啪地从椅子上弹了起来——折腾了大半天，终于看到了柱状图！&lt;/p&gt;

&lt;p&gt;不知道说什么好，默默地看了一眼那个让我找到其它几个绘图库的帖子的标题——&lt;a href="https://stackoverflow.com/questions/44552756/nyaplot-generates-no-plot-in-iruby-running-in-jupyterhub" rel="nofollow" target="_blank" title=""&gt;Nyaplot 在 Jupyterhub 上的 IRuby 中无输出&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;总而言之，没有再继续测试 daru-view 的各种用法，暂且先用 nyaplot 完成了几个简单的绘图任务&lt;/p&gt;

&lt;p&gt;虽然绘图功能看起来不及 matplotlib 那样复杂且强大，但用起来感觉还挺相似的，而且在 IRuby 上显示出来的图还能有轻度交互（缩放、查看数值之类的），感觉还算有点小惊喜的&lt;/p&gt;
&lt;h3 id="碎碎念"&gt;碎碎念&lt;/h3&gt;
&lt;p&gt;感觉接触 Ruby 后，像这样想用一些工具，经常会出现不好使的情况…&lt;/p&gt;

&lt;p&gt;除了 Ruby 对 Windows 的支持确实不算很优秀之外，感觉对于一些特定任务，可能也缺少那种大家集中开发、使用，处于领导地位的库&lt;/p&gt;

&lt;p&gt;相应地在 Python 中，绘图大概会用 matplotlib，数值计算常常需要 Numpy，数据分析有 pandas 等等…似乎大家会聚焦于几个特定的库，而这些库也因此能愈发发展，变得更加强大，因而也越能吸引更多人，比如我这样的小白去入门使用&lt;/p&gt;

&lt;p&gt;因此看到有类似的 &lt;a href="https://github.com/ruby-numo/numo" rel="nofollow" target="_blank" title=""&gt;Numo&lt;/a&gt;、&lt;a href="https://github.com/SciRuby/daru" rel="nofollow" target="_blank" title=""&gt;Daru&lt;/a&gt; 等出现在 Ruby 中，第一反应还挺开心的（虽然 Numo 装都没装上）&lt;/p&gt;

&lt;p&gt;IRuby 用起来感觉还有一些小问题，比如代码提示有时候不起效，会把代码结构搞乱等，可能是我还对相关工具不太熟练吧，体验不算完美，但也没有很差，能让 Ruby 搭上 Jupyter Notebook 交互式编程这一得力工具，感觉也挺不错的了&lt;/p&gt;

&lt;p&gt;这些库目前感觉关注的人很少，从 Github 的 Star 数也能看出来，但就像 Python 那一系列库和 Jupyter Notebook 一起被用到各种学术研究领域，感觉 Ruby 在这方面还是能有一定前景才是…&lt;/p&gt;

&lt;p&gt;至于绘图相关的库… &lt;a href="https://github.com/ruby-numo/numo-gnuplot" rel="nofollow" target="_blank" title=""&gt;numo-gnuplot&lt;/a&gt; 的 README 中提及的参考便有 &lt;a href="https://github.com/rdp/ruby_gnuplot" rel="nofollow" target="_blank" title=""&gt;ruby_gnuplot&lt;/a&gt;、&lt;a href="https://github.com/davor/ruby-plot" rel="nofollow" target="_blank" title=""&gt;ruby-plot&lt;/a&gt;、&lt;a href="https://github.com/elitheeli/plotrobber" rel="nofollow" target="_blank" title=""&gt;Plotrobber（404）&lt;/a&gt;、&lt;a href="https://github.com/pbosetti/gnuplotr" rel="nofollow" target="_blank" title=""&gt;gnuplotr&lt;/a&gt;、&lt;a href="https://github.com/maasha/gnuplotter" rel="nofollow" target="_blank" title=""&gt;gnuplotter&lt;/a&gt;、&lt;a href="https://rubygems.org/gems/scbi_plot" rel="nofollow" target="_blank" title=""&gt;scbi_plot&lt;/a&gt;、&lt;a href="https://github.com/SciRuby/gnuplotrb" rel="nofollow" target="_blank" title=""&gt;gnuplotrb&lt;/a&gt;、&lt;a href="https://rubygems.org/gems/numplot" rel="nofollow" target="_blank" title=""&gt;numplot&lt;/a&gt;，此外还能找到 &lt;a href="https://github.com/SciRuby/rubyplot" rel="nofollow" target="_blank" title=""&gt;rubyplot&lt;/a&gt;、&lt;a href="https://github.com/red-data-tools/charty" rel="nofollow" target="_blank" title=""&gt;charty&lt;/a&gt; 等…&lt;/p&gt;

&lt;p&gt;再补上文中提到的，不禁让人感叹，要是只有“matplotlib”该多好…可能更多开发者能合力维护一个项目，不至于像 &lt;a href="https://github.com/domitry/nyaplot" rel="nofollow" target="_blank" title=""&gt;nyaplot&lt;/a&gt; 那样看起来年久失修吧…&lt;/p&gt;

&lt;p&gt;最后需要说明的是以上内容包含大量个人见解和闲扯，萌新一枚不太懂什么规矩，如有问题还请随意指正…如果大致读完了，那真的很感谢能看我啰嗦这么多！&lt;/p&gt;</description>
      <author>liggest</author>
      <pubDate>Sun, 22 Aug 2021 20:56:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/41605</link>
      <guid>https://ruby-china.org/topics/41605</guid>
    </item>
  </channel>
</rss>
