\documentclass[../../book.tex]{subfiles}
\graphicspath{{\subfix{.}}}
\begin{document}
\chapter{Plotly}
\label{ch:plotly}
\setcounter{section}{-1}  % Start subsections from 0

If you are doing science, you are going to collect data. And if you are collecting data, you are going to want to plot it.  In Python, you have many options for libraries that can plot data. In this chapter, we will explore how to do so for one of the most common ones: Plotly.

We wish to note up front that no library can perform every task that you will desire in terms of plotting.  There are always some specialty plots that libraries may not handle. However, Plotly offers a fairly substantial range of plot types and offers interactivity with these plots as a natural result of plotting. 

We also wish to note that we are going to teach you a somewhat non-standard approach to plotting in Plotly.  Much of the information that is present online focuses on how to plot single plots in a simple manner and often use an approach called `Plotly express.' While this is a nice approach for making figures that have only a single plot, if you want to make more complex figures that include many subplots, you will find this challenging.  We wish to give you a tool that is more flexible and can be used to create any sort of complex plot you may choose to make. %In addition, our approach, we believe, is more aligned with object-oriented programming. 

One last thing to acknowledge: we are focusing on how to construct plots and control many of the aspects of plotting, but we are not focusing on the theory of why you might want to change these aspects.  If you are curious to understand this, there are many good books on graphic design and the design of data visualizations. Here, focus is not on the why, but on the how. 

%%
\section{The basics of plotting using Plotly}

The construction of a figure showing data can be broken down into five elementary steps. Assuming you already have data you want to plot, these steps are:
\begin{enumerate}
    \item \textbf{Create a Figure object that holds the plotting region(s) you will need.} You might think of the \cite{figure_object} as the canvas you are `drawing' on. Such a canvas might contain a single plot area, or it might have several plotting areas.  In technical terms, we need to specify the number of `subplots,' as well as their arrangement---how many rows and columns of these subplots we will want to use. 

    \item \textbf{Add trace object(s) to your figure.} As scientists, we are conversant with many different means of representing data.  We use bars, scatterplots, line plots, histograms, box and whisker plots, etc. A key aspect of constructing a plot is to choose the means to represent it. When doing so, we might also choose things like the color of lines, the shape of markers, etc. These are parameters that control the appearance of our data representation. The choice of representation and the style of the representation are all held in the Plotly trace object. The purpose of making these representations is to add them to our figure, so we will also create and add them in a single step. It is useful to note that the order in which we add traces is the order in which they are drawn, so the last trace added will be on top.  

    \item \textbf{Specify the representation of axes.} Even if we do not explicitly show axes, data is always plotted against axes. However, these axes are not part of the data. Thus, we should consider how to format them (including adding titles) separately from formatting data representations. 

    \item \textbf{Design on an overall appearance for the figure.} This addresses questions of appearance that are separate from data and axes, and includes questions like the color of the background, the font, the overall size, etc. Though it might seem a bit strange to specify these late in the construction of a figure, when using Plotly, it is much easier to do it at this stage. 

    \item \textbf{Display/save the figure.} Plotly allows us to create interactive figures, static figures, and to save files. This is how we will ultimately use our plots.  
\end{enumerate}
We can demonstrate these steps in a simple example. We wish to note that the following example is not the absolute simplest means to generate a figure using Plotly; however, it strikes a balance between being simple and being robust to customization. Also, the steps do not need to be done in the exact order presented.  The first and last steps need to remain in their positions, but the other steps could move around.

\lstinputlisting{../../Distribution/Code by Chapter/ChI - Plotting Data Using Plotly/simpleExample.py}

Running this code in Spyder will save a figure (as an svg) to your \cite{working_directory}, it will also show a png version of the figure in the "Plots" window of the Spyder IDE, and it will open a web browser that contains an interactive version of the plot (you can point to data, zoom in, etc.). In all cases, the plot should look similar to this:

\begin{figure}[H]
    \centering
        \includegraphics[width = 3in]{ChapTechnical/Plotly/PlotlyFigs/Plotly_simple.png}
    \caption{Results of running the code above.  This is a simple scatter plot using many of the Plotly defaults.}
    \label{fig:Plotly:SimpleScatter}
\end{figure}


\vspace{-1em}
If we compare the code to our elementary steps, we can see the following:

\begin{enumerate}
    \item \lstinline{make_subplots()} is the function that creates our Figure object. Though we haven't done so in the above example, we can use this function to specify the number of subplots we want and how they are layed out. Here we do not do this, below we will consider an example where we do. If we don't do so, we will just have a single subplot. By assigning the output of this function to a variable (in this case \lstinline{sinplot}), we can refer to the Figure object by this variable name. 

    \item \lstinline{add_scatter()} is the \cite{method} that creates the traces from our data and then adds them to our Figure object. This function creates a scatterplot-like representation.  If we wanted a different representation, then we could a different function, like \lstinline{add_bar()}. Within these function calls we have the option to specify the appearance of this representation. In this case, we have told it to display the data using markers. As will be discussed below, other options would be to show just lines or markers and lines both. We can also change the color of the markers, the size of the markers, and so on. The data representations is then added to subplot(s) we wish. Since we only have a single subplot, we do not need to specify the specific subplot in this case. 

    \item \lstinline{update_xaxes()} and \lstinline{update_yaxes()} are also methods of the figure we created and are used to specify the formatting of the $x$ and $y$ axes in our figure. In this case, we specify a title for each.

    \item \lstinline{update_layout} is another method of the Figure object we created, and is used to control the general formatting of the figure (i.e., the formatting that is not for data or axes). We can assign a template (here: \lstinline{simple_white}) or alter sspecific traits (see next example plot).

    \item \lstinline{write_image()} is a method of the Figure object that produces a file of the figure.  We control the format of the file (i.e., svg, png, jpg, etc.) simply by specifying this in the name we wish to save the file as. \lstinline{show()} is a method of the Figure object used to display an image and we can display either static images (first usage in our example) or interactive figures (second usage in our example). Note that when outputting static images (svg, png, etc.), Plotly relies upon another library to do so.  You have the option of either kaleido (default) or orca.  If you do not have these libraries, you will be unable to generate such images. The `browser' option, however, should always work. 
\end{enumerate}
The above example shows the very basics of generating a Plotly plot.  However, there is much more we can do in Plotly.  We can create multiple subplots (step 1), represent data in different ways (step 2), put traces on specific subplots (step 2), format specific axes (step 3), fine-tune the layout (step 4), and control the output (step 5).  An example code that does all of these is shown below, and many more example plots are shown at \website

\lstinputlisting{../../Distribution/Code by Chapter/ChI - Plotting Data Using Plotly/subplotExample.py}

Running this code should produce an image like the following:

\begin{figure}[H]
    \centering
    \includegraphics[width = 5in]{ChapTechnical/Plotly/PlotlyFigs/Plotly_custom.png}
    \caption{The result from running the above code.  This is a more complex example, showing the use of subplots and non-default formatting. }
    \label{fig:Plotly:ComplexPlot}
\end{figure}


\vspace{-1em}
Comparing the outputs shown in Figure \ref{fig:Plotly:SimpleScatter} to Figure \ref{fig:Plotly:ComplexPlot} illustrates how we can control many aspects of plotting.  We are not recommending you use this particular style, simply showing what can be changed. 

There are many more changes that could be made.  For instance, it might look odd to you that the numbers on the y-axis have different numbers of decimal places. This can be adjusted using the \lstinline{tickformat} \cite{keyword_argument} when updating axes.  For the rest of this chapter, we will explore the various ways to control each of our five elementary plotting steps in Plotly. This discussion is not meant to be exhaustive, but to provide information on what we think will be the most common tasks, and to help provide a framework for understanding Plotly. Complete information can be found in the Plotly documentation.

\section{Controlling formatting during Plot construction}
Since our aim is to make as general a tool as possible, we are going to construct every figure as a figure with subplots, using the \lstinline{make_subplots()} function. In addition, we wish to leverage a general objected-oriented approach, where we are always creating and manipulating different parts of the Plotly Figure object.  For this reason, once we make a figure, we will continue to modify it using \cite{method}s of that Figure object, including methods like \lstinline{add_scatter()} and \lstinline{update_layout()}.
In what follows, let us consider some of the options availible during each of the elementary steps of plotting

%
% Step 1
%
\subsection*{STEP 1. Creating the Figure object and specifying subplot layout}
 The \lstinline{make_subplots()} function creates 2-dimensional grid of subplots (rows and columns) and then assigns this to a Figure object, we can then pass this Figure object to a variable. 

The \lstinline{make_subplots()} function accepts a large number of \cite{keyword_argument}s. Complete documentation can be found on the Plotly website, but we can summarize the most relevant here, by the behavior they control:
\begin{itemize}
    \item \lstinline{rows} and \lstinline{cols}: integer values that control the number of rows and columns, respectively. If you do not specify a value for these keywords, the default for each is 1.  Thus, if you call \lstinline{make_subplots()} without any arguments, you will return a figure that has a 1$\times1$ grid. 

    \item \lstinline{specs}: a list of lists used to specify more advanced layouts, such as if subplots should span multiple rows or columns. The outer list should contain a number of lists equal to the number of rows in the figure. The inner lists contain a number items equal to the number of columns in the figure. Thus, each item corresponds to a subplot directly. The items in the inner list  are either the word \lstinline{None} (specifying the \cite{data_type} \lstinline{nonetype}), or a \cite{dictionary}. If \lstinline{None} is used, then the subplot will not exist and you cannot add traces to it.  If it is a dictionary, then you can leave it empty or add information to it.  For this book, we will consider two keywords for these dictionaries:
    \begin{itemize}
        \item \lstinline{rowspan} and \lstinline{columnspan}: integers that specify how many rows or columns the subplot will span.   If not included, the subplot will span a single row and column. The spanning behavior is such that the row and column numbers specify the range of the span starting from the top left of the subplot.  This means that the span extends downwards (\lstinline{rowspan}) and to the right (\lstinline{columnspan}). 
    \end{itemize}
    Perhaps the best way to think about the impact of \lstinline{rowspan} and \lstinline{columnspan} is to think of them controlling the size of the subplot, in units of the subplot grid. So, you still add traces to the row and column corresponding to the subplot (i.e., the top left position). You can also add images to the subplots that are overlapped by the subplot. As an example of how to use \lstinline{specs}, imagine we wanted to have a $3\times4$ grid, where there was a subplot that spanned $2\times2$ and was centered on the bottom middle. The specs would look like:
    \begin{lstlisting}
    specs = [ # this outer list contains three lists... one for each row
             [{},{},{},{}], # each inner lists will one entry per column
             [{},{'colspan':2, 'rowspan':2},{},{}], 
             [{},{},{},{}],
            ]\end{lstlisting}
    In this example, all subplots occupy a single grid space, except for the subplot at row = 2, column = 2.  This spans two rows and 2 columns. Now, imagine I added our \lstinline{sin_data} from Figure \ref{fig:Plotly:ComplexPlot} to two traces added to two subplots at (\lstinline{row = 1, col = 1}) and \lstinline{row = 3, col = 3}) and the \lstinline{cos_data} to a trace in the subplot at (\lstinline{row = 2, col = 2}).  The traces showing \lstinline{sin_data} will each occupy a single grid space, while the trace showing \lstinline{cos_data} will span a 2$\times$2 block.  Also, the cos trace subplot will overlap with the trace at (\lstinline{row = 3, col = 3}). The output would look like this:\\
\begin{figure}[H]
    \centering
    \includegraphics[width = 4in]{ChapTechnical/Plotly/PlotlyFigs/PlotlySpecs.png}
    \caption{Plot that results from using the \lstinline{specs} values shown above. This illustrates how the subplot grid is organized in Plotly.}
    \label{fig:Plotly:SubplotGrid}
\end{figure}
    \item  \lstinline{vertical_spacing} and \lstinline{horizontal_spacing}: float values, between 0 and 1 that control the spacing between rows and columns, respectively. The value specifies the fraction of horizontal or vertical space on the plot that is devoted to separation between subplots. You can think of this as the internal margins. Thus, if you had 2 rows, and used \lstinline{vertical_spacing = 0.5}, then half of the availible vertical space would be devoted to separation between the plots. If you set the vertical spacing value too large, then there will not be sufficient room to hold the figure, and you will receive an error that there is insufficient room.  A good rule of thumb is to keep the spacing less than 0.5/\# of rows. The same holds for cols. The default values are 0.2/\# of cols and 0.3/\# of rows respectively. 

    \item \lstinline{shared_yaxes} or \lstinline{shared_xaxes}: boolean value that controls if axes titles and tick numbers are shared. Set to \lstinline{True}, title and tick numbers appear on only the the leftmost $y$-axes and the bottom-most $x$-axes.  If set to \lstinline{False} (default) all axes bear numbers and titles (if supplied). 

    \item \lstinline{subplot_titles}: list of strings that specifies the titles for the subplots. You must pass all of the titles you want as a list and, if you use \lstinline{subplot_titles}, then you \textit{must} have an entry for each subplot. Use empty strings (\lstinline{''}) for subplots you don't want titles to display. When counting the subplots in the list, you count across rows first, before moving to the next row. 

    \item \lstinline{column_widths} and \lstinline{row_heights}: list of floats that control the relative widths of columns or heights of rows,  respectively. The length of the list needs to be equal to the number of columns or rows, respectively.  You can use any numbers you like, as they will be normalized.  Thus, if you had to rows, and you wanted them to have heights in a ratio of 2 to 3, you could use \lstinline{row_heights = [4, 6]}. 
\end{itemize}


%
% Trace objects
%
\subsection*{STEP 2. Creating trace objects and adding them to Figure objects}
In Plotly, the representations of data we use are called `traces,' and there are many types availible. Herein we focus on the 2D plots that we think you will most commonly want to plot.  You can read the Plotly documentation for more 2D plots, and all 3D plots, as well as help on creating animations for any of these. 

We will create representations and add them to Figure objects, using a methods of the Figure object. The \cite{method}s for the most common traces are:

%
% Scatter
%
\vspace{1em}\noindent
\lstinline{add_scatter()}: This is used to create scatter plots (where data are represented by markers) as well as line plots (where data are represented by lines). The keyword arguments used used for this method are:
    \begin{itemize}
        \item \lstinline{x} and \lstinline{y}: list or array floats.  These are the $x$-axis and $y$-axis data, respectively.

        \item \lstinline{mode}: string specifying the display mode. Options include: \lstinline{'lines'} (only lines), \lstinline{'markers'} (only markers), and \lstinline{'lines+markers'} (markers connected by lines). 

        \item \lstinline{name}: string that provides a name for the trace, used in legends and hover labels (labels that appear when the cursor is over the trace in an interactive plot).

        \item \lstinline{marker}: dictionary specifying marker properties. Common keys are:

        \begin{itemize}
            \item \lstinline{color}: specify using Plotly conventions, as described in Figure \ref{fig:Plotly:commonspecs}.  

            \item \lstinline{size}: integer specifying marker size in pixels.

            \item \lstinline{symbol}: string specifying the shape for the marker symbol. There are a large number of options but ones that are common are: \lstinline{'circle'} (a filled circle, which is the default value), \lstinline{'square'} (a filled square), \lstinline{'diamond'} (a filled diamond), \lstinline{'cross'} (plus sign), \lstinline{'x'} (a $\times$ shape). For many of these, you can add the suffix \lstinline{'-open'} to make them non-filled.  For instance, \lstinline{'circle-open'} produces a non-filled circle. 
        \end{itemize}
        
        \item \lstinline{line}: dictionary specifying line properties. You can use the common line keys for Plotly as shown in Figure \ref{fig:Plotly:commonspecs}.

        \item \lstinline{showlegend}: boolean value indicating whether the trace should appear in legends.

        \item \lstinline{fill}: string specifying fill mode. Options include: \lstinline{'tozeroy'} (will fill  until the bottom of the $y$-axis) and  \lstinline{'tonexty'} (will fill below, until the next trace is encountered).
        
        \item \lstinline{fillcolor}: Color of the fill specified using the Plotly conventions shown in Figure \ref{fig:Plotly:commonspecs}.

        \item \lstinline{opacity}: float between 0 (totally transparent) and 1 (totally opaque), specifying the degree of transparency.
    \end{itemize}


    %
    % Bar
    %
\vspace{1em}\noindent
\lstinline{add_bar()}: This method produces a bar chart, which is often used to show relative magnitude between data that is both quantitative and categorical. Keyword arguments for the bar trace are:
    \begin{itemize}
        \item \lstinline{x} and \lstinline{y}: list or array. One of these (the numerical axis) should hold floats or ints while the other (the categorical axis) could also hold floats or ints (specifying the bar locations) or it can hold strings (providing labels to be associated with the bars). Which is the numerical axis and which is the categorical axis will depend on the value of the keyword argument: \lstinline{orientation.}

        \item \lstinline{orientation}: string specifying the orientation of the bars. Options include \lstinline{'v'} (vertical) and \lstinline{'h'} (horizontal).

        \item \lstinline{marker}: dictionary specifying marker properties. Common keys for this include:
        \begin{itemize}               
            \item \lstinline{color}: color of the bars, specified using the Plotly conventions shown in Figure \ref{fig:Plotly:commonspecs}. 
    
            \item \lstinline{line} dictionary specifying line properties. You can use the common line keys for Plotly as shown in Figure \ref{fig:Plotly:commonspecs}.
            
            \item \lstinline{opacity}: float between 0 (totally transparent) and 1 (totally opaque), specifying the degree of transparency.
        \end{itemize}

        \item \lstinline{name}: string that is the trace, used in legends and hover labels.

        \item \lstinline{text}: list or array of strings that will serve as the text labels for each bar.
        
        \item \lstinline{width}: float specifying the width of the bars along the categorical axis (as a fraction of the plot dimensions).

        \item \lstinline{showlegend}: boolean value indicating whether the trace should appear in legends.

        \item \lstinline{textposition}: String specifying the position of text labels. Options include \lstinline{'inside'} (text inside bar) and \lstinline{'outside'} (text outside bar).

        \item \lstinline{textfont}: Dictionary specifying font properties for text labels. Font is specified as shown in Figure \ref{fig:Plotly:commonspecs}.

        \item \lstinline{bargap}: Float specifying the gap between bars in a group (as a fraction of the total plot dimensions). \textit{NOTE: This must be specified in the \lstinline{update_layout()} method of the Figure object.}

        \item \lstinline{bargroupgap}: Number specifying the gap between bar groups (as a fraction of the total plot dimensions). \textit{NOTE: This must be specified in the \lstinline{update_layout()} method of the Figure object.}
    \end{itemize}


    %
    % Histogram
    %
\vspace{1em}\noindent
\lstinline{add_histogram()}: This method is used to construct a histogram, often used to show shape of distributions of data. 
    \begin{itemize}
        \item \lstinline{x}: list or array of floats from which the histogram is constructed.
        
        \item \lstinline{histnorm}: string specifying the normalization mode for the histogram. Options include \lstinline{'count'} (display the count of data points in each bin), \lstinline{'percent'} (display the percentage of data points in each bin), and \lstinline{'density'} (display the probability density, normalized such that the integral of the histogram is 1).
        
        \item \lstinline{name}: string that is the name of the trace, used in legends and hover labels.
        
        \item \lstinline{marker}: dictionary specifying marker properties. Common keys for this include:
        \begin{itemize}               
            \item \lstinline{color}: color of the bars, specified using the Plotly conventions shown in Figure \ref{fig:Plotly:commonspecs}. 
    
            \item \lstinline{line} dictionary specifying line properties. You can use the common line keywords for Plotly as shown in Figure \ref{fig:Plotly:commonspecs}.
            
            \item \lstinline{opacity}: float between 0 (totally transparent) and 1 (totally opaque), specifying the degree of transparency.
        \end{itemize}
        
        \item \lstinline{orientation}: string specifying the orientation of the histogram bars. Options include \lstinline{'v'} (default, vertical bars) and \lstinline{'h'} (horizontal bars).
        
        \item \lstinline{xbins}: dictionary specifying the settings for the bins on the $x$-axis. Keys include:
        \begin{itemize}
            \item \lstinline{start}: float specifying starting value of the bins.
            \item \lstinline{end}: float specifying ending value of the bins.
            \item \lstinline{size}: float specifying the size of the bins.
        \end{itemize}
        \item  \lstinline{ybins}: dictionary specifying the settings for the bins on the $y$-axis (when orientation is given the value \lstinline{'h'}). Same as the above dictionary for the \lstinline{xbins}.
    \end{itemize}


    %
    % Box and whisker plot
    %
\vspace{1em}\noindent
\lstinline{add_box()}: This method creates a box and whisker plot,  used to succinctly summarize statistical information about a set of data---typically showing the median, mean, inner quartile range, and outliers. 
    \begin{itemize}
        \item \lstinline{y}: list or array of floats used to create the box plot.

        \item \lstinline{x}: list or array of strings that provide categorical labels or groupings for the data.

        \item \lstinline{name}: string that is the name of the trace, used in legends and hover labels.

        \item \lstinline{marker}: dictionary specifying marker properties. Common keys are:
        \begin{itemize}
            \item \lstinline{color}: Color of the boxes and outliers, specified using the Plotly conventions, as shown in Figure \ref{fig:Plotly:commonspecs}.

            \item \lstinline{outliercolor}: Color of the outlier points, specified using the Plotly conventions, as shown in Figure \ref{fig:Plotly:commonspecs}.

            \item \lstinline{line}: dictionary specifying line properties. You can use the common line keywords for Plotly as shown in Figure \ref{fig:Plotly:commonspecs}.
        \end{itemize}
        
        \item \lstinline{boxpoints}: string or array-like object specifying which data points should be shown as individual points. Options include: \lstinline{'outliers'} (show outliers as individual points) and \lstinline{'all'} (show all data points as individual points).

        \item \lstinline{boxmean}: string specifying whether to show a mean line inside the box. Options include \lstinline{'false'} (yes, this is  string, not a boolean and this is also the default value, which results in not showing a mean line), \lstinline{'sd'} (show the standard deviation as a line inside the box), \lstinline{'mean'} (show only the mean as a line inside the box), and \lstinline{'sd+mean'} (show both mean and standard deviations).

        \item \lstinline{meanline}: dictionary specifying properties of the mean line when using \lstinline{'mean'} or \lstinline{'mean+sd'}. You can use the common line keywords for Plotly as shown in Figure \ref{fig:Plotly:commonspecs}.
        
        \item \lstinline{orientation}: string specifying the orientation of the box plot. Options include \lstinline{'v'} (default value, vertical boxes) and \lstinline{'h'} (horizontal boxes).

        \item \lstinline{markeroutliercolor}: color of the outlier points, specified using the Plotly conventions as shown in Figure Figure \ref{fig:Plotly:commonspecs}.
        
    \end{itemize}


    %
    % Pie
    %
\vspace{1em}\noindent
\lstinline{add_pie()}: method that creates a pie chart, often used to show part to whole relationships.  Though often frowned upon in science, they do have their place. 
    \begin{itemize}
        \item \lstinline{labels}: list or array of strings that function as labels for the pie chart sectors.

        \item \lstinline{values}: list or array of floats corresponding to the sizes of the pie chart slices.

        \item \lstinline{hole}: float between 0 and 1 specifying the size of the center hole in the pie chart. This creates a donut chart when hole is greater than 0. The default value is 0.

        \item \lstinline{textinfo}: string or array-like object specifying the information to display on the chart. Options include \lstinline{'label'} (display labels for slices), \lstinline{'text'} (display the values of slices as text), \lstinline{'percent'} (display percentages). Any of these can be joined together with a "+" to display multiple kinds.  Fir instance, \lstinline{'percent+label'} displays both the percentages and labels.

        \item \lstinline{direction}: string specifying the direction in which the sectors are drawn. Options are \lstinline{'clockwise'} (default) and \lstinline{'counterclockwise'}.

        \item \lstinline{sort}: boolean value indicating whether to sort the sectors by size.

        \item \lstinline{rotation}: float specifying the rotation angle of the first slice in degrees. The default value is 0, and the first slice starts at the top of the chart. 

        \item \lstinline{textposition}: string specifying the position of text labels. Options include \lstinline{'inside'} (text labels inside the slices) and \lstinline{'outside'} (text labels outside the slices).  If neither is specified, Plotly will try to make the best choice. 

        \item \lstinline{marker}: dictionary specifying marker properties for the sectors.  Common keys include:
        \begin{itemize}
                \item \lstinline{color}: Specified using the Plotly conventions, as shown in Figure \ref{fig:Plotly:commonspecs}.

            \item \lstinline{line}: dictionary specifying line formatting.  See Figure \ref{fig:Plotly:commonspecs} for options. 
        \end{itemize}

        \item \lstinline{showlegend}: boolean value indicating whether the trace should appear in legends.
    \end{itemize}

    %
    % Contour
    %
\vspace{1em}\noindent
\lstinline{add_contour()}: This method creates a 2D contour plot. 3D plots can be very challenging to interpret, and so a 2D rendering of the contours of a 3D plot is often a better choice.
    \begin{itemize}
        \item \lstinline{z}: 2D array of floats.  These are the values to be contoured.
    
        \item \lstinline{x} and \lstinline{y}:  list or array floats or strings specifying the labels or categories for the $x$-axis and $y$-axis, respectively.

        \item  \lstinline{ncontours}: integer specifying the number of contour levels to be displayed. 
         
        \item \lstinline{contours}: dictionary specifying the contour lines. Commonly used keys include:
        \begin{itemize}
            \item \lstinline{coloring}: string specifying how contour representation is colored. Options include fill (color the contour surfaces) and lines (color only the contour lines).
        
            \item \lstinline{showlines}: boolean value indicating whether contour lines should be displayed.
    
            \item \lstinline{start}, \lstinline{end}, and \lstinline{size}: Each of these accept floats that specify the range and step size of contour levels, respectively. If not specified, then Plotly guesses at the values. Can be used to provide more control than when using \lstinline{ncountours} (see above).
    
            \item \lstinline{colorscale}: string or list specifying the colorscale to use for coloring the contour plot. The string refers to a named colorscale (see Figure \ref{fig:Plotly:commonspecs} for a list), while the list can specify the exact colors to be used, following the Plotly conventions shown in Figure \ref{fig:Plotly:commonspecs}. 
    \end{itemize}
        \item \lstinline{showlegend}: boolean value indicating whether the trace should appear in legends.
    
        \item \lstinline{showscale}: boolean value indicating whether a color scale should be displayed alongside the contour plot.
    
        \item \lstinline{line}:  dictionary specifying line properties for the contour lines. You can use the same line specifications shown in Figure \ref{fig:Plotly:commonspecs}. 
    \end{itemize}

    %
    % Heatmap
    %
 \vspace{1em}\noindent
 \lstinline{add_heatmap()}: Method that creates a heatmap. This plot can be used to show the projection of 3D surfaces in 2D, but can also be used to show correlations between variables. 
    \begin{itemize}
        \item \lstinline{z}: 2D array of floats that are the values to be displayed in the heatmap.

        \item \lstinline{x} and \lstinline{y}: list or array of strings specifying the labels or categories for the $x$-axis or $y$-axis, respectively.
    
        \item \lstinline{colorscale}: string or list specifying the colorscale to use for coloring the heatmap. The strings correspond to named color scales, while the list contains colors (specified using the Plotly convention shown in Figure \ref{fig:Plotly:commonspecs}) to be stepped through. 

        \item \lstinline{showlegend}: boolean value indicating whether the trace should appear in legends.
    \end{itemize}


\begin{figure}[h]
    \centering
    \includegraphics[width = 5.5in]{ChapTechnical/Plotly/PlotlyFigs/Plotly common specifications.png}    \caption{Keys and values for Line and Font formatting, as well as how color is specified in Plotly.}
    \label{fig:Plotly:commonspecs}
\end{figure}



\subsubsection*{Adding data traces to subplots}
All of the above methods both create the trace object, and add it to our Figure object.  Because we created the Figure object using \lstinline{make_subplots()}, we will naturally have subplots we can add the traces to.  In order to specify the exact subplot you wish to add the trace to, we use two keyword arguments \lstinline{row} and \lstinline{col}.  These are used to specify the location of the subplot you wish to add the trace to. The default values for these are \lstinline{None}, but they must be specified if you are using a grid of subplots. If you do not supply them, the trace will be added to the subplot at \lstinline{row} = 1, \lstinline{col} = 1. This subplot is the top left most subplot, that is, rows count top by bottom starting at 1 and columns count left to right starting at 1. 

You can assign multiple traces to a single subplot.  If you do so, they will be drawn in the order in which they were added.  Thus, the last trace you add will be drawn on top of all the other traces. 

That is it for assigning traces to the subplots. 

%
% formmatting axes
%
\subsection*{STEP 3. Formatting axes}

If you want to change the formatting of your axes from the default, you need to use the \lstinline{update_xaxes()} and \lstinline{update_yaxes()} methods of the Figure object. When using these, you can specify a particular subplot to update using the \lstinline{row}  and \lstinline{col} keyword.  Specifying these will update the axes for \textit{only} the corresponding subplot. If you do not specify anything for these keywords, then axes for \textit{all} subplots will be updated. 


When specifying the formatting, you have two options.  First, you can use each of the \cite{keyword_argument}s described below.  Alternatively, you can gather these keyword arguments and their values into a dictionary, and then pass this dictionary as the \lstinline{first} \cite{positional_argument}. The former might be quicker when you are formatting a single axis, however, the latter will be superior if you are trying to apply the same formatting multiple times---for instance, across multiple figures. 


Common keyword arguments for the \lstinline{update_xaxes()} and \lstinline{update_yaxes()} methods are:
\begin{itemize}
    \item \lstinline{title}: string that will be used as the axis title.

    \item \lstinline{range}: list of floats that provide the lower and upper limits for the axis. The default behavior is to not use such a list and Plotly takes a reasonable guess at the range, given the data. 
    
    \item \lstinline{type}: string that specifies the type of axis (\lstinline{'linear'} is the default), but other options are \lstinline{'log'} (logarithmic), \lstinline{'date'} (for dates), and  \lstinline{'category'} (for categorical).

    \item \lstinline{showgrid} and \lstinline{showgrid_minor}: boolean value that, when set to \lstinline{True}, shows gridlines at the major or minor tick marks, respectively. If you do not want gridlines, then set these to \lstinline{False}.

    \item \lstinline{line}: dictionary controls the appearance of the line that represents the axis.  You can use the values shown in Figure \ref{fig:Plotly:commonspecs}.

    \item \lstinline{showline}: boolean that, when set to \texttt{True}, results in the axis line being shown.  This is the default value. 

    \item \lstinline{zeroline}: boolean that, when set to \lstinline{True}, results in a line being drawn at the value of zero. The default value is \lstinline{False} and this line is not drawn. The color of this line can be controlled using the keyword \lstinline{zerolinecolor} and using the standard Plotly color designations, as shown in Figure \ref{fig:Plotly:commonspecs}. 

    \item \lstinline{ticks}: string that control the position of the tick marks. Accepted values are \lstinline{'inside'}, \lstinline{'outside'}, \lstinline{'both'}, or an empty string (\lstinline{''}).  If an empty string is used, then no tick marks are drawn.

    \item \lstinline{tickvals}: list of floats that specify where the values at which tickmarks are drawn. If no list is specified, Plotly takes a guess at reasonable tickmark values.
    
    \item \lstinline{ticktext}: list of strings or floats that specify exactly what text appears at the tickmarks. If no such list is specified Plotly will default to something reasonable (i.e., numbers). If you want to use your own custom labels, specified in a list, then you need to also specify \lstinline{tickvals} as well as include \lstinline{tickmode = 'array'}

    \item \lstinline{showticklabels}: boolean that, when set to \lstinline{True}, results in the values at the ticks being displayed. 

    \item \lstinline{tickformat}: string that specifies the formatting for numbers at the tick marks. The formatting of numbers was discussed in our chapter on strings.  

    \item \lstinline{tickprefix} and \lstinline{ticksuffix}: strings that specify text to be added before or after the tick labels, respectively. For instance, you could add a \$ before the number, or a \% after the numbers. 
\end{itemize}



%
% LAYOUT
%
\subsection*{Step 4. Formatting the rest of the figure}

There are two kinds of formatting that you migth like to do to your figure:
\begin{enumerate}
    \item Add an element that is not yet present.  For instance, you might want to add text to the plot to annotate some features.  Or you might want to add an image to your plot.

    \item For the elements that are already present, or apply some global changes.  For instance, you migth want to change change the background color for the plotting area, or change the margins that are used, or perhaps change the default font size of the figure. 
\end{enumerate}
These two actions require different approaches, and so we discuss them separately.

\subsubsection*{Adding elements to the plot}

For the purposes of this book, you will be either adding text-based annotations or images. 

For text-based annotations, you can use the \lstinline{add_annotation()} method of the Figure object. This method accepts a number of keyword arguments, including
\begin{itemize}
    \item \lstinline{text}: String, the text to be displayed in the annotation.  This can be an empty string. You can also supply formatting using HTML within the string.

    \item \lstinline{font} dictionary, containing key-value pairs for formatting text, as shown in \ref{fig:Plotly:commonspecs}.

    \item \lstinline{align}: string with possible values of \lstinline{left}, \lstinline{center}, and \lstinline{right}. Specifies the alignment of text.

    \item \lstinline{bgcolor}: string, which specifies the color of the text box background. Values set as shown in Figure \ref{fig:Plotly:commonspecs}.

    \item \lstinline{bordercolor}: string, which specifies the color of the text box border. Values set as shown in Figure \ref{fig:Plotly:commonspecs}.

    \item \lstinline{showarrow}: boolean, which states if an arrow should be drawn from the annotation position to the text. Default is \lstinline{True}, so you need to be aware that the default behavior is to have a line.

    \item \lstinline{xref} and \lstinline{yref}, \lstinline{axref} and \lstinline{ayref}: string, with possible values \lstinline{paper}, \lstinline{x} or \lstinline{y}. The first two specify the positional coordinates for the annotation are relative to the plot area or the axes coordinates. If there is an arrow, this will be where the arrow starts.  If there is no arrow, then it is the position for text alignment. The second two specify which axis to use as the reference.  If you have multiple subplots, you will have multiple axes of each type, and this is why you migth need to specify which to use. 

    \item \lstinline{x} and \lstinline{y}, \lstinline{ax} and \lstinline{ay}: The first two specifies the positions of annotation.  If there is an arrow drawn, this is where the arrow will start. If not, it species where the text will be aligned on. If there is an arrow drawn, the second two specify where the arrow will end, as an \textit{offset} along the $x$ and $y$ axes, in units of \textit{pixels}. If the reference is set to \lstinline{paper}, then you use a float.  If it is set to \lstinline{x} or \lstinline{y} then you use a number (if the axis is numerical) or a label (if the axis is categorical).

    \item \lstinline{arrowsize}: float, which specifies the scaling factor applied to the arrow. Default is 1.
    
    \item \lstinline{arrowhead}: int, which specifies the style of arrow to use. The options are: 0 (no arrowhead, so a plain line), 1 (triangle for arrowhead), 3 (open triangular arrowhead), 4 (a T-junction), 6 (filled circle), 7 (open circle), 8 (x-shape).

    \item \lstinline{arrowwidth}: float, which specifies the width of the arrow.

    \item \lstinline{arrowcolor}: string, which specifies the color, as shown in Figure \ref{fig:Plotly:commonspecs}.
\end{itemize}

If you want to add an image to the figure, then you will either be adding a \cite{scalable_vector_graphic} image or a \cite{bitmap} image.  Both of these require the use the \lstinline{add_layout_image()} method. The manner in which scalable vector graphics are added is detailed in Chapter \ref{03DrawMol}, so this will not be repeated here. 

If you want to add a bitmap, you can use the same basic approach, however, the \lstinline{source} keyword argument needs to be given an object containing the information for a bitmap.  The simplest way to do this is to use the Pillow library (often imported using \lstinline{import PIL}) to open up an image as a Pillow Image object, and then supply this to the \lstinline{source} keyword argument. For instance:


\lstinline{source = PIL.Image.open(<image_path>)}, where \lstinline{<image_path>} is the \cite{path} to the image on your computer. If you want to know how to use Pillow, we have chapter on that as well: Chapter \ref{15Pillow}. 



\subsubsection*{Formatting elements that are already present using \lstinline{update_layout()}}

When you want to format standard elements of a plot that are not an axis or the data representation (trace), you will use the \lstinline{update_layout()} method.  This accepts keyword arguments that let you change various aspects of the plot. We are going to suggest that you always use the \lstinline{template} keyword, and then follow up its usage with any other keywords you want to change.  This approach allows you to work from a reasonable start. The common keywords for \lstinline{update_layout()} are:
 
\begin{itemize}

    \item \lstinline{template}: a string that specifies a pre-made template from the Plotly library. Examples are \lstinline{'plotly'}, \lstinline{'seaborn'}, \lstinline{'simple_white'}, and more. Of course, one you specify these, you can continue to change them, by using any of the keywords below or in the Plotly documentation. 

    \item \lstinline{row} and \lstinline{col}: integers that specify the row and/or column to which you wish to apply the specified formatting. If you do not use these keyword arguments, then the Layout will be applied to all subplots. If you do, then the Layout will only be applied to the specified subplot(s). 

    \item \lstinline{margin}: \lstinline{dict} that controls the size of the outer margins of the plot---that is the distances from the edges of the figure. The value provided is a dictionary, with keys \lstinline{l}, \lstinline{r}, \lstinline{t}, \lstinline{b} (for left, right, top, and bottom, respectively). Each can be assigned an integer value, which specifies the size of the margin in units of pixels. So, if you wanted to have margins that are 50 pixels on each side, you would use: \lstinline{margin = dict(l = 50, r = 50, t = 50, b = 50)} to do so. \footnote{If you want to control the inner margins (between subplots in a figure with multiple subplots) then refer to the \lstinline{specs} keyword associated with \lstinline{make_subplots} (Step 1), specifically the \lstinline{vertical_spacing} and \lstinline{horizontal_spacing} keywords.}
    
    \item \lstinline{paper_bgcolor}: controls the color of the entire figure.  So, not only the plot areas, but also all margins will have this color. Use the color specifications shown in Figure \ref{fig:Plotly:commonspecs}.
    
    \item \lstinline{plot_bgcolor}:  controls the color of only the plotting areas. The color outside the plotting areas (e.g., margins) will be unaffected. Use the color specifications shown in Figure \ref{fig:Plotly:commonspecs}.

    \item \lstinline{title}: string that will be used as the title of the plot. 

    \item \lstinline{height} and \lstinline{width}: floats that specify the height and width of the page, respectively. Values are in units of pixels. The page is the object that holds all the subplots, so you are adjusting the entire canvas for the figure. If no values are defined, then Plotly will simply render the plot to fit the window it is being drawn in. You can also specify sizes when rendering and saving the plot (see next section) and so you don't have to specify a size here. 

    \item \lstinline{font}:  dictionary that controls the appearance of font in the figure.  The keywords that can be included in this dictionary summarized in Figure \ref{fig:Plotly:commonspecs}.

    \item \lstinline{legend}: This allows you to control the appearance of the legend (sometimes called key) of your plots. This accepts a dictionary. Commonly used keywords for the dictionary are:
    \begin{itemize}

        \item \lstinline{font}: dictionary that controls the appearance of font in the figure.  The keywords that can be included in this dictionary summarized in Figure \ref{fig:Plotly:commonspecs}.
        
        \item \lstinline{title}: string that will be used at the title of the legend. 

        \item \lstinline{x} and \lstinline{y}:  floats between 0 and 1, which specify where the legend is placed on the plot area. These are relative to the min and max of the axes and so 0.5 is the middle. 

        \item \lstinline{xanchor} and \lstinline{yanchor}: strings that tell Ploty where the placement should be anchored to on the legend.  Options are \lstinline{'left'}, \lstinline{'right'}, \lstinline{'center'} (for \lstinline{xanchor}) and \lstinline{'top'}, \lstinline{'middle'}, \lstinline{'bottom'} (for \lstinline{yanchor}).

        \item \lstinline{borderwidth}: float that controls the line around the legend.  Setting this to 0 will result in no line being drawn.

        \item \lstinline{bordercolor}: You can use this to control the color of a border drawn around the legend. Colors are specified using the approach shown in Figure \ref{fig:Plotly:commonspecs}.

        \item \lstinline{bgcolor}: You can use this to control the background color of the legend. olors are specified using the approach shown in Figure \ref{fig:Plotly:commonspecs}.
    \end{itemize}

    \item \lstinline{hovermode}: string that controls how hover information is displayed in interactive plots. Common options include \lstinline{'x'}, \lstinline{'y'}, \lstinline{'closest'}, and \lstinline{'x unified'}. These control whether the hover text is shown for points closest to the cursor or across entire vertical/horizontal slices. To format the appearance of hover text, use the \lstinline{hoverlabel} dictionary. If you do not want any hover functionality, set the keyword \lstinline{hoverinfo} for individual traces to \lstinline{'skip'} or disable it using \lstinline{fig.update_traces(hoverinfo='skip')}.

    %\item \texttt{margin}: You can specify the margin around plots by supplying a dictionary.  The keywords for the dictionary are \texttt{t}, \texttt{b}, \texttt{l}, \texttt{r}, which specify margins for the top, bottom, left and right of the plot. The values you provide should be integers, which specify the width of the margin in units of pixels. 
    
    \item \lstinline{annotations}: dictionary that allows you to add text elements to the plot. You can use the same set of options shown for the \lstinline{add_annotation()} method, as shown above, but the keyword arguments serve  as keys in this dictionary.

    \item \lstinline{shapes}: dictionary that lets you draw shapes on your plot. Common keywords are:
    \begin{itemize}
        \item \lstinline{type}: Specifies the type of shape to be drawn. Options include: \lstinline{'line'}, \lstinline{'rect'}, and \lstinline{'circ'}.

        \item \lstinline{x0}, \lstinline{x1}, \lstinline{y0}, and \lstinline{x1}: float that the starting and ending points along $x$ and $y$ axes. 

        \item \lstinline{fillcolor}: you can specify color using Plotly conventions shown in Figure \ref{fig:Plotly:commonspecs}

        \item \lstinline{line}: dictionary that controls the appearance of lines, as shown in Figure \ref{fig:Plotly:commonspecs}

        \item \lstinline{opacity}: float between 0 (completely transparent) and 1 (completely opaque). 

        \item \lstinline{layer}: string that specifies if the shape is drawn below or above other elements on the plot.  Values are \lstinline{'above'} or \lstinline{'below'}. 
    \end{itemize}

    \item \lstinline{images}: a list of dictionaries (one per image) that specifies and formats an image to include in your plot area. Common keywords of the dictionaries are:
    \begin{itemize}
        \item \lstinline{source}: string or variable that points to the image to be displayed. Though there are several options, we suggest creating an object that is a base64-encoded image data string, and passing this to the source.  A discussion of image encoding is given in the chapter on images in Python. 

        \item \lstinline{x} and \lstinline{y}: floats that are the x- and y-coordinates of the left and top edges of the image. These are given in plot coordinates. 

        \item     \lstinline{xanchor} and \lstinline{yanchor}: strings that specify the reference position for x and y.  Options are \lstinline{'left'} and \lstinline{'right'} for the former and \lstinline{'top'} and \lstinline{'bottom'} for the latter. 

        \item \lstinline{sizex} and \lstinline{ysize}: floats that specify the width and height of the image.  These are given in plot coordinates. 

        \item \lstinline{sizing}: string that specifies the image should be sized and/or stretched. Options include \lstinline{'contain'} (keep aspect ratio) and \lstinline{'stretch'} (stretch image).

        \item \lstinline{opacity}: float between 0 (completely transparent) and 1 (completely opaque). 
    \end{itemize}
\end{itemize}
One further note on usage: for keywords that accept dictionaries, we find it simpler and cleaner to construct the dictionary outside the \lstinline{update_layout()} method call, and then pass the dictionary's variable to the correct keyword. 

%
% Output
%
\subsection*{Step 5. Outputting the figure by saving or displaying}

For this book, we will use two different output types, to generate three different kinds of figure output.  The methods are:
\begin{itemize}
    \item \lstinline{write_image()}: This method is used to save a static image of your plot, such as you might include in a paper, report, or slide deck. The function has one positional argument, which is the filename.  This accepts a string that can provide information on where to save and the file to save. Using the extension of the file, you can specify the file type, and options include \lstinline{'png'}, \lstinline{'jpg'}, \lstinline{'svg'}, and \lstinline{'pdf'}. However, you can also specify keyword arguments, and the three you are most likely to use are:
    \begin{itemize}
        \item \lstinline{width} and \lstinline{height}: integer that specify the final image width and height (respectively) in pixels. Because you can call \lstinline{write_image()} method multiple times for the same Figure object, you can output multiple files in different sizes for different use cases. 

        \item \lstinline{engine}: string that specifies the engine you wish to use to write the image. In this book we have tried to ensure you only have a single engine and so Plotly will default to using it. However, if you have multiple engines installed, you may want to specify one or the other.  Options are \lstinline{'kaleido'} and \lstinline{'orca'}.
    \end{itemize}

    \item \lstinline{show()}: This method is used to generate either static or interactive images. They can be displayed in browsers or other settings. It accepts a positional argument, which controls the display mode, and options are \lstinline{'div'}, \lstinline{'cdn'}, \lstinline{'svg'}, \lstinline{'png'}, and \lstinline{'browser'}.  The last of these will open the plot in a web browser window. We are going to suggest that you primarily use \lstinline{'svg'}, \lstinline{'png'}, and \lstinline{'browser'}.  The first two will output to the Sypder plot window, and provide a static record of the plots you have made, while the last one will provide interactive plots that exist until you close the browser window. 
\end{itemize}


%\section{Additional information and examples}

%Basically, go to our website to see examples of the kinds of plots you can make. 

\section{Understanding the structure of Plotly \texttt{Figure} objects}
As you become more familiar with the Plotly library, it will probably be helpful to understand the structure of the Plotly Figure object.  Fortunately, you can gain access to this structure by printing the object. For instance, let us consider printing the \lstinline{sincosplot} Figure object we created near the beginning of this chapter and which was shown in Figure \ref{fig:Plotly:ComplexPlot}. 

\begin{pyin}
print(sincosplot)    
\end{pyin}


\begin{lstlisting}[basicstyle=\tiny]
Figure({
    'data': [{'line': {'color': '#FF00FF', 'width': 3},
              'mode': 'lines',
              'name': 'sine',
              'type': 'scatter',
              'x': array([ 0.        ,  0.20408163,  0.40816327,  0.6122449 ,  0.81632653,
                           1.02040816,  1.2244898 ,  1.42857143,  1.63265306,  1.83673469,
                           2.04081633,  2.24489796,  2.44897959,  2.65306122,  2.85714286,
                           3.06122449,  3.26530612,  3.46938776,  3.67346939,  3.87755102,
                           4.08163265,  4.28571429,  4.48979592,  4.69387755,  4.89795918,
                           5.10204082,  5.30612245,  5.51020408,  5.71428571,  5.91836735,
                           6.12244898,  6.32653061,  6.53061224,  6.73469388,  6.93877551,
                           7.14285714,  7.34693878,  7.55102041,  7.75510204,  7.95918367,
                           8.16326531,  8.36734694,  8.57142857,  8.7755102 ,  8.97959184,
                           9.18367347,  9.3877551 ,  9.59183673,  9.79591837, 10.        ]),
              'y': array([ 0.        ,  0.20266794,  0.39692415,  0.57470604,  0.72863478,
                           0.85232157,  0.94063279,  0.98990308,  0.99808748,  0.96484631,
                           0.89155923,  0.78126802,  0.63855032,  0.46932961,  0.2806294 ,
                           0.08028167, -0.12339814, -0.32195632, -0.50715171, -0.67129779,
                          -0.80758169, -0.91034694, -0.97532829, -0.99982867, -0.9828312 ,
                          -0.92504137, -0.82885774, -0.6982724 , -0.53870529, -0.35677924,
                          -0.16004509,  0.04333173,  0.24491007,  0.43632343,  0.6096272 ,
                           0.75762842,  0.8741843 ,  0.9544572 ,  0.99511539,  0.99447137,
                           0.95255185,  0.8710967 ,  0.75348673,  0.60460332,  0.43062587,
                           0.23877532,  0.0370144 , -0.16628279, -0.36267843, -0.54402111])},
             {'marker': {'color': 'darkcyan', 'symbol': 'diamond'},
              'mode': 'markers',
              'name': 'cosine',
              'type': 'scatter',
              'x': array([ 0.        ,  0.20408163,  0.40816327,  0.6122449 ,  0.81632653,
                           1.02040816,  1.2244898 ,  1.42857143,  1.63265306,  1.83673469,
                           2.04081633,  2.24489796,  2.44897959,  2.65306122,  2.85714286,
                           3.06122449,  3.26530612,  3.46938776,  3.67346939,  3.87755102,
                           4.08163265,  4.28571429,  4.48979592,  4.69387755,  4.89795918,
                           5.10204082,  5.30612245,  5.51020408,  5.71428571,  5.91836735,
                           6.12244898,  6.32653061,  6.53061224,  6.73469388,  6.93877551,
                           7.14285714,  7.34693878,  7.55102041,  7.75510204,  7.95918367,
                           8.16326531,  8.36734694,  8.57142857,  8.7755102 ,  8.97959184,
                           9.18367347,  9.3877551 ,  9.59183673,  9.79591837, 10.        ]),
              'xaxis': 'x2',
              'y': array([ 1.        ,  0.97924752,  0.91785141,  0.81835992,  0.68490244,
                           0.52301811,  0.33942593,  0.1417459 , -0.0618173 , -0.26281476,
                          -0.45290412, -0.6241957 , -0.76958007, -0.88302305, -0.9598162 ,
                          -0.99677222, -0.99235724, -0.94675453, -0.8618568 , -0.74118774,
                          -0.58975572, -0.41384591, -0.22075945, -0.01851037,  0.18450698,
                           0.37986637,  0.55945943,  0.71583215,  0.84249428,  0.93418872,
                           0.98710971,  0.99906074,  0.9695458 ,  0.8997899 ,  0.79268826,
                           0.65268613,  0.48559429,  0.29834787,  0.09871854, -0.10500809,
                          -0.30437638, -0.49111153, -0.65746312, -0.79652673, -0.90253053,
                          -0.97107484, -0.99931473, -0.98607811, -0.93191435, -0.83907153]),
              'yaxis': 'y2'}],
    'layout': {'font': {'color': 'grey', 'family': 'times', 'size': 18},
               'template': '...',
               'title': {'text': 'Example with subplots'},
               'xaxis': {'anchor': 'y',
                         'domain': [0.0, 0.44],
                         'linecolor': 'grey',
                         'range': [0, 10],
                         'showline': False,
                         'ticks': 'inside',
                         'title': {'text': 'x-specified'}},
               'xaxis2': {'anchor': 'y2',
                          'domain': [0.56, 1.0],
                          'linecolor': 'grey',
                          'range': [0, 10],
                          'showline': False,
                          'ticks': 'inside',
                          'title': {'text': 'x-specified'}},
               'yaxis': {'anchor': 'x',
                         'color': '#FF00FF',
                         'domain': [0.0, 1.0],
                         'title': {'text': 'intensity'},
                         'zeroline': True,
                         'zerolinecolor': 'grey'},
               'yaxis2': {'anchor': 'x2',
                          'color': 'darkcyan',
                          'domain': [0.0, 1.0],
                          'zeroline': True,
                          'zerolinecolor': 'grey'}}
})
\end{lstlisting}
The very first thing to note is that the Figure object \textit{appears} to hold information inside of dictionaries.  This is \textit{sort of} true.  However, the Figure object is its own data structure, and so you cannot always interact with it in the way you would a dictionary.  However, for the most part, trying to interact with it as a dictionary is a reasonable approach to start with. 

The first object is given the \lstinline{data} keyword, and holds information on the data. This object is associated with a list, where there is one entry for each trace.  These entries are also dictionary-like, and contain a number of keywords specifying what and how the trace will be rendered.  In our example, the first entry is of the type `scatter' and has information on the name, the mode for the display (`lines') and specification for the way in which these lines will be drawn. However, there is also information on the x and y data, where the data is directly given.  This is super convenient, as we can always pull the data that we are interested in directly from a figure! For instance, \lstinline{sincosplot['data'][0]['x']} would output the $x$-data for the first entry in the data dictionary within the sincosplot Figure object. 

One other critical piece of information in the \lstinline{data} part of the Figure object occurs when data is referenced to a specific subplot.  For instance, the marker version of the data is shown in the first row, second column. The axes on the subplots are numbered, and this subplot has the axes \lstinline{x2} and \lstinline{y2}. You can see that the second entry in the data structure of the Figure object includes these designations. So, this is a way to know where data is plotted in a complex figure.  However, there is even more: we can \textit{change} where a trace is drawn by changing these designations directly.  The axes on the first subplot are \lstinline{x} and \lstinline{y}. So we can use the commands \lstinline{sincosplot['data'][0]['xaxis'] = 'x2'} and \lstinline{sincosplot['data'][0]['yaxis'] = 'y2'} to change the axes to which the data is assigned and move the data that was plotted on the first subplot to the second subplot. 

The other top-level container within the Figure object is \lstinline{layout}. Layout is another dictionary-like object, and it contains information on the styling of the plot, including information on the font, the template, the title of the plot. Additionally, this is where the identity of the axes is stored, including their format. So, we can again go in and directly change any of these. 

Despite all of the above utility \textbf{there is one thing you cannot do: you cannot simply add a trace object}. That is, you cannot create a dictionary that looks like a well-formatted trace object (with type, data, axes, etc) and add it to the data structure.  If you do, you will find that the apparent list is actually a tuple, and so we cannot add or remove things from it.  At the best, we can add only subsets and permutations of the current data object. Thus, the only way to add a trace is to use the \lstinline{add_<trace type>()} methods of the Figure object, as described above. 


\section{Other tasks}
\setcounter{subsection}{-1}  % Start subsections from 0

There are many other tasks that you might like to do when working with Plotly, and we will outline just a few here.

\subsection{Making insets}

It is common to desire to make one figure inside another figure---an inset.  There are two ways to accomplish this directly in Plotly, though neither are super straightforward.
\begin{itemize}
    \item You can create a large number of subplots, create the make figure to span all these subplots, and then just add the inset to the subplot that is in the place you want it.  For instance, you could make subplots that are given by \lstinline{rows = 4, cols = 4}. You could then place a subplot in \lstinline{row = 1, col = 1} and have it span 4 rows and columns.  This figure will occupy the entire figure canvas.  Then you could add another subplot in \lstinline{row = 4, col = 1} and it will sit in the top right corner of the plotting canvas---the top right corner of the subplot spanning the entire figure canvas. 

    \item You can add multiple axes and then use the \lstinline{domain} keyword for the axes, to control where they appear on the plot.  We will not go into more detail here, but the usage can be found in Plotly's online documentation. 
\end{itemize}


\section{The \texttt{codechembook} Plotly wrappers}

As a final note, we have also written wrappers that produce Plotly images quickly, focusing on the types of plots that we, as experimental chemists, often make. These are included in the \lstinline{quickPlots} module of our codechembook library and there are many examples of its usage throughout the Narrative chapters, starting with Chapter \ref{05CompFit}. The ones we think you will use most are: 
\lstinline{quickScatter()}, 
\lstinline{quickBar()},
\lstinline{quickHist()},
and \lstinline{plotFit()}



\end{document}