Engee 文档
Notebook

工程师图库

在这组示例中,我们将展示Engee中最多样化类型的图表的样子,以及通过什么手段实现这样的结果–数据和代码的示例。

正确的时间表类型允许您以非常雄辩但简洁的形式向听众保存或传达必要的信息。 图形从应该存在于内存工作区中的变量中获取信息(_应该在变量window_中可见)。 它们通常从交互式ngscript脚本中显示,紧跟在相应的代码单元格之后。 当然,也有例外。

*Unicode图形也可以在命令行上显示,但是,如果交互式图形可用,则可能仅出于特殊图形设计的需要才需要这样的有限格式。;
*图形可以保存到文件存储中,并从文件浏览器中打开为文件(有时很有用)。

用于显示图形的最简单和最常用的命令是函数 plot() 从图书馆 Plots 来显示图形。

Engee中的绘图库是自动连接的。

与此同时,在Engee/Julia生态系统中还有更多的库用于显示漂亮的图形,其中一些我们将在本演示中查看。:

  • StatsPlots 用于显示复杂的统计图,
  • GMTGeneral Mapping Tools 于显示地理地图。

我们还建议您不要避开允许您创建更丰富和更专业的可视化的库,例如:

  • Makie 用于复杂数据的高质量可视化,
  • Luxor -用于创建矢量二维图形的语言。

当输出库构建了一个图形后,它将其传输到图形环境,这里有选项。:

*环境 gr (默认情况下启用)构建快速,经济和非交互式图形(由命令启用 gr()),可以使用上下文菜单保存

  • plotlyplotlyjs 它们创建了一个交互式画布,可以使用界面按钮对图形进行缩放,旋转和保存(您可以分别使用命令切换到它们 plotly()plotlyjs())

您还可以选择用于显示图形的位图(png)或向量(svg)格式。 通过在命令内部指定 gr/plotly/plotlyjs 论点 fmt=:svg 你会得到一个非常优雅,可扩展的矢量格式的图,但是,如果图上有大量的元素,特别是如果它是交互式的,它的输出将需要更多的资源。 光栅图形是另一回事(fmt=:png). 它们构建得更快,并且在重绘时不需要此类资源。

您将在下面找到完美时间表的其余配方元素。

In [ ]:
Pkg.add(["StatsPlots", "WordCloud", "MeshIO", "ColorSchemes", "Colors", "GMT", "Statistics", "StatsBase", "CSV", "Distributions", "Meshes"])
In [ ]:
gr()
plot([1,2,3], [1,3,7])
Out[0]:

数据分析

基于数据表构建条形图。

In [ ]:
using DataFrames, HTTP, CSV;

# Открыть данные из файла
data = sort( CSV.File( "data/city.csv" ) |> DataFrame, ["population"], rev=true );

# (или) Загрузить данные с сервера
#url = "https://raw.githubusercontent.com/hflabs/city/master/city.csv"
#data = sort( CSV.File( HTTP.get(url).body) |> DataFrame, ["population"], rev=true );

bar( first(data, 8).population, label="Население, чел.", xrotation = 30 )
xticks!( 1:8, first(data, 8).address )
Out[0]:

利用库研究多维数据的相关性 StatsPlots 和功能 corrplor.

In [ ]:
using StatsPlots, DataFrames, LaTeXStrings

M = randn( 1000, 4 )
M[:,2] .+= 0.8sqrt.(abs.(M[:,1])) .- 0.5M[:,3] .+ 5
M[:,3] .-= 0.7M[:,1].^2 .+ 2
corrplot( M, label = [L"$x_i$" for i=1:4],
          xtickfontsize=4, ytickfontsize=6,
          guidefontcolor=:blue, yguidefontsize=15, yguidefontrotation=-45.0 )
Out[0]:

功能 marginalkde 从图书馆 StatsPlots

In [ ]:
using StatsPlots

x = randn(1024)
y = randn(1024)
marginalkde(x, x+y)
Out[0]:
In [ ]:
using DataFrames, Statistics

# Создадим данные
df = DataFrame(Возраст=rand(4), Баланс=rand(4), Должность=rand(4), Зарплата=rand(4))
cols = [:Возраст, :Баланс, :Должность]  # Выберем часть данных
M = cor(Matrix(df[!,cols]))       # Ковариационная матрица

# График
(n,m) = size(M)
heatmap( M, fc=cgrad([:white,:dodgerblue4]), xticks=(1:m,cols), xrot=90, yticks=(1:m,cols), yflip=true, leg=false )
annotate!( [(j, i, text(round(M[i,j],digits=3), 10,"Arial",:black)) for i in 1:n for j in 1:m] )
Out[0]:
1.0 -0.033 -0.388 -0.033 1.0 -0.893 -0.388 -0.893 1.0

通常的直方图:函数 histogram

In [ ]:
using Random
Random.seed!(2018)

x = randn(1000)
y = randn(1000)
z = randn(1000)

histogram(x, bins=20, alpha=0.4, label="A")
histogram!(y, bins=20, alpha=0.6, label="B")
histogram!(z, bins=20, alpha=0.8, label="C")
Out[0]:

二维样本分布图:函数 histogram2d

In [ ]:
x = randn(10^4)
y = randn(10^4)

histogram2d(x, y)
Out[0]:

使用二维直方图的体积图 wireframe

In [ ]:
using StatsBase

x = randn(10^4)
y = randn(10^4)
h = StatsBase.fit( Histogram, (x, y), nbins=20 )

wireframe( midpoints(h.edges[1]), midpoints(h.edges[2]), h.weights )
Out[0]:

结合不同设计的时间表

In [ ]:
using Random

Random.seed!(1)
plot( Plots.fakedata(100, 12),
      layout = 4,
      palette = cgrad.([:grays :blues :heat :lightrainbow]),
      bg_inside = [:orange :pink :darkblue :black],
      seriestype= [:line :scatter :histogram :line] )
Out[0]:

只是不同类型的图表。:

In [ ]:
x = 1:4:250;
y = sin.( 2pi/250 * x );

p1 = plot( x, y, title= "График 1", seriestype=:stem, linewidth=3, legend=false )
p2 = plot( x, y, title= "График 2", seriestype=:scatter, color=:red )
  plot!( p2, x .- 10, 0.9y, seriestype=:scatter, color=:black, markersize=2 )
p3 = plot( x, y, title= "График 3", seriestype=:line, color=:green, legend=false )
p4 = plot( x, y, title= "График 4", seriestype=:steppre, color=:black, leg=false )

plot( p1, p2, p3, p4, layout=(2,2), titlefont=font(7), legendfont=font(7) )
Out[0]:

字云:

In [ ]:
import Pkg; Pkg.add(["WordCloud"], io=devnull);
using WordCloud, HTTP

# Загрузить текст из файла
content = read( open("data/Википедия - Математика.txt", "r"), String )

# Или загрузить данные с сервера
#url = "https://ru.wikipedia.org/wiki/Математика"
#resp = HTTP.request("GET", url, redirect=true)
#content = resp.body |> String |> html2text

stopwords = ["XVII", "того", "frac"];
stopwords = vcat(stopwords, string.(collect(1:100)));

wc = wordcloud( processtext( content, maxnum=100, stopwords=stopwords, minlength=4 ),
    mask=shape(ellipse, 600, 400, color=(0.98, 0.97, 0.99), backgroundcolor=1, backgroundsize=(700, 550)),
    masksize=:original, colors=:seaborn_icefire_gradient, angles=[0] ) |> generate!
paint(wc, "$(@__DIR__)/fromweb.svg")
wc
Out[0]:

动画制作

使用命令创建GIF动画 @animate,它在一个循环中运行一个第三方函数,该循环绘制了150个半径递减的圆圈,透明度增加。 除其他外,您还可以使用格式 mp4.

In [ ]:
@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, "$(@__DIR__)/anim_fps15.gif", fps = 15)
Out[0]:
No description has been provided for this image

旋转对象(几何在STL文件中指定)

In [ ]:
import Pkg; Pkg.add(["Meshes", "MeshIO"], io=devnull);
using Meshes, MeshIO, FileIO
gr();

obj = load( "$(@__DIR__)/data/lion.stl" );

@gif for az in 0:10:359
    p = plot( camera = (az, -20), axis=nothing, border=:none, aspect_ratio=:equal, size=(400,400) )
    for i in obj
        m = Matrix([i[1] i[2] i[3] i[1]])'
        if m[1,1] > 0 plot!( p, m[:,1], m[:,2], m[:,3], lc=:green, label=:none, lw=.4, aspect=:equal )
        else plot!( p, m[:,1], m[:,2], m[:,3], lc=:gray, label=:none, lw=.4, aspect=:equal )
        end
    end
end
[ Info: Saved animation to /user/start/examples/data_analysis/plots_gallery/tmp.gif
Out[0]:
No description has been provided for this image

矩阵和图像的输出

功能 heatmap

In [ ]:
include( "$(@__DIR__)/data/peaks.jl" );

(x, y, z) = peaks()
heatmap(x, y, z)
Out[0]:
In [ ]:
using LaTeXStrings

x = range( -1.3, 1.3, 501 );
y = range( -1.3, 1.3, 501 );

X = repeat( x, outer = [1,501] )
Y = repeat( y', outer = [501,1] )

#C = ones( size(X) ) .* ( 0.360284 + 0.100376*1im );
C = ones( size(X) ) .* ( -0.75 + 0.1im );

Z_max = 1e6; it_max = 50;

Z = Complex.( X, Y );
B = zeros( size(C) );

for k = 1:it_max
    Z = Z.^2 .+ C;
    B = B .+ ( abs.(Z) .< 2 );
end

heatmap( B,
         aspect_ratio = :equal,
         cbar=false,
         axis=([], false),
         color=:jet )
title!( L"Julia Set $(c=0.360284+0.100376i)$" )
Out[0]:

从文件输出插图:库 Images

In [ ]:
using Images

load( "$(@__DIR__)/data/640px-Business_Centre_of_Moscow_2.jpg" )
Out[0]:
No description has been provided for this image

笛卡尔坐标图

由笛卡尔坐标平面上的矢量定义的两个三角函数的输出。

In [ ]:
x = 0:0.1:2pi
y1 = cos.(x)
y2 = sin.(x)

plot(x, y1, c="blue", linewidth=3, label="cos")
plot!(x, y2, c="red", line=:dash, label="sin")
title!("Тригонометрические функции")
xlabel!("Угол (рад)")
ylabel!("sin(x) и cos(x)")

# Отдельной командой установим границы осей
plot!( xlims=(0,2pi), ylims=(-2, 2) )
Out[0]:

填充图形下的区域(参数 fillrange)

In [ ]:
using Distributions

x = range(-3, 3, 100 )
y = pdf.( Normal(0,1), x )

ix = abs.(x) .< 1
plot( x[ix], y[ix], fillrange = zero(x[ix]), fc=:blues, leg=false)
plot!( x, y, grid=false, lc=:black, widen=false )
WARNING: using Distributions.shape in module Main conflicts with an existing identifier.
Out[0]:

填写时间表(area)

In [ ]:
x = 1:10;
areaData = x .* rand(10,5) .* 5;
cur_colors = theme_palette(:default)

plot()
for i in 1:size(areaData,2)
    plot!( areaData[i,:], fillcolor = cur_colors[i], fillrange = 0, fillalpha=.5 )
end
plot!()
Out[0]:

一个累积的时间表,填写

In [ ]:
x = 1:10;
areaData = x .* rand(10,5);
cur_colors = theme_palette(:default)

plot()
for i in size(areaData,2):-1:1
    plot!( sum(areaData[:,1:i], dims=2), fillcolor = cur_colors[i], fillrange = 0, lw=0 )
end
plot!()
Out[0]:

带置信区间的图表(参数 xerryerr)

In [ ]:
using Random
Random.seed!(2018)

f(x) = 2 * x + 1
x = 0:0.1:2
n = length(x)
y = f.(x) + randn(n)

plot( x, y,
      xerr = 0.1 * rand(n),
      yerr = rand(n),
      marker = (:circle, :red) )
Out[0]:

三维图形

In [ ]:
t = 0:pi/100:10pi;
x1 = sin.(1 * t)
y1 = cos.(1 * t)

x2 = sin.(2 * t)
y2 = cos.(2 * t)

plot(
    plot( x1, y1, t, leg=false, lw=2 ),
    plot( x2, y2, t, leg=false, lw=2 )
)
Out[0]:

使用参数组合平滑和逐步图 layout

In [ ]:
x = range( 1, 2pi, length=50 )

plot( x, [sin.(x) sin.(x)],
      seriestype=[:line :step],
      layout = (2, 1) )
Out[0]:

三维参数图

In [ ]:
t = range(0, stop=10, length=1000)

x = cos.(t)
y = sin.(t)
z = sin.(5t)

plot( x, y, z )
Out[0]:

极坐标图

指向形成螺旋的点的箭头(图) quiver)

In [ ]:
cur_colors = theme_palette(:roma);
th = range( 0, 3*pi/2, 10 );
r = range( 5, 20, 10 );
c = collect(1:10)

X = r .* cos.(th)
Y = r .* sin.(th)

quiver( r.*0, r.*0, quiver=(th,r), aspect_ratio=:equal, proj=:polar,
        line_z=repeat(c, inner=4), c=:roma, cbar=false, lw=2 )
Out[0]:

功能 pie

In [ ]:
x = [ "Энтузиасты", "Экспериментаторы", "Ученые" ]
y = [0.4,0.35,0.25]

pie(x, y, title="Кто использует Julia",l = 0.5)
Out[0]:

功能 polar

In [ ]:
θ = range(0, 2π, length=50)
r = 1 .+ cos.(θ) .* sin.(θ).^2

plot(θ, r, proj=:polar, lims=(0,1.5))
Out[0]:

极坐标中的逐步图(图 rose)

In [ ]:
using Random
Random.seed!(2018)

n = 24
R = rand(n+1)
θ = 0:2pi/n:2pi
plot( θ, R, proj=:polar, line=:steppre, lims=(0,1) )
Out[0]:

极坐标图,使用函数设置

In [ ]:
θ = range( 0, 8π, length=1000 )
fr(θ) = sin( 5/4 * θ )

plot( θ, fr.(θ), proj=:polar, lims=(0,1) )
Out[0]:

极坐标中的气泡图

In [ ]:
include( "$(@__DIR__)/data/planetData.jl" );

scatter( angle, distance, ms=diameter, mc = c,
         proj=:polar, legend=false,
         markerstrokewidth=1, markeralpha=.7 )
title!( "Планеты Солнечной системы" )
Out[0]:

离散数据

水平定位条形图(功能 bar)

In [ ]:
ticklabel = string.( collect('а':'м') )
bar( 1:12, orientation=:h, yticks=(1:12, ticklabel), yflip=true )
Out[0]:

条形图 bargroupedbar

In [ ]:
using StatsPlots
include( "$(@__DIR__)/data/BostonTemp.jl" );

plots_id = [1,2,3];

groupedbar( hcat([Temperatures[i,:] for i in plots_id]...),
            xticks=(1:12, Months),
            label = [Years[i] for i in plots_id]',
            color = reshape(palette(:tab10)[1:3], (1,3)) )
Out[0]:

图表 stem (stvol-list)

In [ ]:
x1 = range( 0, 2pi, 50 );
x2 = range( pi, 3pi, 50 );

X = [x1, x2];
Y = [cos.(x1), 0.5.*sin.(x2)];

plot( X, Y, line=:stem, marker=:circle )
Out[0]:

三维立体 stem-图表

In [ ]:
X = repeat( range(0,1,10), outer = [1,10] )
Y = repeat( range(0,1,10)', outer = [10,1] )

Z = exp.(X.+Y)

plot( X, Y, Z, line=:stem, color=:skyblue, markercolor=:white, marker=:circle, leg=false )
Out[0]:

等高线图

圆柱体周围的层流的曲线图。

解析[近似](https://apmr.matelys.com/BasicsMechanics/Fluid/FlowAroundADisk.html 这个函数的计算公式如下:

In [ ]:
include( "$(@__DIR__)/data/flowAroundCylinder.jl" );

(r, theta, x, y, streamline, pressure) = flowAroundCylinder();

plot( x, y, streamline, levels=60, seriestype=:contour,
      xlim = [-5,5], ylim=[-5,5], cbar=false, linewidth=2,
      leg=false, color=:haline )

(xx,yy) = circle( 0, 0, 1 );

plot!( xx, yy, lw=2, lc=:black )
Out[0]:

填充轮廓图(层流流线型圆柱体周围的静压)

In [ ]:
include( "$(@__DIR__)/data/flowAroundCylinder.jl" );

(r, theta, x, y, streamline, pressure) = flowAroundCylinder();
plot( x, y, pressure, seriestype=:contourf, xlim = [-5,5], ylim=[-5,5], cbar=false, linewidth=1, leg=false )

(xx,yy) = circle( 0, 0, 1 );
plot!( xx, yy, lw=2, lc=:black )
Out[0]:

数学函数的等值线图

In [ ]:
# Подготовим данные
y = x = range( -7, 7, step=0.1 )
z = @. sin(x) + cos(y')

Plots.contour( x, y, z, color=:haline )
Out[0]:

表面和网格

参数 seriestype=:surface

In [ ]:
# Подготовим данные
y = x = range( -7, 7, step=0.1 )
z = @. sin(x) + cos(y')

plot( x, y, z, st=:surface, color=:cool )
Out[0]:

参数 seriestype=:wireframe

In [ ]:
# Подготовим данные
y = x = range( -7, 7, step=0.5 )
z = @. sin(x) + cos(y')

plot( x, y, z, st=:wireframe )
Out[0]:

二维函数图

In [ ]:
include( "$(@__DIR__)/data/peaks.jl" );

(x,y,z) = peaks();

plot( x, y, z; levels=20, st=:surface )
Out[0]:

让我们绘制"sombrero"函数的图形。 使用时 gr() 论点 hidesurface 没有使用。 但使用时 plotly() 论点 hidesurface=false 允许您同时显示表面和其上的轮廓图。

In [ ]:
x = y = range( -8, 8, length=41 )
f(x,y) = sin.(sqrt.(x.*x+y.*y))./sqrt.(x.*x+y.*y)

# в gr() этот способ позволяет увидеть график поверхности позади графика линий
p = plot( x, y, f, st=:surface, fillalpha=0.7, cbar=false ) 
plot!( p, x, y, f, st=:wireframe )

# в plotly() есть более удобный синтаксис
#wireframe( x, y, f, hidesurface=false )
Out[0]:

与轮廓图相结合的曲面图

In [ ]:
Pkg.add("Contour")
In [ ]:
using Contour

# Данные
x = range(-3, 3, length=50)
y = range(-3, 3, length=50)
#z = [exp(-(xi^2 + yi^2)/5) * sin(xi^2 + yi^2) for xi in x, yi in y]
z = sin.(2*x) .+ cos.(1.6y')

colors = cgrad(:viridis, 8) # Палитра графика, разделенная на 10 цветов
levels = range(minimum(z), maximum(z), length=10)[2:9] # 8 уровней (от 2го до 9го из 10ти)
contour_data = Contour.contours(x, y, z, levels)  # Контуры с заданными уровнями (много линий в каждом)

# Создаем 3D-график
surface(x, y, z, c=:viridis, legend=false)  # 3D поверхность

# Контурный график на плоскости XY
for cl in Contour.levels(contour_data)
    lvl = level(cl) # значение контура по Z
    for line in lines(cl)
        ys, xs = coordinates(line) # координаты точек текущего сегмента контура
        plot!(xs, ys, zeros(size(xs)) .+ abs(1.1*minimum(z)), c=colors[lvl], lw=2)
    end
end

plot!()
Out[0]:

点图和气泡图

气泡图

In [ ]:
using Random: seed!
seed!(28)

xyz = randn(100, 3)

scatter( xyz[:, 1], xyz[:, 2], marker_z=xyz[:, 3],
         label="Окружности",
         colormap=:plasma, cbar=false,
         markersize=15 * abs.(xyz[:, 3]),
         xlimits=[-3,3], ylimits=[-3,3]
       )
Out[0]:

为每个点分配单独颜色的三维点图

In [ ]:
using Colors, ColorSchemes
cs = ColorScheme([colorant"yellow", colorant"red"])
Out[0]:
No description has been provided for this image
In [ ]:
using CSV, DataFrames

df = DataFrame(CSV.File( "$(@__DIR__)/data/seamount.csv" ))
C = get( cs, df.z, :extrema )

scatter( df.x, df.y, df.z, c=C, leg=false )
Out[0]:

具有用于颜色直方图的虚构空间的三维点图

In [ ]:
using CSV, DataFrames

df = DataFrame(CSV.File( "$(@__DIR__)/data/seamount.csv" ))
cs = cgrad(:thermal)
C = get( cs, df.x, :extrema )

l = @layout [a{0.97w} b]
p1 = scatter( df.x, df.y, df.z, c=C, leg=false )
p2 = heatmap(rand(2,2), clims=(0,10), framestyle=:none, c=cgrad(cs), cbar=true, lims=(-1,0))
plot(p1, p2, layout=l)
Out[0]:

颜色和注释

创建调色板:

In [ ]:
using Images
scheme = rand(RGB, 10)
Out[0]:
No description has been provided for this image

我们使用调色板从随机数中对矩阵进行着色,并将其输出为图像。:

In [ ]:
matrix = rand(1:10, 20, 20)
img = scheme[ matrix ]
Out[0]:
No description has been provided for this image

让我们从带有线条和注释的随机点创建一个图形。:

In [ ]:
x = 1:10
y = rand(10)

# Создадим точечный график
scatter(x, y)

# Нанесем вертивальные и горизонтальные линии на график
vline!( [5], color=:red, linestyle=:dash, label=:none )
hline!( [0.5], color=:blue, linestyle=:dot, label=:none )

# Нанесем аннотации на график (работает только в gr())
annotate!( 8, 0.52, text("Горизонтальная линия", :blue, :right, 8))
annotate!( 4.8, 0.7, text("Вертикальная линия", :red, 8, rotation = 90))
Out[0]: