Julia数据可视化:Plots.jl包的使用

本文详细介绍了Julia语言中的Plots.jl包,涵盖基本绘图操作,如线图、散点图、条形图,以及保存图片的方法。还深入讨论了轴属性、线属性、填充、标记、注释、字体、间距和其他常用属性。此外,文章还展示了布局设置,包括简单和高级布局,并提供了创建和管理动画的步骤。最后,提到了主题选择、颜色处理、显示中文、绘图后端以及绘图系列等其他用法。
摘要由CSDN通过智能技术生成

目录

前言

一、基本绘图

1. 线图

2. 散点图 

3. 条形图

4. 保存图片

5. 综合案例

二、基本属性

0. 常用属性

1. 轴

2. 线

3. 填充

4. 标记

5. 注释

6. 字体

7. 间距

8. 其他

三、布局设置

1. 简单布局

2. 高级布局

四、其他用法

1. 主题选择

2. 颜色

3. 显示中文

4. 绘图后端

5. 绘图系列

6. 脚本绘图

五、绘制动画

参考资料 


前言

本文来源于官方文档的整理,由于英语水平有限,如有错误请在评论区指出。

Plots.jl 实际上并不是一个绘图包!Plots.jl 是一个绘图元包:它是许多不同绘图库的接口。因此,Plots.jl 实际所做的是解释您的命令,然后使用另一个绘图库生成绘图。后台的这个绘图库称为后端。这样做的好处是,这意味着您可以使用 Plots.jl 语法使用许多不同的绘图库。

一、基本绘图

1. 线图

using Plots
x = 0:10; y = sin.(x); # These are the plotting data
plot(x, y)

using Plots
x = 0:10; y1 = sin.(x); y2 = cos.(x)  # 绘图数据 
p1 = plot(x, y1)  # 图1
p2 = plot(x, [y1 y2])  # 图2
p3 = 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")

scatter([1:50], [y1 y2], framestyle=:box,mc=[:blue :green])

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 Plots
p = 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)  # 根据文件后缀名推断文件类型并保存 

5. 综合案例

using Plots

# 准备数据
x=collect(1:20)
y1=rand(20)
y2=rand(20)

# 提前设置各种属性
default(
titlefont = (20, "times"), 
legendfontsize = 18, 
guidefont = (18, :darkgreen), 
tickfont = (12, :orange), 
guide = "x", 
title = "Example",
framestyle = :zerolines, 
yminorgrid = true,
legend = :outertopleft
)

# 进行绘图
p=plot([x x],[y1 y2], label = ["line1" "line"], xlabel = "X", linewidth = 2)

# 保存图片
png(p,"test.png")

二、基本属性

在 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")

在绘图前设置好默认属性

# 设置默认字体
default(
titlefont = (20, "times"), 
legendfontsize = 18, 
guidefont = (18, :darkgreen), 
tickfont = (12, :orange), 
guide = "x", 
framestyle = :zerolines, 
yminorgrid = true)

# 进行绘图
plot([sin, cos], -2π, 2π, label = ["sin(θ)" "cos(θ)"], title = "Trigonometric Functions", xlabel = "θ", linewidth = 2, legend = :outertopleft)

 

0. 常用属性

属性名作用说明
size图片大小默认(600, 400)
dpi分辨率dpi=100,默认100
title标题title = "自定义标题"
titlefontsize标题大小titlefontsize = 10
label图例label= ["图例一" "图例二"],可为空
xlabelX轴xlabel = "自定义x轴名称"
ylabelY轴ylabel = "自定义y轴名称"
xticksX轴刻度xticks = 0:1:10
yticksY轴刻度yticks = 0:10:100
xlimsX轴范围xlims = (0,10)
ylimsY轴范围ylims = (0,100)
guidefontsize轴标签字体大小guidefontsize = 10
grid网格true, false, :x, :y, :z
framestyle轴框架的样式:axes, :box, :semi, :origin, :zerolines, :grid, :none
linewidth线条粗细lw = 4
linecolor, lc线条颜色lc=[:blue :green]
linestyle, ls线条风格:auto, :solid, :dash, :dot, :dashdot, :dashdotdot
markercolor点标志颜色mc=[:orange :purple]
markershape点标志形状:circle, :rect, :star4-8, :diamond, :hexagon, :cross, :xcross, ,  , :vline, :hline, :+, :x等
markersize, ms点标志大小ms=5
fillcolor, fc填充颜色fc = :red
background背景颜色bg = :white
background_outside外部背景色bgoutside = :gray90
fontfamily字体样式serif 、sans-serif、 monospace

annotations

注释

 annotations = (-1, 0,"this is #10", :right, 20, "courier")

smooth是否添加回归线默认false

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. 线

设置与系列:线对应的属性。别名:l。以下是等价的:

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. 填充

设置与系列填充区域对应的属性。别名:farea. 以下是等价的:

plot(y, fill = (0, 0.5, :red))

plot(y,
    fillrange = 0,  #填充范围和y之间的区域
    fillalpha = 0.5,  # 填充区域的不透明度
    fillcolor = :red  # 填充颜色
)

4. 标记

设置与系列标记对应的属性。别名:mmark. 以下是等价的:

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. 注释

可通过 annotations属性 或者 annotate!()函数 向图像添加注释文本。

using Plots

plot(
    1:10,
    annotations = (-1, 0, Plots.text("this is #3", :left,50,:gray,rotation=45.0)),
)

# 两组数据
annotate!([(7,3,"(1,1)"),(3,7,text("hey", 14, :left, :top, :green))])
# 传入一组数据
annotate!([(4, 4, ("More text", 8, 45.0, :bottom, :red))])
# 传入两组数据
annotate!([2,5], [6,3], ["text at (2,6)", "text at (5,3)"])

6. 字体

font()函数 可从一个特征列表中创建一个Font。值可以被指定为参数(通过类型/值来区分)或关键字参数。具体参数如下

  • family: AbstractString. "serif" or "sans-serif" or "monospace"
  • pointsize: Integer. 字体的大小
  • halign: Symbol. 水平排列方式 (:hcenter, :left, or :right)
  • valign: Symbol. 垂直排列方式 (:vcenter, :top, or :bottom)
  • rotation: Real.文本旋转角度,单位为度 (use a non-integer type)
  • color: Colorant or Symbol
julia> font(8)
julia> font(family="serif", halign=:center, rotation=45.0)

7. 间距

plot(
    1:10,
    top_margin=5mm,  # 上间距
    left_margin=10mm,  # 左间距
    right_margin = 30mm,  # 右间距
    bottom_margin = 20mm,  # 下间距   
)

8. 其他

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 的多维数组自定义布局为基础,还可以使用大括号可以实现精确的大小调整,否则子图在可用空间区域进行平均分配。

符号本身(在下面ab示例中)可以是任何有效的标识符,并且没有任何特殊含义。

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)

主题的示例可见:网址,可使用的主题如下表:

:default:orange:wong2:mute
:dark:sand:gruvbox_dark:dao
:ggplot2:solarized:gruvbox_light:dracula
:juno:solarized_light:bright
:lime:wong:vibrant

2. 颜色

有许多颜色属性,用于lines、fills、markers、backgrounds和foregrounds。许多颜色都遵循一个层次结构......例如,lineecolor从seriescolor获得它的值,除非你覆盖了这个值。这使得你可以简单地精确设置你想要的东西,而不需要大量的模板。

支持的类型:

  • 命名颜色,如—— :red,:white等
  • 颜色字符串,如—— "red", "white"等
  • 十六进制颜色,如——"#4472c4"等
  • RGB颜色,如—— "rgb(25,202,173)"等
  • 十进制整数

说明: 

  1. 符号或字符串将被传递给Colors.parse(Colorant, c),所以:red相当于colorant "red"
  2. false或者nothing将被转换为一个不可见的RGBA(0,0,0,0)
  3. 一个整数,它将从系列颜色中挑选出相应的颜色

2.1 命名颜色

支持的命名颜色见 网址,常用的颜色比如:red,blue,blue1, blue2, blue3, ...等等。

2.2 系列颜色

对于系列,有几个属性需要了解。

  • seriescolor: 不直接使用,但定义了系列的基础颜色
  • linecolor: 路径的颜色
  • fillcolor: 填充区域颜色
  • markercolor: 标记和形状的内部颜色
  • markerstrokecolor: 标记和形状的边界/笔触的颜色

seriescolor默认为:auto,并根据其在子图中的索引从color_palette中分配一个颜色。默认情况下,其他颜色 :match。

(一般来说,颜色渐变可以通过*color来设置,而相应的颜色值在渐变中通过*_z来查询。)

这些属性中的每一个都有一个相应的alpha覆盖: seriesalpha、linealpha、fillalpha、markeralpha和markerstrokealpha。它们是可选的,你仍然可以作为Colors.RGBA的一部分给出alpha信息。

 在某些情况下,当用户没有设置一个值时,线条颜色或标记笔画颜色可能被覆盖。

2.3 前景/背景(Foreground/Background)

前景色和背景色的工作原理是相似的。

2.4 用法说明

  • 默认主题下的线条颜色不是CSS定义的,但接近于:steelblue。
  • line_z和marker_z参数将把数据值映射为ColorGradient值。
  • color_palette决定了当seriescolor == :auto时分配的颜色。
    • 如果传递一个颜色的向量,它将强制循环这些颜色。
    • 如果通过一个梯度,它将无限地从该梯度中提取独特的颜色,试图将它们分散开来。

2.5 色彩主题

Plots支持ColorSchemes.jl中的所有色系。它们可以作为梯度或调色板使用,并作为持有其名称的符号传递给cgrad或palette。

plot(
    [x -> sin(x - a) for a in range(0, π / 2, length = 5)], 0, 2π;
    palette = :Dark2_5,
)

2.6 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)

2.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)

3. 显示中文

使用默认字体无法正常显示中文,可设置 fontfamily 属性以显示中文,其中默认后端GR可设置的字体如下所示,详情可见Fonts — GR Framework 0.71.7 documentation

Times RomanHelveticaCourierSymbol
Times ItalicHelvetica ObliqueCourier ObliqueBookman Light
Times BoldHelvetica BoldCourier BoldBookman Light Italic
Times Bold ItalicHelvetica Bold ObliqueCourier Bold ObliqueBookman Demi

4. 绘图后端

当我们开始在上面绘图时,我们的绘图使用了默认的后端 GR。但是,假设我们想要一个不同的绘图后端,它将绘图到一个漂亮的 GUI 或 VS Code 的绘图窗格中。为此,我们需要一个与这些功能兼容的后端。一些常见的后端是 PyPlot 和 Plotly。要安装这些后端,只需使用标准 Julia 安装 ( Pkg.add("BackendPackage"))。我们可以通过使用全小写的后端名称作为函数来专门选择我们正在绘制的后端。

我们可以通过使用全小写的后端名称作为函数来专门选择我们正在绘制的后端。让我们使用 Plotly 和 GR 从上面绘制示例:

x = 1:10; y = rand(10, 2) # 2 columns means two lines
plotlyjs() # Set the backend to Plotly
# This plots into the web browser via Plotly
plot(x, y, title = "This is Plotted using Plotly")

gr() # Set the backend to GR
# This plots using GR
plot(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 .png
savefig(p, "myplot.pdf") # Saves the plot from p as a .pdf vector graphic

 像 GR 这样的一些后端可以保存到矢量图形和 PDF,而像 Plotly 这样的其他后端只能保存到.png。有关后端的更多信息,请参阅后端页面。有关来自各种后端的绘图示例,请参阅示例部分。

5. 绘图系列

在 Plots.jl 中,这些其他绘制系列的方式称为系列类型。支持的所有系列类型见:Supported Attributes · Plots

常见系列类型包含:bar(柱状图), scatter(散点图), scatter3d(3D散点图)

系列类型可以通过seriestype属性进行更改,如下所示:

gr() # We will continue onward using the GR backend
plot(x, y, seriestype = :scatter, title = "My Scatter Plot")

对于每个内置系列类型,都有一个速记函数用于直接调用与系列类型名称匹配的系列类型。它处理与命令相同的属性plot. 例如,我们可以改为使用以下方法绘制散点图:

scatter(x, y, title = "My Scatter Plot")

6. 脚本绘图

在脚本中,Julia 不会进行自动显示(这就是;不需要的原因)。但是,如果我们想在脚本中显示我们的图,这意味着我们只需要添加display调用。例如:

display(plot(x, y))

五、绘制动画

动画是通过以下3个步骤创建:

  • 初始化一个 Animation 对象.
  •  fram(anim) 保存动画的每一帧。
  • gif(anim, filename, fps=15) 将帧转换成gif动画。

(方便的宏@gif和@animate极大地简化了这些代码。短版本的例子见主页,长版本的例子见gr。)

有两个宏为创建动画提供了不同程度的便利。@animate@gif。主要区别在于,@animate将返回一个Animation对象供以后处理,而@gif将创建一个gif动画文件(并在返回到IJulia单元时显示)。

对于简单的、一次性的、你想立即观看的动画,使用@gif。对于任何更复杂的东西,请使用@animate。当你需要完全控制动画的生命周期时,可以构建动画对象(不过通常没有必要)。

using Plots

p = scatter([0,25,75,100],[0,1,-1,0])
@gif for i ∈ 1:100
        x = i
        y = 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)
end

gif(anim, "test.gif")

 

using Plots

@userplot CirclePlot
@recipe function f(cp::CirclePlot)
    x, y, i = cp.args
    n = length(x)
    inds = circshift(1:n, 1 - i)
    linewidth --> range(0, 10, length = n)
    seriesalpha --> range(0, 1, length = n)
    aspect_ratio --> 1
    label --> false
    x[inds], y[inds]
end

n = 150
t = range(0, 2π, length = n)
x = sin.(t)
y = cos.(t)

anim = @animate for i ∈ 1:n
    circleplot(x, y, i)
end
gif(anim, "anim_fps15.gif", fps = 15)

gif(anim, "anim_fps30.gif", fps = 30)

 

 每一个标志只会在 "每N次迭代 "时保存一个框架。

@gif for i ∈ 1:n
    circleplot(x, y, i, line_z = 1:n, cbar = false, framestyle = :zerolines)
end every 5

 when标志只会在 "表达式为真时 "保存一个帧。

n = 400
t = range(0, 2π, length = n)
x = 16sin.(t).^3
y = 13cos.(t) .- 5cos.(2t) .- 2cos.(3t) .- cos.(4t)

@gif for i ∈ 1:n
    circleplot(x, y, i, line_z = 1:n, cbar = false, c = :reds, framestyle = :none)
end when i > 40 && mod1(i, 10) == 5

参考资料 

官方文档链接:https://docs.juliaplots.org/latest/

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: yolov5 plots.py代码解析 yolov5 plots.py是YOLOv5的一个可视化工具,用于绘制训练过程中的损失函数、学习率、精度等指标的变化曲线。下面是对该代码的简要解析: 1. 导入必要的库 ```python import matplotlib.pyplot as plt import numpy as np ``` 2. 定义绘图函数 ```python def plot_results(save_dir='runs/train', show=False): ... ``` 该函数接受一个参数save_dir,表示保存训练结果的目录。如果show为True,则会在绘制完成后显示图像。 3. 读取训练结果 ```python results = np.load(f'{save_dir}/results.npy', allow_pickle=True) ``` 该代码读取保存在save_dir目录下的results.npy文件,该文件含了训练过程中的各种指标的变化情况。 4. 绘制损失函数曲线 ```python plt.plot(results[..., :2], linewidth=4) plt.xlabel('Batch') plt.ylabel('Loss') plt.legend(['Train', 'Val']) ``` 该代码绘制了训练集和验证集的损失函数曲线,其中results[..., :2]表示取出results数组中的前两列数据,即训练集和验证集的损失函数值。 5. 绘制学习率曲线 ```python plt.plot(results[..., 2], linewidth=4) plt.xlabel('Batch') plt.ylabel('Learning rate') ``` 该代码绘制了学习率的变化曲线,其中results[..., 2]表示取出results数组中的第三列数据,即学习率的值。 6. 绘制精度曲线 ```python plt.plot(results[..., 3:5], linewidth=4) plt.xlabel('Batch') plt.ylabel('Accuracy') plt.legend(['Train', 'Val']) ``` 该代码绘制了训练集和验证集的精度曲线,其中results[..., 3:5]表示取出results数组中的第四列和第五列数据,即训练集和验证集的精度值。 7. 显示图像 ```python if show: plt.show() ``` 如果show为True,则会在绘制完成后显示图像。 以上就是yolov5 plots.py代码的简要解析。 ### 回答2: YOLOv5是一个流行的目标检测框架,它具有高效、准确以及易于使用等优点。其中,plots.py是YOLOv5框架中的一个可视化模块,它可以绘制训练过程中的损失函数曲线、精度曲线和PR曲线等。下面,我将对plots.py代码进行分析。 首先,plots.py中引用了matplotlib库,这个库用于创建各种图表,括直方图、饼图、条形图、折线图和散点图等。同时,代码还使用了numpy库来进行数值计算和数组处理。 接下来,代码中定义了一个绘制曲线的函数plot_results,该函数含几个参数,括results文件夹路径、保存图像的文件名、含训练和验证结果的txt文件路径、训练和验证的epoch数目、标签信息等。这个函数具有非常好的灵活性,可以很方便地适应不同的数据集和模型。 然后,代码中定义了一个函数load_results,用于读取保存结果的txt文件,并将其转换为numpy数组格式。该函数返回结果数组和元信息信息(类别标签、数据集名称等)。 在绘制曲线的过程中,代码通过matplotlib的subplot模块将三个曲线绘制在同一个图表中。首先,绘制了训练和验证的loss曲线;然后,绘制了训练和验证的accuracy曲线;最后,绘制了precision-recall曲线。 需要注意的是,plots.py文件中的代码并不是一个完整的Python程序,而是一个函数集合,只有在与其他YOLOv5程序集成时才能够被调用。如果想要使用plots.py中的可视化功能,需要将该函数集成到YOLOv5的源代码中,并在训练和验证过程中调用相应的函数。 ### 回答3: YOLOv5是一个目标检测算法,而其中的plots.py代码是用于绘制检测结果的脚本。本文将对该代码进行详细的解析。 1. 导入所需要的库 ```python import os import os.path as osp import matplotlib.pyplot as plt from matplotlib.colors import hsv_to_rgb from PIL import Image, ExifTags import numpy as np import torch ``` 其中,os,os.path以及PIL库用于读取图片,matplotlib.pyplot用于绘制图像,而numpy和torch库则分别用于图像和网络的处理。 2. 定义绘制函数 ```python def plot_one_box(x, img, color=None, label=None, line_thickness=None): """绘制检测结果框""" tl = line_thickness or round(0.002 * max(img.shape[0:2])) + 1 # line thickness c1, c2 = tuple(x[:2].astype(int)), tuple(x[2:4].astype(int)) cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA) if label: tf = max(tl - 1, 1) # 字体厚度 t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0] c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3 cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled # 写入标签文字 text_color = [255, 255, 255] cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, text_color, thickness=tf, lineType=cv2.LINE_AA) ``` 该函数有五个参数: - x: 检测结果框的坐标。形式为[xmin, ymin, xmax, ymax]。 - img: 要绘制的图像。 - color: 检测结果框线条颜色。默认为None,表示随机生成颜色。 - label: 检测结果的标签。默认为None,表示不绘制标签文字。 - line_thickness: 检测结果框线条的厚度。默认为None,表示根据图片大小自动设置。 该函数首先根据传入的参数绘制检测结果框,并根据标签值计算标签框的大小和位置,最后在标签框内部写入标签文字。 3. 定义绘制函数 ```python def plot_results(img, results, names, classes, colors, line_thickness=None): """绘制检测结果""" # 获取图像长、宽、通道数 img_h, img_w, _ = img.shape # 获取侦测结果 for res in results.pred: if res is not None and len(res): # 提取结果框信息 det_cls = res[:, -1].astype(np.int32) det_conf = res[:, -2] det_bboxes = res[:, :-2].reshape(-1, 4) # 遍历计算并绘制结果框 for cls, bbox, conf in zip(det_cls, det_bboxes, det_conf): cls_name = classes[int(cls)] label = None if names else (cls_name + ' %.2f' % conf) color = colors[int(cls)] if colors is not None else None plot_one_box(bbox, img, color=color, label=label, line_thickness=line_thickness) ``` 该函数有五个参数: - img: 要绘制的图像。 - results: 检测结果,含侦测框、类别和置信度信息。 - names: 标签名称列表。 - classes: 类别名称列表。 - colors: 其它类别对应的颜色。 该函数根据传入的检测结果结果框信息,遍历计算并绘制所有的检测结果框。对于每个框,都可以根据它的类别、边框位置和置信度参数计算它的标签和颜色,并最终绘制该框到原始图像中。 4. 定义程序入口 ```python def main(): # 加载检测结果和图像 img = cv2.imread(opt.img, cv2.IMREAD_COLOR) results = torch.load(opt.result, map_location='cpu') # 在绘图上显示检测结果 plot_results(img, results, opt.names, opt.classes, opt.colors) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 保存绘制结果 if opt.save_path: plt.savefig(opt.save_path) else: plt.show() ``` 该函数定义了程序的入口。程序首先根据传入的参数读取待绘制的检测结果和图像。然后,将检测结果绘制到图像上,并显示图像。最后根据save_path参数,决定是将图像保存到指定路径,还是直接显示在屏幕上。 综上所述,plots.py代码主要含绘制检测结果框和绘制检测结果两个函数,以及程序入口main()函数。通过这些函数,我们可以方便地将YOLOv5检测算法的检测结果可视化并进行保存或显示。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值