2015/06/25

在Cygwin上安裝matplotlib、使用pylab繪製簡單的圖形

matplotlib是一套2D繪圖的Python程式庫,支援各式各樣的圖形表格;透過pyplot與pylab提供類似於MATLAB的介面,功能強大,用起來卻非常簡單,因為各種你會需要的功能,都已經幫你準備好了。

底下列出幾個從官網抓來的展示圖。

若要在Windows上安裝matplotlib,最簡單的方法是安裝已經統包整理好的套件,諸如Python(x,y)Enthought CanopyContinuum Anaconda,譬如安裝Canopy之後,開啟編輯器,輸入底下的範例程式碼:
import pylab

pylab.figure(1)
pylab.plot([1,2,3,4,5], [1,7,3,5,2])
pylab.show()
然後執行,嘿,便會出現新視窗顯示下圖。
真不錯,不過這篇的重點是在Cygwin上安裝matplotlib。安裝Cygwin本身的部分,請參考這篇

開啟Cygwin終端機,試著以底下指令安裝matplotlib:
$ pip install matplotlib
Collecting matplotlib
  Using cached matplotlib-1.4.3.tar.gz
    Complete output from command python setup.py egg_info:
    IMPORTANT WARNING:
        pkg-config is not installed.
        matplotlib may not be able to find some of its dependencies
    ===================================================================
    Edit setup.cfg to change the build options

    BUILDING MATPLOTLIB
                matplotlib: yes [1.4.3]
                    python: yes [2.7.10 (default, Jun  1 2015, 18:17:45)  [GCC
                            4.9.2]]
                  platform: yes [cygwin]
...省略...
    ==================================================================
                            * The following required packages can not be built:
                            * freetype

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-vScgZ4/matplotlib

出現錯誤訊息,因為沒有matplotlib需要的程式庫套件,我試了很多遍,參考了網路上許多文章,大概需要的套件有freetype、python-gtk、python-tk、libpng、gcc等,但因為試來試去,結果安裝了一堆,也不知道哪些其實是不需要的;我安裝的Cygwin套件有:libfreetype-devel、libfreetype6、python-gtk2.0、python-gtk2.0-devel、python-tkinter、libpng16、libpng16-devel、libpng-devel、libX11-devel、pkg-config、gcc-core

然後再試著安裝,成功囉:

$ pip install matplotlib
Collecting matplotlib
  Using cached matplotlib-1.4.3.tar.gz
Requirement already satisfied (use --upgrade to upgrade): numpy>=1.6 in /usr/lib/python2.7/site-packages (from matplotlib)
Requirement already satisfied (use --upgrade to upgrade): six>=1.4 in /usr/lib/python2.7/site-packages (from matplotlib)
Collecting python-dateutil (from matplotlib)
  Downloading python_dateutil-2.4.2-py2.py3-none-any.whl (188kB)
    100% |████████████████████████████████| 192kB 524kB/s
Collecting pytz (from matplotlib)
  Downloading pytz-2015.4-py2.py3-none-any.whl (475kB)
    100% |████████████████████████████████| 475kB 262kB/s
Requirement already satisfied (use --upgrade to upgrade): pyparsing>=1.5.6 in /usr/lib/python2.7/site-packages (from matplotlib)
Collecting nose>=0.11.1 (from matplotlib)
  Downloading nose-1.3.7-py2-none-any.whl (154kB)
    100% |████████████████████████████████| 155kB 655kB/s
Collecting mock (from matplotlib)
  Downloading mock-1.0.1.tar.gz (818kB)
    100% |████████████████████████████████| 819kB 187kB/s
Building wheels for collected packages: matplotlib, mock
  Running setup.py bdist_wheel for matplotlib
  Stored in directory: /home/yehnan/.cache/pip/wheels/12/98/77/c3a045fea5159ea287a3db9d1c55c471d452019fecfde2f194
  Running setup.py bdist_wheel for mock
  Stored in directory: /home/yehnan/.cache/pip/wheels/c9/b4/72/4de2802cbc4bfd82f938ff92015e1b42f01131583675ab4d00
Successfully built matplotlib mock
Installing collected packages: python-dateutil, pytz, nose, mock, matplotlib
Successfully installed matplotlib-1.4.3 mock-1.0.1 nose-1.3.7 python-dateutil-2.4.2 pytz-2015.4

花費了不少時間,接著執行剛剛的範例程式碼(假設檔名為a.py):

$ python a.py
/usr/lib/python2.7/site-packages/gtk-2.0/gtk/__init__.py:57: GtkWarning: could not open display
  warnings.warn(str(e), _gtk.Warning)
/usr/lib/python2.7/site-packages/matplotlib/backends/backend_gtk.py:61: GtkWarning: gdk_cursor_new_for_display: assertion 'GDK_IS_DISPLAY (display)' failed
  cursors.MOVE          : gdk.Cursor(gdk.FLEUR),
...省略...
  File "/usr/lib/python2.7/site-packages/matplotlib/backends/backend_gtk.py", line 61, in
    cursors.MOVE          : gdk.Cursor(gdk.FLEUR),
RuntimeError: could not create GdkCursor object


呃,DISPLAY?啥?不知道怎麼解決,不過可以把程式碼換成底下這一份,不要以圖形視窗介面顯示,而是儲存到PNG圖檔。

import matplotlib
matplotlib.use('Agg')

import pylab

pylab.figure(1)
pylab.plot([1,2,3,4,5], [1,7,3,5,2])
#pylab.show()
pylab.savefig('a.png')

執行後便會得到圖檔a.png,如下:
耶,成功囉。

有高手留言,需再安裝Cygwin/X,便能以pylab.show()顯示,讓我們試試看囉。再次執行Cygwin安裝程式,選擇套件xorg-server、xinit、xlaunch並安裝。

在Cygwin終端機下輸入指令startx,會看到一個全黑視窗(立刻會跳出),以及出現一堆訊息,然後就沒了。
嗯,試著從程式集選擇Cygwin-X的XWin Server:
看到底下的終端機介面,輸入$ python a.py執行範例程式(使用pylab.show()那一個):
哇,真的出現囉,收工。

參考資料:

4 comments:

  1. 在cygwin command line下打startx,就可以開啟X windows的 console,在該console下執行matplot的disply,就可以即時的顯示圖片了。

    ReplyDelete
    Replies
    1. 謝謝。不過我沒有安裝Cygwin/X,所以沒有startx可用。

      Delete
  2. 若需要X Window,可參考http://x.cygwin.com/docs/ug/setup-cygwin-x-installing.html。

    ReplyDelete
  3. hey 如果要用 pylab.show() 記得要把 matplotlib.use('Agg') 拿掉 不然backend不隊會show 不出來 (我昨天測試的結果)

    ReplyDelete