利用Julia和UnicodePlot模塊在終端下繪製科學圖形

蟲蟲安全 發佈 2020-06-08T08:13:03+00:00

我們知道Julia語言是一個面向科學計算的高性能動態高級數據程式語言。Julia擁有豐富的函數庫,支持高精度數字、和分布式並行運行方式。除了大量由Julia編寫的核心函數庫為,還可以使用現有的成熟的C和FORTRAN數值計算庫。

我們知道Julia語言是一個面向科學計算的高性能動態高級數據程式語言。Julia擁有豐富的函數庫,支持高精度數字、和分布式並行運行方式。除了大量由Julia編寫的核心函數庫為,還可以使用現有的成熟的C和FORTRAN數值計算庫。當然大家可能會覺得自己不搞數值計算,沒必要學習Julia。實際上Julia非常易用和接近用戶。今天蟲蟲給大家介紹一個Julia的一個的終端繪圖模塊UnicodePlot,用它來實例演示Julia的魅力。

安裝

下載Julia語言包

Julia安裝非常簡單,直接用官方下載對應包即可,支持Windows、Linux和mac。

由於從官方下載比較慢,可以從國內鏡像站下載(中科大和浙大)

下載後,用bin/julia啟動控制台即可進行各種操作。

本文中主要使用UnicodePlot畫圖,不多介紹julia編程其他內容,如果對其有興趣請參考官方文檔。

添加國內源

為了安裝模塊快速,我們需要添加註冊國內源為下載來源,方法:

在Julia提示符下,輸入]進入julia pkg包管理模式

通過registry add 命令添加國內國內源

安裝UnicodePlot模塊

使用add命令安裝UnicodePlots

基本繪圖方法

我們以簡單的示例開始,首先畫個簡單的點線:

plt = lineplot([-1, 2, 3, 7], [-1, 2, 9, 4], title = "示例1", name = "點線圖", xlabel = "x", ylabel = "y")

還有其他可用的Canvas類型(請參見"低層接口"一節)。在某些情況下(例如列印到文件),使用AsciiCanvas,DotCanvas或BlockCanvas可能會導致更好的結果。

lineplot([-1, 2, 3, 7], [-1, 2, 9, 4], title = "示例2", name = "點線圖ascii模式", xlabel = "x", ylabel = "y", canvas = DotCanvas, border = :ascii)



每個plot圖都有一個以感嘆號結尾的變體變量。

lineplot!(plt, [0, 4, 8], [10, 1, 10], color = :blue, name = "藍色線")


散點圖

也可以畫散點圖,下面示例中我們用隨機函數生成50個 x,y點,然後用scatterplot畫出其分布的散點圖。

scatterplot(randn(50),randn(50),title ="我的散點圖")

直線和曲線畫法

線圖畫法很簡單,用lineplot函數並給出對應的x和y坐標(以數組形式):

lineplot([1, 2, 7], [9, -6, 8], title = "示例4 畫線圖")


也可以畫曲線,只需指定函數和對應的範圍。比如,下面示例畫出來正弦和餘弦曲線:

plt = lineplot([cos, sin], -π/2, 2π,title = "示例5 三角函數曲線")


還可以通過指定截距和斜率來繪製直線,比如給圖5,增加一條直線

lineplot!(plt, -0.5, .2, name = "直線圖"


梯狀圖

我們可以用stairs函數繪製梯狀圖,stairs支持的樣式是:pre和:post

stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], color = :red, style = :post, title = "示例6 梯狀圖")

pre樣式對應的圖如下:

條形圖


條形圖使用barplot,barplot函數接受兩個向量或一個字典,下面我們根據一線城市的人口畫個圖

barplot(["北京", "上海", "深圳", "廣州"], [2.153,2.428,1.344,1.530],title = "人口分布(千萬)")

注意:可以使用關鍵字參數symb指定應用於繪製條形圖的字符。例如symb ="#"

直方圖

同理直方圖繪製使用Histogram函數:

histogram(randn(1000) .* 0.1, nbins = 15, closed = :left,title="示例7 直方圖")


直方圖功能還支持使用參數xscale進行軸縮放。

histogram(randn(1000) .* 0.1, nbins = 15, closed = :left,xscale=log10,title="示例7 直方圖xscale縮放")

箱形圖

箱形圖使用boxplot函數:

boxplot([1,3,3,4,6,10],title="示例8 箱型圖")

箱型圖可以支持分組繪製和顯示:

boxplot(["A組", "B組"], [[1,2,3,4,5], [2,3,4,5,6,7,8,9]], title="示例9 分組箱型圖", xlabel="x")

稀疏模式

可以使用SparseArrays模塊來繪製稀疏矩陣。

using SparseArrays
spy(sprandn(50, 120, .05),title="示例10 稀疏矩陣圖")

密度圖

密度圖表示了數據分布狀況,密度圖繪製使用densityplot函數:


plt = densityplot(randn(1000), randn(1000))
densityplot!(plt, randn(1000) .+ 2, randn(1000) .+ 2,name="示例11 密度圖")


熱度圖

熱度圖使用函數heatmap:

heatmap(repeat(collect(0:10)', outer=(11, 1)), zlabel="z",title="示例12 熱度圖")

熱度圖還支持在使用xoffset和yoffset縮放後使用參數xscale,yscale和軸偏移來縮放軸。可以用colormap參數可用於指定命名或自定義顏色圖。

另外,colorbar和colorbar_border選項可用於啟用/禁用顏色欄並配置其邊框。 zlabel選項和zlabel!方法可用於設置z軸(顏色欄)標籤。

heatmap(collect(0:30) * collect(0:30)', xscale=0.1, yscale=0.1, xoffset=-1.5, colormap=:inferno,title="示例12 熱度圖(帶參數)")

總體參數和方法

參數說明

所有圖都支持以下命名參數的集合(或子集)。

title::String = "": 顯示在圖頂部的文本標題。

name::String = "": 顯示在圖形右邊的注釋。

xlabel::String = "": x軸的說明

ylabel::String = "": y軸的說明

width::Int = 40: 每行繪製寬度字符數。

height::Int = 20: 每行繪製高度行數,不適用於barplot。

xlim::Vector = [0, 1]: x坐標的繪製範圍

ylim::Vector = [0, 1]: y坐標的繪製範圍

margin::Int = 3: 整個圖左側的空字符數。

border::Symbol = :solid:繪圖邊框的樣式。支持:solid,:bold,:dashed,:dotted,:ascii,:corners和:none等值。

padding::Int = 1: 標籤和畫布之間圖的左右空間。

labels::Bool = true: 可以通過設置labels = false來隱藏標籤。

grid::Bool = true: 可用於在原點隱藏網格線

color::Symbol = :auto: 繪圖的顏色。可以是:green,:blue,:red,:yellow,:cyan,:magenta中的任何一個。

canvas::Type = BrailleCanvas: 繪圖所用的畫布類型。

symb::AbstractString = "▪": 僅限於Barplot。指定應用於渲染條形的字符


注意:如果要將列印圖列印到文件中,但是字體存在等寬字體問題,請制定 border = :ascii和canvas = AsciiCanvas(或對於散點圖,canvas = DotCanvas)來解決。

基本函數

title!(plot::Plot, title::String)

對需要顯示在繪圖窗口頂部中心的字符串中添加標題。如果標題為空,則不會繪製標題的整行。

xlabel!(plot::Plot, xlabel::String)

xlabel要顯示在繪圖窗口底部的字符串。如果標題為空,則不會繪製標籤的整行

ylabel!(plot::Plot, xlabel::String)

y標籤顯示在繪圖窗口最左側的字符串。

annotate!負責設置繪圖的所有文字裝飾。它具有兩個功能:

annotate!(plot::Plot, where::Symbol, value::String)

where可以指定:tl(左上)、:t(左上)、: tr(右上)、:bl(左下)、:b(右下)、:br(下) -right)、: l(左)、:r(右)

annotate!(plot::Plot, where::Symbol, row::Int, value::String)

where可以指定 :l(左)、:r(右)

row 可以指定在1到畫布的字符行數之間

底層實現:Canvas對象

在幕後進行所有繁重工作的主要結構是Canvas的子類型。Canvas畫布是用於柵格化繪圖的圖形對象。基本上,它使用Unicode字符表示像素。

下面是一個簡單的示例說明:

canvas = BrailleCanvas(40, 10, # 列數和行數(字符)
origin_x = 0., origin_y = 0., # 虛擬空間中的位置 width = 1., height = 1.) # 虛擬空間大小
lines!(canvas, 0., 0., 1., 1., :blue) # 虛擬空間
points!(canvas, rand(50), rand(50), :red) # 虛擬空間
lines!(canvas, 0., 1., .5, 0., :yellow) # 虛擬空間
pixel!(canvas, 5, 8, :red) # pixel空間

基本畫布

可以分別使用nrows(canvas)和ncols(canvas)訪問畫布的高度和寬度(以字符為單位)。您可以將這些功能與printrow結合使用,以將畫布嵌入到所需的任何位置。例如,printrow(STDOUT,canvas,3)將畫布的第三字符行寫入標準輸出。


如所見,當一個字符代表多個像素時出現的一個問題是很難分配顏色。這是因為字符的每個"像素"可能屬於不同的顏色組(每個字符只能具有一種顏色)。該軟體包使用整個組的顏色混合來處理此問題。

混合色彩

目前,已實現以下類型的Canvas畫布:

BrailleCanvas:這種類型的畫布可能是Unicode繪圖解析度最高的一種。它實際上使用盲文符號的Unicode字符作為像素。這有效地將每個字符轉換為8個像素,可以使用二進位操作分別對其進行操作。

BlockCanvas:此畫布也是基於Unicode的。它具有BrailleCanvas解析度的一半。與BrailleCanvas相比,像素之間沒有可見的間距。該畫布有效地將每個字符轉換為4個像素,可以使用二進位操作分別對其進行操作。

HeatmapCanvas:此畫布也是基於Unicode的。它具有BlockCanvas解析度的一半。該畫布使用前景和背景終端顏色將每個字符有效地轉換為2個顏色像素。這樣,畫布的行數是顯示的y坐標數的一半。

AsciiCanvas和DotCanvas:這兩個畫布僅使用標準ASCII字符進行繪製。自然,它看起來不像基於Unicode的那樣好。但是,在某些情況下,它可能會產生更好的結果。將圖列印到文件中就是其中一種情況。

DensityCanvas:與BrailleCanvas不同,密度畫布不會簡單地將"像素"標記為已設置。相反,它會為每個字符增加一個計數器,以跟蹤該字符中繪製的像素的頻率。畫布與跟蹤最大頻率的變量一起可以繪製數據點的密度。

BarplotGraphics:此圖形區域很特別,因為它不支持任何像素操作。它實際上是沒有裝飾物但數字的條形圖。它僅支持一種方法加法!允許用戶向圖形對象添加其他條。

總結

UnicodePlot包給了我們在Julia REPL下繪製精美圖形的方法。UnicodePlot的函數豐富,可操作性和擴展性強,繪製的圖形精美,可以做為一種廣普的終端圖形繪製解決方案。

關鍵字: