Сообщество Engee

Галерея графиков Engee

Автор
avatar-nkapyrinnkapyrin
Notebook

Галерея графиков Engee

В этом наборе примеров мы покажем, как выглядят самые разные виды графиков в Engee, и какими средствами достигается такой результат – примеры данных и кода.

Правильно подобранный тип графика позволяют сохранить или донести до слушателя нужную информацию в очень красноречивой, при этом лаконичной форме. Графики берут информацию из переменных, которые должны существовать в рабочей области памяти (должны быть видны в окне Переменные). Их отображение, как правило, осуществляется из интерактивных скриптов ngscript, сразу после соответствующих ячеек с кодом. Конечно, есть исключения

  • графики в формате Unicode можно отображать и в командной строке, однако при наличии графических интерактивных графиков, такой ограниченный формат может быть нужен разве что для нужд специального графического дизайна;
  • графики можно сохранять в файловое хранилище и открывать как файлы из файлового браузера (иногда это полезно).

Самая простая и часто используемая команда для выводов графиков – функция plot() из библиотеки Plots для вывода графиков.

Библиотека Plots в Engee подключается автоматически.

При этом в экосистеме Engee/Julia есть еще множество библиотек для вывода красивых графиков, некоторые мы рассмотрим в этой демонстрации:

  • StatsPlots для вывода сложных статистических графиков,
  • GMT или General Mapping Tools для вывода географических карт.

Мы также советуем не избегать библиотек, позволяющих создавать гораздо более насыщенные и профессиональные визуализации, например:

  • Makie для очень качественной визуализации сложных данных,
  • Luxor – язык для создания векторной двухмерной графики.

Когда библиотека вывода построила график, она передает его в графическое окружение, и здесь есть варианты:

  • окружение gr (которое включено по умолчанию) строит быстрые, экономные и не интеравтивные графики (включается командой gr()), которые можно сохранить при помощи контекстного меню
  • plotly или plotlyjs создают интерактивное полотно, на котором график можно масштабировать, вращать и сохранять при помощи кнопок интерфейса (переключиться на них можно, соответственно, командами 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]:

Облако слов (wordcloud):

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]:
No description has been provided for this image

Анимация

Создание 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]: