我们知道Julia语言是一个面向科学计算的高性能动态高级数据编程语言。Julia拥有丰富的函数库,支持高精度数字、和分布式并行运行方式。除了大量由Julia编写的核心函数库为,还可以使用现有的成熟的C和FORTRAN数值计算库。当然大家可能会觉得自己不搞数值计算,没必要学习Julia。实际上Julia非常易用和接近用户。今天虫虫给大家介绍一个Julia的一个的终端绘图模块UnicodePlot,用它来实例演示Julia的魅力。

安装

下载Julia语言包

Julia安装非常简单,直接用官方下载对应包即可,支持Windows、Linux和mac。

由于从官方下载比较慢,可以从国内镜像站下载(中科大和浙大)

下载后,用bin/julia启动控制台即可进行各种操作。

本文中主要使用UnicodePlot画图,不多介绍julia编程其他内容,如果对其有兴趣请参考官方文档。

添加国内源

为了安装模块快速,我们需要添加注册国内源为下载来源,方法:

在Julia提示符下,输入]进入julia包模式

通过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的函数丰富,可操作性和扩展性强,绘制的图形精美,可以做为一种广普的终端图形绘制解决方案。

相关文章