目录
前言
一、基本绘图
1. 线图
2. 散点图
3. 条形图
3.1 基本条形图
3.2 堆积条形图
4. 保存图片
二、基本属性
0. 常用属性
1. 轴
2. 线(line)
3. 填充(fill)
4. 标记
5.其他
三、布局设置
1. 简单布局
2. 高级布局
四、其他设置
1. 主题选择
五、绘制动画
六、其他用法
1. 绘图后端
2. 绘图系列
3. 脚本绘图
4. 颜色(colors)
4.1 命名颜色
4.2 系列颜色
4.3前景/背景(Foreground/Background)
4.4 用法说明
4.5 色彩主题
参考资料
前言
本文来源于官方文档的整理,由于英语水平有限,如有错误请在评论区指出。
Plots.jl 实际上并不是一个绘图包!Plots.jl 是一个绘图元包:它是许多不同绘图库的接口。因此,Plots.jl 实际所做的是解释您的命令,然后使用另一个绘图库生成绘图。后台的这个绘图库称为后端。这样做的好处是,这意味着您可以使用 Plots.jl 语法使用许多不同的绘图库。
一、基本绘图
1. 线图
using Plotsx = 0:10; y = sin.(x); # These are the plotting dataplot(x, y)
using Plotsx = 0:10; y1 = sin.(x); y2 = cos.(x) # 绘图数据 p1 = plot(x, y1) # 图1p2 = plot(x, [y1 y2]) # 图2p3 = plot!(x, x.+1) # 图3,在图2基础上增加图形plot(p1,p2,p3;layout = 3, label=["a" "b" "c"],title=["figure1" "figure2" "figure3"])
2. 散点图
scatter(x, y, title = "My Scatter Plot")
3. 条形图
3.1 基本条形图
p1 = bar([1,2,3])p2 = bar([1,2,3];bar_width=0.5) # 设置条的宽度p3 = bar([1,2,3];fc=[1,2,3],ms =10) # 填充颜色p4 = bar([1,2,3];fc=[1,2,3],lc=:white) # 填充颜色及边的颜色plot(p1,p2,p3,p4;layout = 4, label=["a" "b" "c" "d"],title=["figure1" "figure2" "figure3" "figure4"])
3.2 堆积条形图
p1 = bar([3 2 1;6 5 4]) # 后面的值覆盖在前面的值之上p2 = bar([3 2 1;6 5 4];dir=:h ) # 改变图的方向p3 = bar([3 2 1;6 5 4],axiscolor=:red) # 坐标轴颜色p4 = bar([3 2 1;6 5 4],bordercolor=:white) # 边的颜色plot(p1,p2,p3,p4;layout = 4, label=["a" "b" "c" "d"],title=["figure1" "figure2" "figure3" "figure4"])
4. 保存图片
using Plotsp = plot(rand(100))png(p, filename) # 将绘图保存为png文件pdf(p, filename) # 将绘图保存为pdf文件svg(p, filename) # 将绘图保存为svg文件eps(p, filename) # 将绘图保存为eps文件ps(p, filename) # 将绘图保存为ps文件json(p, filename) # 将绘图保存为json文件tex(p, filename) # 将绘图保存为tex文件txt(p, filename) # 将绘图保存为txt文件save(p,filename) # 根据文件后缀名推断文件类型并保存
二、基本属性
在 Plots.jl 中,绘图的修饰符称为attributes,这些都记录在属性页。Plots.jl 数据与属性遵循的规则是:位置参数是数据,关键字参数是属性。例如:plot(x,y,attribute=value)。
从属性页面中看到,linewidth
可以用于(或其别名lw
)增加线宽,使用命令label
更改图例的标签,并使用title
添加标题。让我们将其应用于我们之前的情节:
x = 1:10; y = rand(10, 2) # 2列意味着两条线plot(x, y, title = "Two Lines", label = ["Line 1" "Line 2"], lw = 3)
每个属性也可以通过使用修饰函数改变绘图来应用。例如,利用函数xlabel!
为 x 轴添加标签
xlabel!("My x label")
0. 常用属性
1. 轴
将设置元组传递到xaxis参数将快速定义xlabel、xlims、xticks、xscale、xflip和xtickfont。以下是等效的:
plot(y, xaxis = ("my label", (0,10), 0:0.5:10, :log, :flip, font(20, "Courier")))plot(y,xlabel = "my label", # x轴的标签xlims = (0,10), # x轴的取值范围xticks = 0:0.5:10, # x轴的刻度xscale = :log, # x轴的尺度类型xflip = true, # 是否翻转图形xtickfont = font(20, "Courier") # x轴刻度的字号及字体)plot!(xticks = ([0:π:3*π;], ["0", "\\pi", "2\\pi"])) # 将元组传递给xticks,改变刻度和标签的位置yticks!([-1:1:1;], ["min", "zero", "max"]) # 更改yticks
2. 线(line)
设置与系列:线对应的属性。别名:。以下是等价的:
plot(y, line = (:steppre, :dot, :arrow, 0.5, 4, :red))plot(y,seriestype = :steppre, # 线的类型linestyle = :dot, # 线的样式arrow = :arrow, # 线末尾的形状箭头linealpha = 0.5, # 线的不透明度linewidth = 4, # 线的宽度linecolor = :red # 线的颜色)
3. 填充(fill)
设置与系列填充区域对应的属性。别名:f
,area
.以下是等价的:
plot(y, fill = (0, 0.5, :red))plot(y,fillrange = 0, #填充范围和y之间的区域fillalpha = 0.5, # 填充区域的不透明度fillcolor = :red # 填充颜色)
4. 标记
设置与系列标记对应的属性。别名:m
,mark
.以下是等价的:
scatter(y, marker = (:hexagon, 20, 0.6, :green, stroke(3, 0.2, :black, :dot)))scatter(y,markershape = :hexagon, # 标记形状markersize = 20, # 标记大小markeralpha = 0.6, # 标记的不透明度markercolor = :green, # 标记的颜色markerstrokewidth = 3, # 标记边界宽度markerstrokealpha = 0.2, # 标记边界的不透明度markerstrokecolor = :black, # 标记边界的颜色markerstrokestyle = :dot # 标记边界的样式)
5.其他
scatter(y, thickness_scaling = 2) # 将字体大小和线宽增加2倍# 如果后端不支持这个,请使用函数`scalefontsizes(2)`,它可以缩放默认字体scatter(y, ticks=:native) # 让后端自行计算刻度线。# 使用交互式后端进行鼠标缩放时,这将非常有用scatter(rand(100), smooth=true) # 在图中添加回归线
三、布局设置
Plot: 整个图形/窗口。Subplot: 一个子图包含:标题(title)、轴(axes)、色栏(colorbar)、图例(legend)和图形区域(plot area)。Axis: 子图的一个轴,包含轴向导(标签)、记号标签和记号标记。Plot Area: 数据所示的一个子图的部分……包含了序列、网格线等。Series: 一种特定的数据可视化。( 例如 : a line或一组标记 )1. 简单布局
1.1将整数传递给layout,使其能够自动计算许多子图的网格大小:
# 创建2x2网格,并将4个系列中的每个映射到其中一个子图plot(rand(100, 4), layout = 4)
1.2将元组传递给layout以创建该大小的网格:
# 创建一个4x1网格,并将4个系列的每个映射到其中一个子图plot(rand(100, 4), layout = (4, 1))
1.3使用grid(...) 构造函数创建更复杂的网格布局:
# heights数组为各子图的高度plot(rand(100, 4), layout = grid(4, 1, heights=[0.1 ,0.4, 0.4, 0.1]))
1.4添加标题(title)及标签(label)
plot(rand(100,4), layout = 4, label=["a" "b" "c" "d"],title=["1" "2" "3" "4"])
1.5逐步添加子图
将多个图组合成一个图,需将保存先前图的变量传递给plot
函数:
l = @layout [a ; b c]p1 = plot(...)p2 = plot(...)p3 = plot(...)plot(p1, p2, p3, layout = l)
2. 高级布局
@layout
宏是定义复杂布局最简单的方法,使用 Julia 的多维数组自定义布局为基础,还可以使用大括号可以实现精确的大小调整,否则子图在可用空间区域进行平均分配。
符号本身(在下面a
的b
示例中)可以是任何有效的标识符,并且没有任何特殊含义。
l = @layout [a{0.3w} [grid(3,3) b{0.2h}]]plot(rand(10, 11),layout = l, legend = false, seriestype = [:bar :scatter :path],title = ["($i)" for j in 1:1, i in 1:11], titleloc = :right, titlefont = font(8))
四、其他设置
1. 主题选择
通过函数theme(主题样式名)可设置置图形的主题。例如:
theme(:default)
主题的示例可见:网址,可使用的主题如下表:
五、绘制动画
动画是通过以下3个步骤创建:
初始化一个Animation
对象.用fram(anim)保存动画的每一帧。用gif(anim, filename, fps=15)将帧转换成gif动画。
(方便的宏@gif和@animate极大地简化了这些代码。短版本的例子见主页,长版本的例子见gr。)
有两个宏为创建动画提供了不同程度的便利。@animate和@gif。主要区别在于,@animate将返回一个Animation对象供以后处理,而@gif将创建一个gif动画文件(并在返回到IJulia单元时显示)。
对于简单的、一次性的、你想立即观看的动画,使用@gif。对于任何更复杂的东西,请使用@animate。当你需要完全控制动画的生命周期时,可以构建动画对象(不过通常没有必要)。
using Plotsp = scatter([0,25,75,100],[0,1,-1,0])@gif for i ∈ 1:100x = iy = sin((i/100)*2pi)scatter!([x],[y],c = :reds,legend = false)end
l = @layout([[a; b] c])p = plot(plot([sin, cos], 1, ylims = (-1, 1), leg = false), scatter([atan, cos], 1, ylims = (-1, 1.5), leg = false), plot(log, 1, ylims = (0, 2), leg = false), layout = l, xlims = (1, 2π))anim = Animation()for x = range(1, stop = 2π, length = 20)plot(push!(p, x, Float64[sin(x), cos(x), atan(x), cos(x), log(x)]))frame(anim)endgif(anim, "test.gif")
using Plots@userplot CirclePlot@recipe function f(cp::CirclePlot)x, y, i = cp.argsn = length(x)inds = circshift(1:n, 1 - i)linewidth --> range(0, 10, length = n)seriesalpha --> range(0, 1, length = n)aspect_ratio --> 1label --> falsex[inds], y[inds]endn = 150t = range(0, 2π, length = n)x = sin.(t)y = cos.(t)anim = @animate for i ∈ 1:ncircleplot(x, y, i)endgif(anim, "anim_fps15.gif", fps = 15)
gif(anim, "anim_fps30.gif", fps = 30)
每一个标志只会在 "每N次迭代 "时保存一个框架。
@gif for i ∈ 1:ncircleplot(x, y, i, line_z = 1:n, cbar = false, framestyle = :zerolines)end every 5
when标志只会在 "表达式为真时 "保存一个帧。
n = 400t = range(0, 2π, length = n)x = 16sin.(t).^3y = 13cos.(t) .- 5cos.(2t) .- 2cos.(3t) .- cos.(4t)@gif for i ∈ 1:ncircleplot(x, y, i, line_z = 1:n, cbar = false, c = :reds, framestyle = :none)end when i > 40 && mod1(i, 10) == 5
六、其他用法
1. 绘图后端
当我们开始在上面绘图时,我们的绘图使用了默认的后端 GR。但是,假设我们想要一个不同的绘图后端,它将绘图到一个漂亮的 GUI 或 VS Code 的绘图窗格中。为此,我们需要一个与这些功能兼容的后端。一些常见的后端是 PyPlot 和 Plotly。要安装这些后端,只需使用标准 Julia 安装 (Pkg.add("BackendPackage")
)。我们可以通过使用全小写的后端名称作为函数来专门选择我们正在绘制的后端。
我们可以通过使用全小写的后端名称作为函数来专门选择我们正在绘制的后端。让我们使用 Plotly 和 GR 从上面绘制示例:
x = 1:10; y = rand(10, 2) # 2 columns means two linesplotlyjs() # Set the backend to Plotly# This plots into the web browser via Plotlyplot(x, y, title = "This is Plotted using Plotly")
gr() # Set the backend to GR# This plots using GRplot(x, y, title = "This is Plotted using GR")
如果您在 VS Code 或 Juno 中,第一个绘图命令将导致绘图在绘图窗格中打开。如果您在 REPL 中,绘图命令将在浏览器窗口中打开。无论如何,您始终可以使用该gui()
命令打开 GUI。
每个绘图后端都有非常不同的感觉。有些具有交互性,有些更快并且可以处理大量数据点,有些可以绘制 3D 绘图。保存绘图由savefig
命令完成。举个例子:
savefig("myplot.png") # Saves the CURRENT_PLOT as a .pngsavefig(p, "myplot.pdf") # Saves the plot from p as a .pdf vector graphic
像 GR 这样的一些后端可以保存到矢量图形和 PDF,而像 Plotly 这样的其他后端只能保存到.png
。有关后端的更多信息,请参阅后端页面。有关来自各种后端的绘图示例,请参阅示例部分。
2. 绘图系列
在 Plots.jl 中,这些其他绘制系列的方式称为系列类型。支持的所有系列类型见:Supported Attributes · Plots
常见系列类型包含:bar(柱状图), scatter(散点图),scatter3d(3D散点图)
系列类型可以通过seriestype
属性进行更改,如下所示:
gr() # We will continue onward using the GR backendplot(x, y, seriestype = :scatter, title = "My Scatter Plot")
对于每个内置系列类型,都有一个速记函数用于直接调用与系列类型名称匹配的系列类型。它处理与命令相同的属性plot
.例如,我们可以改为使用以下方法绘制散点图:
scatter(x, y, title = "My Scatter Plot")
3. 脚本绘图
在脚本中,Julia 不会进行自动显示(这就是;
不需要的原因)。但是,如果我们想在脚本中显示我们的图,这意味着我们只需要添加display
调用。例如:
display(plot(x, y))
4. 颜色(colors)
有许多颜色属性,用于lines、fills、markers、backgrounds和foregrounds。许多颜色都遵循一个层次结构......例如,lineecolor从seriescolor获得它的值,除非你覆盖了这个值。这使得你可以简单地精确设置你想要的东西,而不需要大量的模板。
支持的类型:
命名颜色,如—— :red,:white等颜色字符串,如—— "red", "white"等十六进制颜色,如——"#4472c4"等RGB颜色,如——"rgb(25,202,173)"等十进制整数
说明:
符号或字符串将被传递给Colors.parse(Colorant, c),所以:red相当于colorant "red"false或者nothing将被转换为一个不可见的RGBA(0,0,0,0)一个整数,它将从系列颜色中挑选出相应的颜色
4.1 命名颜色
支持的命名颜色见 网址,常用的颜色比如:red,blue,blue1, blue2, blue3, ...等等。
4.2 系列颜色
对于系列,有几个属性需要了解。
seriescolor: 不直接使用,但定义了系列的基础颜色linecolor: 路径的颜色fillcolor: 填充区域颜色markercolor:标记和形状的内部颜色markerstrokecolor:标记和形状的边界/笔触的颜色
seriescolor默认为:auto,并根据其在子图中的索引从color_palette中分配一个颜色。默认情况下,其他颜色 :match。
(一般来说,颜色渐变可以通过*color来设置,而相应的颜色值在渐变中通过*_z来查询。)
这些属性中的每一个都有一个相应的alpha覆盖: seriesalpha、linealpha、fillalpha、markeralpha和markerstrokealpha。它们是可选的,你仍然可以作为Colors.RGBA的一部分给出alpha信息。
在某些情况下,当用户没有设置一个值时,线条颜色或标记笔画颜色可能被覆盖。
4.3前景/背景(Foreground/Background)
前景色和背景色的工作原理是相似的。
4.4 用法说明
默认主题下的线条颜色不是CSS定义的,但接近于:steelblue。line_z和marker_z参数将把数据值映射为ColorGradient值。color_palette决定了当seriescolor == :auto时分配的颜色。 如果传递一个颜色的向量,它将强制循环这些颜色。如果通过一个梯度,它将无限地从该梯度中提取独特的颜色,试图将它们分散开来。4.5 色彩主题
Plots支持ColorSchemes.jl中的所有色系。它们可以作为梯度或调色板使用,并作为持有其名称的符号传递给cgrad或palette。
plot([x -> sin(x - a) for a in range(0, π / 2, length = 5)], 0, 2π;palette = :Dark2_5,)
ColorPalette(调色板)
Plots从传递给color_palette属性的调色板中自动为系列选择颜色。该属性接受colorscheme名称的符号或ColorPalette对象。调色板可以用palette(cs, [n])构建,其中cs可以是一个符号、一个颜色向量、一个ColorScheme、ColorPalette或ColorGradient。可选参数n决定从cs中选择多少种颜色。
palette(:tab10)
palette([:purple, :green], 7)
palette([RGB(0,0,0), RGB(1,1,1)], 7)
ColorGradient(颜色梯度)
对于heatmap、surface、contour或line_z、marker_z和line_z Plots.jl从一个ColorGradient中选择颜色。如果没有指定,将使用默认的ColorGradient :inferno。通过向seriescolor属性传递一个colorscheme名称的符号,可以选择不同的梯度。对于更详细的配置,颜色属性也接受一个ColorGradient对象。颜色梯度可以通过以下方式构建
cgrad(cs, [z], alpha = nothing, rev = false, scale = nothing, categorical = nothing)
其中cs可以是一个符号、一个颜色向量、一个ColorScheme、ColorPalette或ColorGradient。
cgrad(:acton)
你可以传递一个介于0和1之间的数值向量作为第二个参数来指定颜色转换的位置。
cgrad([:orange, :blue], [0.1, 0.3, 0.8])
在rev = true的情况下,colorscheme的颜色被反转。
设置categorical = true会返回一个CategoricalColorGradient,它只从一个离散的颜色集合中选择,而不连续插值。可选的第二个参数决定了要从颜色表中选择多少种颜色。它们会沿着colorscheme的颜色均匀分布。
cgrad(:matter, 5, categorical = true)
参考资料
官方文档链接:/latest/