The Figure Data Structure in R
The structure of a figure - data, traces and layout explained in R
New to Plotly?
Plotly is a free and open-source graphing library for R. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.
Overview
Plotly's R graphing library makes interactive, publication-quality graphs. Examples of how to make line plots, scatter plots, area charts, bar charts, error bars, box plots, histograms, heatmaps, subplots, multiple-axes, and 3D (WebGL based) charts. Plotly.R is free and open source and you can view the source, report issues or contribute on GitHub. The rendering process uses the Plotly.js JavaScript library under the hood. Figures can be represented in R either as lists or as instances of the plotly
, and are serialized as text in JavaScript Object Notation (JSON) before being passed to Plotly.js.
Viewing the underlying data structure for any plotly
object, can be done via dput(fig)
.
library(plotly)
fig <- plot_ly() %>%
add_lines(x = c("a","b","c"), y = c(1,3,2))%>%
layout(title="sample figure", xaxis = list(title = 'x'), yaxis = list(title = 'y'), plot_bgcolor = "#c7daec")
str(fig$x)
## List of 7
## $ visdat :List of 1
## ..$ 30d6bf3e7cd:function ()
## $ cur_data : chr "30d6bf3e7cd"
## $ attrs :List of 2
## ..$ 30d6bf3e7cd:List of 3
## .. ..$ alpha_stroke: num 1
## .. ..$ sizes : num [1:2] 10 100
## .. ..$ spans : num [1:2] 1 20
## ..$ 30d6bf3e7cd:List of 8
## .. ..$ alpha_stroke: num 1
## .. ..$ sizes : num [1:2] 10 100
## .. ..$ spans : num [1:2] 1 20
## .. ..$ x : chr [1:3] "a" "b" "c"
## .. ..$ y : num [1:3] 1 3 2
## .. ..$ type : chr "scatter"
## .. ..$ mode : chr "lines"
## .. ..$ inherit : logi TRUE
## .. ..- attr(*, "class")= chr [1:2] "plotly_line" "list"
## $ layout :List of 3
## ..$ width : NULL
## ..$ height: NULL
## ..$ margin:List of 4
## .. ..$ b: num 40
## .. ..$ l: num 60
## .. ..$ t: num 25
## .. ..$ r: num 10
## $ source : chr "A"
## $ config :List of 2
## ..$ modeBarButtonsToAdd: chr [1:2] "hoverclosest" "hovercompare"
## ..$ showSendToCloud : logi FALSE
## $ layoutAttrs:List of 1
## ..$ 30d6bf3e7cd:List of 4
## .. ..$ title : chr "sample figure"
## .. ..$ xaxis :List of 1
## .. .. ..$ title: chr "x"
## .. ..$ yaxis :List of 1
## .. .. ..$ title: chr "y"
## .. ..$ plot_bgcolor: chr "#c7daec"
## - attr(*, "TOJSON_FUNC")=function (x, ...)
fig
Accessing figure structures in Dash
Dash for R is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.
Learn about how to install Dash for R at https://dashr.plot.ly/installation.
Everywhere in this page that you see fig, you can display the same figure in a Dash for R application by passing it to the figure argument.
library(dash)
library(dashCoreComponents)
library(dashHtmlComponents)
library(plotly)
fig <- plot_ly() %>%
add_lines(x = c("a","b","c"), y = c(1,3,2))%>%
layout(title="sample figure")
app <- Dash$new()
app$layout(
htmlDiv(
list(
dccGraph(id = 'graph', figure=fig),
htmlPre(
id='structure',
style = list(border = 'thin lightgrey solid',
overflowY = 'scroll',
height = '275px')
)
)
)
)
app$callback(
output(id = 'structure', property='children'),
params=list(input(id='graph', property='figure')),
function(fig_json) {
plotly_json <- function(p, ...) {
plotly:::to_JSON(plotly_build(p), ...)
}
jfig <- plotly_json(fig, pretty = TRUE)
return(jfig)
})
After executing this code, give app$run_server() in the console to start the dash.
Figures as Trees of Attributes
Plotly.js supports inputs adhering to a well-defined schema, whose overall architecture is explained in this page and which is exhaustively documented in the Figure Reference (which is itself generated from a machine-readable JSON representation of the schema). Figures are represented as trees with named nodes called "attributes".
Attributes are referred to in text and in the Figure Reference by their names. For example "layout = list(width = NULL)"
refers to the attribute whose key is "width"
inside a list which is the value associated with a key "layout"
at the root of the figure.
When manipulating a plotly
object, attributes can be set directly using R object attributes e.g. fig.layout.title.font.family="Open Sans"
or using fig %>% layout(title = list(font = 'Open Sans')).
When building a figure, it is not necessary to populate every attribute of every object. At render-time, the JavaScript layer will compute default values for each required unspecified attribute, depending upon the ones that are specified, as documented in the Figure Reference. An example of this would be layout.xaxis.range
, which may be specified explicitly, but if not will be computed based on the range of x
values for every trace linked to that axis. The JavaScript layer will ignore unknown attributes or malformed values, although the plotly
module provides R-side validation for attribute values.
The Top-Level data
Attribute
The first of the three top-level attributes of a figure is data
, whose value must be a list referred to as "traces".
- Each trace has one of more than 40 possible types (see below for a list organized by subplot type, including e.g.
scatter
,bar
,pie
,surface
,choropleth
etc), and represents a set of related graphical marks in a figure. Each trace must have atype
attribute which defines the other allowable attributes. - Each trace is drawn on a single subplot whose type must be compatible with the trace's type, or is its own subplot (see below).
- Traces may have a single legend entry, with the exception of pie and funnelarea traces (see below).
- Certain trace types support continuous color, with an associated colorbar, which can be controlled by attributes either within the trace, or within the layout when using the coloraxis attribute.
The Top-Level layout
Attribute
The second of the three top-level attributes of a figure is layout
, whose value is referred to in text as "the layout" and must be a list, containing attributes that control positioning and configuration of non-data-related parts of the figure such as:
- Dimensions and margins, which define the bounds of "paper coordinates" (see below)
- Title and legend (positionable in container and/or paper coordinates)
- Color axes and associated color bars (positionable in paper coordinates)
- Subplots of various types on which can be drawn multiple traces and which are positioned in paper coordinates:
xaxis
,yaxis
,xaxis2
,yaxis3
etc: X and Y cartesian axes, the intersections of which are cartesian subplotsscene
,scene2
,scene3
etc: 3d scene subplotsternary
,ternary2
,ternary3
,polar
,polar2
,polar3
,geo
,geo2
,geo3
,mapbox
,mapbox2
,mabox3
etc: ternary, polar, geo or mapbox subplots
- Non-data marks which can be positioned in paper coordinates, or in data coordinates linked to 2d cartesian subplots:
- Controls which can be positioned in paper coordinates and which can trigger Plotly.js functions when interacted with by a user:
updatemenus
: single buttons, toggles and dropdown menussliders
: slider controls
The Top-Level frames
Attribute
The third of the three top-level attributes of a figure is frames
, whose value must be a list that define sequential frames in an animated plot. Each frame contains its own data attribute as well as other parameters. Animations are usually triggered and controlled via controls defined in layout.sliders and/or layout.updatemenus
Positioning With Paper, Container Coordinates, or Axis Domain Coordinates
Various figure components configured within the layout of the figure support positioning attributes named x
or y
, whose values may be specified in "paper coordinates" (sometimes referred to as "plot fractions" or "normalized coordinates"). Examples include layout.xaxis.domain
or layout.legend.x
or layout.annotation.x
.
Positioning in paper coordinates is not done in absolute pixel terms, but rather in terms relative to a coordinate system defined with an origin (0,0)
at (layout.margin.l, layout.margin.b)
and a point (1,1)
at (layout.width-layout.margin.r, layout.height-layout.margin.t)
(note: layout.margin
values are pixel values, as are layout.width
and layout.height
). Paper coordinate values less than 0 or greater than 1 are permitted, and refer to areas within the plot margins.
To position an object in "paper" coordinates, the corresponding axis reference
is set to "paper"
. For instance a shape's xref
attribute would be set to
"paper"
so that the x
value of the shape refers to its position in paper
coordinates.
Note that the contents of the layout.margin
attribute are by default computed based on the position and dimensions of certain items like the title or legend, and may be made dependent on the position and dimensions of tick labels as well when setting the layout.xaxis.automargin
attribute to True
. This has the effect of automatically increasing the margin values and therefore shrinking the physical area defined between the (0,0)
and (1,1)
points. Positioning certain items at paper coordinates less than 0 or greater than 1 will also trigger this behavior. The layout.width
and layout.height
, however, are taken as givens, so a figure will never grow or shrink based on its contents.
The figure title may be positioned using "container coordinates" which have (0,0)
and (1,1)
anchored at the bottom-left and top-right of the figure, respectively, and therefore are independent of the values of layout.margin.
Furthermore, shapes, annotations, and images can be placed relative to an axis's
domain so that, for instance, an x
value of 0.5
would place the object
halfway along the x-axis, regardless of the domain as specified in the
layout.xaxis.domain
attribute. This behavior can be specified by adding
' domain'
to the axis reference in the axis referencing attribute of the object.
For example, setting yref = 'y2 domain'
for a shape will refer to the length
and position of the axis named y2
.
2D Cartesian Trace Types and Subplots
The most commonly-used kind of subplot is a two-dimensional Cartesian subplot. Traces compatible with these subplots support xaxis
and yaxis
attributes whose values must refer to corresponding objects in the layout portion of the figure. For example, if xaxis="x"
, and yaxis="y"
(which is the default) then this trace is drawn on the subplot at the intersection of the axes configured under layout.xaxis
and layout.yaxis
, but if xaxis="x2"
and yaxis="y3"
then the trace is drawn at the intersection of the axes configured under layout.xaxis2
and layout.yaxis3
. Note that attributes such as layout.xaxis
and layout.xaxis2
etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of different types can be drawn on the same subplot.
X- and Y-axes support the type
attribute, which enables them to represent continuous values (type="linear"
, type="log"
), temporal values (type="date"
) or categorical values (type="category"
, type="multicategory
). Axes can also be overlaid on top of one another to create dual-axis or multiple-axis charts. 2-d cartesian subplots lend themselves very well to creating "small multiples" figures, also known as facet or trellis plots.
The following trace types are compatible with 2d-cartesian subplots via the xaxis
and yaxis
attributes:
- scatter-like trace types:
scatter
andscattergl
, which can be used to draw scatter plots, line plots and curves, bubble charts, dot plots and filled areas and also support error bars bar
,funnel
,waterfall
: bar-like trace types which can also be used to draw timelines and Gantt chartshistogram
: an aggregating bar-like trace typebox
andviolin
: 1-dimensional distribution-like trace typesheatmap
andcontour
: matrix trace typeshistogram2d
andhistogram2dcontour
: 2-dimensional distribution-like density trace typesohlc
andcandlestick
: stock-like trace typescarpet
: a special trace type for building carpet plots, in that other traces can use as subplots (see below)splom
: multi-dimensional scatter plots which implicitly refer to many 2-d cartesian subplots at once.
3D, Polar and Ternary Trace Types and Subplots
Beyond 2D cartesian subplots, figures can include three-dimensional cartesian subplots, polar subplots and ternary subplots. The following trace types support attributes named scene
, polar
or ternary
, whose values must refer to corresponding objects in the layout portion of the figure i.e. ternary="ternary2"
etc. Note that attributes such as layout.scene
and layout.ternary2
etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of a compatible type can be placed on the same subplot.
The following trace types are compatible with 3D subplots via the scene
attribute, which contains special camera controls:
scatter3d
, which can be used to draw individual markers, lines and curvessurface
andmesh
: 3d surface trace typescone
andstreamtube
: 3d vector field trace typesvolume
andisosurface
: 3d volume trace types
The following trace types are compatible with polar subplots via the polar
attribute:
- scatter-like trace types:
scatterpolar
andscatterpolargl
, which can be used to draw individual markers, curves and filled areas (i.e. radar or spider charts) barpolar
The following trace types are compatible with ternary subplots via the ternary
attribute:
scatterternary
, which can be used to draw individual markers, curves and filled areas
Map Trace Types and Subplots
Figures can include two different types of map subplots: geo subplots for outline maps and mapbox subplots for tile maps. The following trace types support attributes named geo
or mapbox
, whose values must refer to corresponding objects in the layout i.e. geo="geo2"
etc. Note that attributes such as layout.geo2
and layout.mapbox
etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of a compatible type can be placed on the same subplot.
The following trace types are compatible with geo subplots via the geo
attribute:
scattergeo
, which can be used to draw individual markers, line and curves and filled areas on outline mapschoropleth
: colored polygons on outline maps
The following trace types are compatible with mapbox subplots via the mapbox
attribute:
scattermapbox
, which can be used to draw individual markers, lines and curves and filled areas on tile mapschoroplethmapbox
: colored polygons on tile mapsdensitymapbox
: density heatmaps on tile maps
Traces Which Are Their Own Subplots
Certain trace types cannot share subplots, and hence have no attribute to map to a corresponding subplot in the layout. Instead, these traces are their own subplot and support a domain
attribute for position, which enables the trace to be positioned in paper coordinates (see below). With the exception of pie
and funnelarea
, such traces also do not support legends (see below)
The following trace types are their own subplots and support a domain attribute:
pie
andfunnelarea
: one-level part-to-whole relationships with legend itemssunburst
andtreemap
: hierarchical multi-level part-to-whole relationshipsparcoords
andparcats
: continuous and categorical multidimensional figures with parallel coordinates and parallel setssankey
: flow diagramstable
: text-based tablesindicator
: big numbers, gauges, and bullet charts
Carpet Trace Types and Subplots
Certain trace types use traces of type carpet
as a subplot. These support a carpet
attribute whose value must match the value of the carpet
attribute of the carpet
trace they are to be drawn on. Multiple compatible traces can be placed on the same carpet
trace.
The following trace types are compatible with carpet
trace subplots via the carpet
attribute:
scattercarpet
, which can be used to draw individual markers, curves and filled areascontourcarpet
Trace Types, Legends and Color Bars
Traces of most types can be optionally associated with a single legend item in the legend. Whether or not a given trace appears in the legend is controlled via the showlegend
attribute. Traces which are their own subplots (see above) do not support this, with the exception of traces of type pie
and funnelarea
for which every distinct color represented in the trace gets a separate legend item. Users may show or hide traces by clicking or double-clicking on their associated legend item. Traces that support legend items also support the legendgroup
attribute, and all traces with the same legend group are treated the same way during click/double-click interactions.
The fact that legend items are linked to traces means that when using discrete color, a figure must have one trace per color in order to get a meaningful legend.
Traces which support continuous color can also be associated with color axes in the layout via the coloraxis
attribute. Multiple traces can be linked to the same color axis. Color axes have a legend-like component called color bars. Alternatively, color axes can be configured within the trace itself.
What About Dash?
Dash for R is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.
Learn about how to install Dash for R at https://dashr.plot.ly/installation.
Everywhere in this page that you see fig
, you can display the same figure in a Dash for R application by passing it to the figure
argument of the Graph
component from the built-in dashCoreComponents
package like this:
library(plotly)
fig <- plot_ly()
# fig <- fig %>% add_trace( ... )
# fig <- fig %>% layout( ... )
library(dash)
library(dashCoreComponents)
library(dashHtmlComponents)
app <- Dash$new()
app$layout(
htmlDiv(
list(
dccGraph(figure=fig)
)
)
)
app$run_server(debug=TRUE, dev_tools_hot_reload=FALSE)