Построение блоков
Линии
Экземпляр Plot
будет иметь вектор линий (trace
). Каждая из них должна быть подтипом AbstractTrace
.
PlotlyJS.jl определяет один такой подтип:
mutable struct GenericTrace{T <: AbstractDict{Symbol,Any}} <: AbstractTrace
fields::T
end
fields
представляет собой объект AbstractDict, который сопоставляет атрибуты линий с их значениями.
Мы создаем эту оболочку вокруг Dict, чтобы предоставить удобный синтаксис, как описано ниже.
Рассмотрим пример. Предположим, требуется создать следующий объект JSON:
{
"type": "scatter",
"x": [1, 2, 3, 4, 5],
"y": [1, 6, 3, 6, 1],
"mode": "markers+text",
"name": "Team A",
"text": ["A-1", "A-2", "A-3", "A-4", "A-5"],
"textposition": "top center",
"textfont": {
"family": "Raleway, sans-serif"
},
"marker": { "size": 12 }
}
Это можно сделать, как показано ниже:
fields = Dict{Symbol,Any}(:type => "scatter",
:x => [1, 2, 3, 4, 5],
:y => [1, 6, 3, 6, 1],
:mode => "markers+text",
:name => "Team A",
:text => ["A-1", "A-2", "A-3", "A-4", "A-5"],
:textposition => "top center",
:textfont => Dict(:family => "Raleway, sans-serif"),
:marker => Dict(:size => 12))
GenericTrace("scatter", fields)
scatter with fields marker, mode, name, text, textfont, textposition, type, x, and y
Более удобный синтаксис имеет следующий вид:
t1 = scatter(;x=[1, 2, 3, 4, 5],
y=[1, 6, 3, 6, 1],
mode="markers+text",
name="Team A",
text=["A-1", "A-2", "A-3", "A-4", "A-5"],
textposition="top center",
textfont_family="Raleway, sans-serif",
marker_size=12)
scatter with fields marker, mode, name, text, textfont, textposition, type, x, and y
Обратите внимание на несколько моментов:
-
Линия
type
стала именем функции. Аналогичный метод существует для всех типов линий plotly.js. -
Все остальные атрибуты линии были заданы с помощью именованных аргументов. Это позволяет не вводить префикс символа (
:
) и стрелки (=>
), которые были необходимы при построенииDict
. -
Вложенные атрибуты можно задавать, используя символы подчеркивания. Обратите внимание, что JSON
"marker": { "size": 12 }
был написан какmarker_size=12
.
Чтобы убедиться, что это действительно эквивалентный JSON, можно вывести его содержимое (обратите внимание, что порядок атрибутов разный, но содержимое идентично):
print(JSON.json(t1, 2))
{
"textfont": {
"family": "Raleway, sans-serif"
},
"mode": "markers+text",
"marker": {
"size": 12
},
"textposition": "top center",
"y": [
1,
6,
3,
6,
1
],
"type": "scatter",
"name": "Team A",
"text": [
"A-1",
"A-2",
"A-3",
"A-4",
"A-5"
],
"x": [
1,
2,
3,
4,
5
]
}
Доступ к атрибутам
Если нужно извлечь конкретный атрибут, это можно сделать с помощью getindex(t1, :attrname)
или синтаксического приема t1[:attrname]
. Обратите внимание, что в вызове getindex
могут использоваться как символы, так и строки:
julia> t1["marker"]
Dict{Any, Any} with 1 entry:
:size => 12
julia> t1[:marker]
Dict{Any, Any} with 1 entry:
:size => 12
Для доступа к вложенному свойству используется parent.child
.
julia> t1["textfont.family"]
"Raleway, sans-serif"
Задание дополнительных атрибутов
Можно задать дополнительные атрибуты. Предположим, нужно задать для marker.color
красный цвет. Мы можем сделать это с помощью вызова setindex!(t1, "red", :marker_color)
или, что эквивалентно, t1["marker_color"] = "red"
:
julia> t1["marker_color"] = "red"
"red"
julia> println(JSON.json(t1, 2))
{
"textfont": {
"family": "Raleway, sans-serif"
},
"mode": "markers+text",
"marker": {
"color": "red",
"size": 12
},
"textposition": "top center",
"y": [
1,
6,
3,
6,
1
],
"type": "scatter",
"name": "Team A",
"text": [
"A-1",
"A-2",
"A-3",
"A-4",
"A-5"
],
"x": [
1,
2,
3,
4,
5
]
}
Обратите внимание, что атрибут color
был корректно добавлен внутри существующего атрибута marker
(наряду с size
), а не заменен атрибутом marker
.
Этот синтаксис можно использовать и для добавления совершенно новых вложенных атрибутов:
julia> t1["line_width"] = 5
5
julia> println(JSON.json(t1, 2))
{
"textfont": {
"family": "Raleway, sans-serif"
},
"mode": "markers+text",
"marker": {
"color": "red",
"size": 12
},
"line": {
"width": 5
},
"textposition": "top center",
"y": [
1,
6,
3,
6,
1
],
"type": "scatter",
"name": "Team A",
"text": [
"A-1",
"A-2",
"A-3",
"A-4",
"A-5"
],
"x": [
1,
2,
3,
4,
5
]
}
Макеты
Тип Layout
определяется следующим образом:
mutable struct Layout{T <: AbstractDict{Symbol,Any}} <: AbstractLayout
fields::T
subplots::_Maybe{Subplots}
end
Для построения макета можно использовать тот же удобный синтаксис именованных аргументов, который применялся для линий:
julia> l = Layout(;title="Penguins",
xaxis_range=[0, 42.0], xaxis_title="fish",
yaxis_title="Weight",
xaxis_showgrid=true, yaxis_showgrid=true,
legend_y=1.15, legend_x=0.7)
layout with fields legend, margin, template, title, xaxis, and yaxis
julia> println(JSON.json(l, 2))
{
"xaxis": {
"showgrid": true,
"range": [
0.0,
42.0
],
"title": {
"text": "fish"
}
},
"template": {
"data": {
"scatterpolargl": [
{
"type": "scatterpolargl",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"carpet": [
{
"baxis": {
"gridcolor": "white",
"endlinecolor": "#2a3f5f",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f",
"linecolor": "white"
},
"type": "carpet",
"aaxis": {
"gridcolor": "white",
"endlinecolor": "#2a3f5f",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f",
"linecolor": "white"
}
}
],
"scatterpolar": [
{
"type": "scatterpolar",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"parcoords": [
{
"line": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
},
"type": "parcoords"
}
],
"scatter": [
{
"type": "scatter",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"histogram2dcontour": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "histogram2dcontour",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"contour": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "contour",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"scattercarpet": [
{
"type": "scattercarpet",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"mesh3d": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "mesh3d"
}
],
"surface": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "surface",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"scattermapbox": [
{
"type": "scattermapbox",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"scattergeo": [
{
"type": "scattergeo",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"histogram": [
{
"type": "histogram",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"pie": [
{
"type": "pie",
"automargin": true
}
],
"choropleth": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "choropleth"
}
],
"heatmapgl": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "heatmapgl",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"bar": [
{
"type": "bar",
"error_y": {
"color": "#2a3f5f"
},
"error_x": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
}
}
],
"heatmap": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "heatmap",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"contourcarpet": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "contourcarpet"
}
],
"table": [
{
"type": "table",
"header": {
"line": {
"color": "white"
},
"fill": {
"color": "#C8D4E3"
}
},
"cells": {
"line": {
"color": "white"
},
"fill": {
"color": "#EBF0F8"
}
}
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
},
"type": "scatter3d",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"scattergl": [
{
"type": "scattergl",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"histogram2d": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "histogram2d",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"scatterternary": [
{
"type": "scatterternary",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"barpolar": [
{
"type": "barpolar",
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
}
}
]
},
"layout": {
"xaxis": {
"gridcolor": "white",
"zerolinewidth": 2,
"title": {
"standoff": 15
},
"ticks": "",
"zerolinecolor": "white",
"automargin": true,
"linecolor": "white"
},
"hovermode": "closest",
"paper_bgcolor": "white",
"geo": {
"showlakes": true,
"showland": true,
"landcolor": "#E5ECF6",
"bgcolor": "white",
"subunitcolor": "white",
"lakecolor": "white"
},
"colorscale": {
"sequential": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
],
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequentialminus": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
},
"yaxis": {
"gridcolor": "white",
"zerolinewidth": 2,
"title": {
"standoff": 15
},
"ticks": "",
"zerolinecolor": "white",
"automargin": true,
"linecolor": "white"
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"font": {
"color": "#2a3f5f"
},
"annotationdefaults": {
"arrowhead": 0,
"arrowwidth": 1,
"arrowcolor": "#2a3f5f"
},
"plot_bgcolor": "#E5ECF6",
"title": {
"x": 0.05
},
"coloraxis": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
},
"hoverlabel": {
"align": "left"
},
"mapbox": {
"style": "light"
},
"polar": {
"angularaxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
}
},
"autotypenumbers": "strict",
"ternary": {
"aaxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
},
"baxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
}
},
"scene": {
"xaxis": {
"gridcolor": "white",
"gridwidth": 2,
"backgroundcolor": "#E5ECF6",
"ticks": "",
"showbackground": true,
"zerolinecolor": "white",
"linecolor": "white"
},
"zaxis": {
"gridcolor": "white",
"gridwidth": 2,
"backgroundcolor": "#E5ECF6",
"ticks": "",
"showbackground": true,
"zerolinecolor": "white",
"linecolor": "white"
},
"yaxis": {
"gridcolor": "white",
"gridwidth": 2,
"backgroundcolor": "#E5ECF6",
"ticks": "",
"showbackground": true,
"zerolinecolor": "white",
"linecolor": "white"
}
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
]
}
},
"legend": {
"y": 1.15,
"x": 0.7
},
"margin": {
"l": 50,
"b": 50,
"r": 50,
"t": 60
},
"title": "Penguins",
"yaxis": {
"showgrid": true,
"title": {
"text": "Weight"
}
}
}
attr
Существует специальная функция attr
, которая позволяет применять ту же процедуру использования ключевых слов, которую мы видели в функциях trace и layout, но ко вложенным атрибутам. Давайте вернемся к предыдущему примеру, но будем использовать attr
для построения xaxis
и legend
:
julia> l2 = Layout(;title="Penguins",
xaxis=attr(range=[0, 42.0], title="fish", showgrid=true),
yaxis_title="Weight", yaxis_showgrid=true,
legend=attr(x=0.7, y=1.15))
layout with fields legend, margin, template, title, xaxis, and yaxis
julia> println(JSON.json(l2, 2))
{
"xaxis": {
"showgrid": true,
"range": [
0.0,
42.0
],
"title": "fish"
},
"template": {
"data": {
"scatterpolargl": [
{
"type": "scatterpolargl",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"carpet": [
{
"baxis": {
"gridcolor": "white",
"endlinecolor": "#2a3f5f",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f",
"linecolor": "white"
},
"type": "carpet",
"aaxis": {
"gridcolor": "white",
"endlinecolor": "#2a3f5f",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f",
"linecolor": "white"
}
}
],
"scatterpolar": [
{
"type": "scatterpolar",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"parcoords": [
{
"line": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
},
"type": "parcoords"
}
],
"scatter": [
{
"type": "scatter",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"histogram2dcontour": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "histogram2dcontour",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"contour": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "contour",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"scattercarpet": [
{
"type": "scattercarpet",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"mesh3d": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "mesh3d"
}
],
"surface": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "surface",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"scattermapbox": [
{
"type": "scattermapbox",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"scattergeo": [
{
"type": "scattergeo",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"histogram": [
{
"type": "histogram",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"pie": [
{
"type": "pie",
"automargin": true
}
],
"choropleth": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "choropleth"
}
],
"heatmapgl": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "heatmapgl",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"bar": [
{
"type": "bar",
"error_y": {
"color": "#2a3f5f"
},
"error_x": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
}
}
],
"heatmap": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "heatmap",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"contourcarpet": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "contourcarpet"
}
],
"table": [
{
"type": "table",
"header": {
"line": {
"color": "white"
},
"fill": {
"color": "#C8D4E3"
}
},
"cells": {
"line": {
"color": "white"
},
"fill": {
"color": "#EBF0F8"
}
}
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
},
"type": "scatter3d",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"scattergl": [
{
"type": "scattergl",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"histogram2d": [
{
"colorbar": {
"ticks": "",
"outlinewidth": 0
},
"type": "histogram2d",
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"scatterternary": [
{
"type": "scatterternary",
"marker": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
}
}
],
"barpolar": [
{
"type": "barpolar",
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
}
}
]
},
"layout": {
"xaxis": {
"gridcolor": "white",
"zerolinewidth": 2,
"title": {
"standoff": 15
},
"ticks": "",
"zerolinecolor": "white",
"automargin": true,
"linecolor": "white"
},
"hovermode": "closest",
"paper_bgcolor": "white",
"geo": {
"showlakes": true,
"showland": true,
"landcolor": "#E5ECF6",
"bgcolor": "white",
"subunitcolor": "white",
"lakecolor": "white"
},
"colorscale": {
"sequential": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
],
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequentialminus": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
},
"yaxis": {
"gridcolor": "white",
"zerolinewidth": 2,
"title": {
"standoff": 15
},
"ticks": "",
"zerolinecolor": "white",
"automargin": true,
"linecolor": "white"
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"font": {
"color": "#2a3f5f"
},
"annotationdefaults": {
"arrowhead": 0,
"arrowwidth": 1,
"arrowcolor": "#2a3f5f"
},
"plot_bgcolor": "#E5ECF6",
"title": {
"x": 0.05
},
"coloraxis": {
"colorbar": {
"ticks": "",
"outlinewidth": 0
}
},
"hoverlabel": {
"align": "left"
},
"mapbox": {
"style": "light"
},
"polar": {
"angularaxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
}
},
"autotypenumbers": "strict",
"ternary": {
"aaxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
},
"baxis": {
"gridcolor": "white",
"ticks": "",
"linecolor": "white"
}
},
"scene": {
"xaxis": {
"gridcolor": "white",
"gridwidth": 2,
"backgroundcolor": "#E5ECF6",
"ticks": "",
"showbackground": true,
"zerolinecolor": "white",
"linecolor": "white"
},
"zaxis": {
"gridcolor": "white",
"gridwidth": 2,
"backgroundcolor": "#E5ECF6",
"ticks": "",
"showbackground": true,
"zerolinecolor": "white",
"linecolor": "white"
},
"yaxis": {
"gridcolor": "white",
"gridwidth": 2,
"backgroundcolor": "#E5ECF6",
"ticks": "",
"showbackground": true,
"zerolinecolor": "white",
"linecolor": "white"
}
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
]
}
},
"legend": {
"y": 1.15,
"x": 0.7
},
"margin": {
"l": 50,
"b": 50,
"r": 50,
"t": 60
},
"title": "Penguins",
"yaxis": {
"showgrid": true,
"title": {
"text": "Weight"
}
}
}
Обратите внимание, что мы получили точно такой же вывод, как и раньше, но нам не пришлось вручную строить Dict
или добавлять xaxis_
или legend_
в качестве префиксов к нескольким аргументам.
Использование DataFrame
Новая возможность в версии 0.6.0 |
Вы можете создавать линии, используя столбцы любого подтипа для типа AbstractDataFrame
(например, типа DataFrame
из DataFrames.jl).
Для демонстрации этой функциональности загрузим известный набор данных ирисов:
julia> using DataFrames, RDatasets
julia> iris = dataset("datasets", "iris");
julia> first(iris, 10)
10×5 DataFrame
│ Row │ SepalLength │ SepalWidth │ PetalLength │ PetalWidth │ Species │
│ │ Float64 │ Float64 │ Float64 │ Float64 │ Cat… │
├─────┼─────────────┼────────────┼─────────────┼────────────┼─────────┤
│ 1 │ 5.1 │ 3.5 │ 1.4 │ 0.2 │ setosa │
│ 2 │ 4.9 │ 3.0 │ 1.4 │ 0.2 │ setosa │
│ 3 │ 4.7 │ 3.2 │ 1.3 │ 0.2 │ setosa │
│ 4 │ 4.6 │ 3.1 │ 1.5 │ 0.2 │ setosa │
│ 5 │ 5.0 │ 3.6 │ 1.4 │ 0.2 │ setosa │
│ 6 │ 5.4 │ 3.9 │ 1.7 │ 0.4 │ setosa │
│ 7 │ 4.6 │ 3.4 │ 1.4 │ 0.3 │ setosa │
│ 8 │ 5.0 │ 3.4 │ 1.5 │ 0.2 │ setosa │
│ 9 │ 4.4 │ 2.9 │ 1.4 │ 0.2 │ setosa │
│ 10 │ 4.9 │ 3.1 │ 1.5 │ 0.1 │ setosa │
Предположим, что необходимо построить линию рассеяния, в которой столбец SepalLength
является переменной x, а столбец SepalWidth
— переменной y. Для этого вызывается
julia> my_trace = scatter(iris, x=:SepalLength, y=:SepalWidth, marker_color=:red)
scatter with fields marker, type, x, and y
julia> [my_trace[:x][1:5] my_trace[:y][1:5]]
5×2 Array{Float64,2}:
5.1 3.5
4.9 3.0
4.7 3.2
4.6 3.1
5.0 3.6
julia> my_trace[:marker_color]
:red
Как это работает? Основное правило заключается в том, что если значением любого именованного аргумента является символ Julia (т. е. созданный с помощью :something
), то функция, создающая линию, проверяет, является ли этот символ одним из имен столбцов в DataFrame. Если это так, она извлекает столбец из DataFrame и задает его в качестве значения для именованного аргумента. В противном случае символ передается напрямую.
В приведенном выше примере при конструировании my_trace
в качестве значения именованного аргумента x
был задан символ :SepalLength
. Он совпал с именем столбца iris
, поэтому этот столбец был извлечен и заменен :SepalLength
в качестве значения аргумента x
. То же самое относится к y
и SepalWidth
.
Однако при задании marker_color=:red
мы обнаружили, что :red
не является одним из имен столбцов, поэтому значением именованного аргумента marker_color
осталось :red
.
Интерфейс DataFrame становится более полезным при построении целых графиков. Дополнительные сведения см. в разделе о вспомогательных методах.
Новая возможность в версии 0.9.0 |
Начиная с версии 0.9.0 можно создавать группы линий, используя API DataFrame. Лучше всего это можно понять на примере, поэтому давайте посмотрим, как это работает:
julia> iris = dataset("datasets", "iris");
julia> unique(iris[:Species])
3-element Array{String,1}:
"setosa"
"versicolor"
"virginica"
julia> traces = scatter(
iris, group=:Species, x=:SepalLength, y=:SepalWidth, mode="markers", marker_size=8
)
3-element Array{GenericTrace,1}:
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:x => [5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9 … 5.0, 4.5, 4.4, 5.0, 5.1, 4.8, 5.1, 4.6, 5.3, 5.0],:mode => "markers",:y => [3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1 … 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],:type => "scatter",:name => CategoricalValue{String,UInt8} "setosa",:marker => Dict{Any,Any}(:size => 8)))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:x => [7.0, 6.4, 6.9, 5.5, 6.5, 5.7, 6.3, 4.9, 6.6, 5.2 … 5.5, 6.1, 5.8, 5.0, 5.6, 5.7, 5.7, 6.2, 5.1, 5.7],:mode => "markers",:y => [3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7 … 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],:type => "scatter",:name => CategoricalValue{String,UInt8} "versicolor",:marker => Dict{Any,Any}(:size => 8)))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:x => [6.3, 5.8, 7.1, 6.3, 6.5, 7.6, 4.9, 7.3, 6.7, 7.2 … 6.7, 6.9, 5.8, 6.8, 6.7, 6.7, 6.3, 6.5, 6.2, 5.9],:mode => "markers",:y => [3.3, 2.7, 3.0, 2.9, 3.0, 3.0, 2.5, 2.9, 2.5, 3.6 … 3.1, 3.1, 2.7, 3.2, 3.3, 3.0, 2.5, 3.0, 3.4, 3.0],:type => "scatter",:name => CategoricalValue{String,UInt8} "virginica",:marker => Dict{Any,Any}(:size => 8)))
julia> [t[:name] for t in traces]
3-element CategoricalArray{String,1,UInt8}:
"setosa"
"versicolor"
"virginica"
Обратите внимание, что в DataFrame iris
есть три компонента Species
, и при передаче group=:Species
в scatter
мы получили три линии.
Можно передать Vector{Symbol}
в качестве группы, чтобы разбить данные о значении на несколько столбцов:
julia> tips = dataset("reshape2", "tips");
julia> unique(tips[:Sex])
2-element Array{String,1}:
"Female"
"Male"
julia> unique(tips[:Day])
4-element Array{String,1}:
"Sun"
"Sat"
"Thur"
"Fri"
julia> traces = violin(tips, group=[:Sex, :Day], x=:TotalBill, orientation="h")
8-element Array{GenericTrace,1}:
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Female, Fri)",:orientation => "h",:x => [5.75, 16.32, 22.75, 11.35, 15.38, 13.42, 15.98, 16.27, 10.09]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Female, Sat)",:orientation => "h",:x => [20.29, 15.77, 19.65, 15.06, 20.69, 16.93, 26.41, 16.45, 3.07, 17.07 … 10.59, 10.63, 12.76, 13.27, 28.17, 12.9, 30.14, 22.12, 35.83, 27.18]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Female, Sun)",:orientation => "h",:x => [16.99, 24.59, 35.26, 14.83, 10.33, 16.97, 10.29, 34.81, 25.71, 17.31, 29.85, 25.0, 13.39, 16.21, 17.51, 9.6, 20.9, 18.15]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Female, Thur)",:orientation => "h",:x => [10.07, 34.83, 10.65, 12.43, 24.08, 13.42, 12.48, 29.8, 14.52, 11.38 … 18.64, 11.87, 19.81, 43.11, 13.0, 12.74, 13.0, 16.4, 16.47, 18.78]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Male, Fri)",:orientation => "h",:x => [28.97, 22.49, 40.17, 27.28, 12.03, 21.01, 12.46, 12.16, 8.58, 13.42]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Male, Sat)",:orientation => "h",:x => [20.65, 17.92, 39.42, 19.82, 17.81, 13.37, 12.69, 21.7, 9.55, 18.35 … 15.69, 11.61, 10.77, 15.53, 10.07, 12.6, 32.83, 29.03, 22.67, 17.82]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Male, Sun)",:orientation => "h",:x => [10.34, 21.01, 23.68, 25.29, 8.77, 26.88, 15.04, 14.78, 10.27, 15.42 … 34.63, 34.65, 23.33, 45.35, 23.17, 40.55, 20.69, 30.46, 23.1, 15.69]))
GenericTrace{Dict{Symbol,Any}}(Dict{Symbol,Any}(:type => "violin",:name => "(Male, Thur)",:orientation => "h",:x => [27.2, 22.76, 17.29, 19.44, 16.66, 32.68, 15.98, 13.03, 18.28, 24.71 … 9.78, 7.51, 28.44, 15.48, 16.58, 7.56, 10.34, 13.51, 18.71, 20.53]))
julia> [t[:name] for t in traces]
8-element Array{String,1}:
"(Female, Fri)"
"(Female, Sat)"
"(Female, Sun)"
"(Female, Thur)"
"(Male, Fri)"
"(Male, Sat)"
"(Male, Sun)"
"(Male, Thur)"
Также в версии 0.9.0 при использовании API DataFrame разрешено передавать функцию в качестве значения именованного аргумента. При построении каждой линии значение будет заменено путем вызова функции для любого используемого DataFrame. При использовании в сочетании с аргументом group
это позволяет быстро вычислять специфические для группы атрибуты линии.
Дополнительные сведения см. в docstring для GenericTrace
и пример violin_side_by_side
на странице примеров Violin.
Грани
Новая возможность в PlotlyBase версии 0.6.5 (PlotlyJS версии 0.16.4) |
При построении графика DataFrame
(назовем его df
) именованные аргументы facet_row
и facet_col
позволяют создать матрицу подграфиков. Строки этой матрицы соответствуют unique(df[:facet_row])
, где :facet_row
— это заполнитель для фактического значения, переданного в качестве аргумента facet_row
. Аналогично, столбцы матрицы подграфиков поступают из unique(df[:facet_col])
.
Каждый подграфик будет иметь одинаковую структуру, определяемую именованными аргументами, переданными plot
, но одновременно будет показывать данные только для одного значения facet_row
и facet_col
.
Ниже приведен соответствующий пример.
julia> using PlotlyJS, CSV, DataFrames
julia> df = dataset(DataFrame, "tips")
244×7 DataFrame
Row │ total_bill tip sex smoker day time size
│ Float64 Float64 String7 String3 String7 String7 Int64
─────┼────────────────────────────────────────────────────────────────
1 │ 16.99 1.01 Female No Sun Dinner 2
2 │ 10.34 1.66 Male No Sun Dinner 3
3 │ 21.01 3.5 Male No Sun Dinner 3
4 │ 23.68 3.31 Male No Sun Dinner 2
5 │ 24.59 3.61 Female No Sun Dinner 4
6 │ 25.29 4.71 Male No Sun Dinner 4
7 │ 8.77 2.0 Male No Sun Dinner 2
8 │ 26.88 3.12 Male No Sun Dinner 4
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
238 │ 32.83 1.17 Male Yes Sat Dinner 2
239 │ 35.83 4.67 Female No Sat Dinner 3
240 │ 29.03 5.92 Male No Sat Dinner 3
241 │ 27.18 2.0 Female Yes Sat Dinner 2
242 │ 22.67 2.0 Male Yes Sat Dinner 2
243 │ 17.82 1.75 Male No Sat Dinner 2
244 │ 18.78 3.0 Female No Thur Dinner 2
229 rows omitted
julia> plot(
df, x=:total_bill, y=:tip, xbingroyp="x", ybingroup="y", kind="histogram2d",
facet_row=:sex, facet_col=:smoker
)
data: [
"histogram2d with fields type, x, xaxis, xbingroyp, y, yaxis, and ybingroup",
"histogram2d with fields type, x, xaxis, xbingroyp, y, yaxis, and ybingroup",
"histogram2d with fields type, x, xaxis, xbingroyp, y, yaxis, and ybingroup",
"histogram2d with fields type, x, xaxis, xbingroyp, y, yaxis, and ybingroup"
]
layout: "layout with fields annotations, legend, margin, template, xaxis, xaxis2, xaxis3, xaxis4, yaxis, yaxis2, yaxis3, and yaxis4"