{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"authorship_tag":"ABX9TyNqpViyago/JXFficnYyZP7"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","source":["# Plotly Mechanics\n","\n","Plotly.js, the JavaScript library `plotly` is based on understands figures as trees with named nodes called attributes. The root node of the tree has three top-level attributes.\n","\n","- The top-level ***`data`*** attribute consists of a list of dicts referred to as traces.\n"," - Each trace has a plot type (scatter, bar, pie, etc.), and is drawn on a single subplot. Traces can have a single legend, and other attributes depending on trace type.\n","\n","- The top-level ***`layout`*** attribute is referred to as \"the layout\" and consists of a dict with attributes that control non-data parts of the figure. Parts of the figure governed by the `layout` attribute include:\n"," - Dimensions and margins\n"," - Templates, fonts, colors, hover labels\n"," - Titles and legends\n"," - Non-data marks such as annotations, shapes, and images\n"," - Controls like buttons, toggles, menus, or sliders\n","\n","- The top-level ***`frames`*** attribute does not exist for all types of plots. `frames` consists of a list of dicts that define sequential frames in an animated plot. Each frame in the sequence has its own `data` attribute (and other parameters).\n","\n","When building a figure, you do not have to populate every attribute of every object. The JavaScript layer can compute default values for some unspecified attributes.\n","\n","Let's look at an example for a simple line plot, using `plotly`:"],"metadata":{"id":"mSrqJA12YpJj"}},{"cell_type":"code","source":["import plotly.express as px # import statement\n","fig = px.line(x=[\"a\",\"b\",\"c\"], y=[1,3,2], title=\"sample figure\") # figure with sample data\n","fig # show figure"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":542},"id":"Lr3BUpN6YuE2","executionInfo":{"status":"ok","timestamp":1706148950528,"user_tz":300,"elapsed":160,"user":{"displayName":"Katherine Walden","userId":"17094108395123900917"}},"outputId":"b1c2ee38-46c7-4d6b-fefd-b16680dbd60b"},"execution_count":7,"outputs":[{"output_type":"display_data","data":{"text/html":["\n","\n","\n","
\n","
\n","\n",""]},"metadata":{}}]},{"cell_type":"code","source":["print(fig) # show back-end data for this figure"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"FRgoAuLBY7PM","executionInfo":{"status":"ok","timestamp":1706148752712,"user_tz":300,"elapsed":121,"user":{"displayName":"Katherine Walden","userId":"17094108395123900917"}},"outputId":"e808afc0-9735-43f9-a3f4-49d15337d3d9"},"execution_count":6,"outputs":[{"output_type":"stream","name":"stdout","text":["Figure({\n"," 'data': [{'hovertemplate': 'x=%{x}
y=%{y}',\n"," 'legendgroup': '',\n"," 'line': {'color': '#636efa', 'dash': 'solid'},\n"," 'marker': {'symbol': 'circle'},\n"," 'mode': 'lines',\n"," 'name': '',\n"," 'orientation': 'v',\n"," 'showlegend': False,\n"," 'type': 'scatter',\n"," 'x': array(['a', 'b', 'c'], dtype=object),\n"," 'xaxis': 'x',\n"," 'y': array([1, 3, 2]),\n"," 'yaxis': 'y'}],\n"," 'layout': {'legend': {'tracegroupgap': 0},\n"," 'template': '...',\n"," 'title': {'text': 'sample figure'},\n"," 'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'x'}},\n"," 'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'y'}}}\n","})\n"]}]},{"cell_type":"markdown","source":["The JSON object generated as part of `plotly`'s back-end process:\n","```\n","Figure({\n"," 'data': [{'hovertemplate': 'x=%{x}
y=%{y}',\n"," 'legendgroup': '',\n"," 'line': {'color': '#636efa', 'dash': 'solid'},\n"," 'mode': 'lines',\n"," 'name': '',\n"," 'orientation': 'v',\n"," 'showlegend': False,\n"," 'type': 'scatter',\n"," 'x': array(['a', 'b', 'c'], dtype=object),\n"," 'xaxis': 'x',\n"," 'y': array([1, 3, 2]),\n"," 'yaxis': 'y'}],\n"," 'layout': {'legend': {'tracegroupgap': 0},\n"," 'template': '...',\n"," 'title': {'text': 'sample figure'},\n"," 'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'x'}},\n"," 'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'y'}}}\n","})\n","```\n","\n","We can use `fig.to_dict()` and `fig.to_json()` to represent the back-end of a `plotly` figure as a dictionary or JSON object, respectively.\n","\n","A few notes on this figure structure:\n","- 2D Cartesian coordinate system subplots are the most commonly-used type of subplot. In `plotly`, traces compatible with these subplots support `xaxis` and `yaxis` attributes. Trace types compatible with 2D cartesian subplots include scatterplots, bar charts, histograms, and box plots.\n","\n","- Both `X` and `Y` axes support a `type` attribute. The `type` attribute can modify a trace to show continuous values, temporal values, or categorical values."],"metadata":{"id":"VvTwZ8ozZBGe"}},{"cell_type":"markdown","source":["## Additional Resources\n","\n","- Figure data structure: [`plotly`, \"The Figure Data Structure in Python\"](https://plotly.com/python/figure-structure/)\n","- `plotly` fundamental syntax: [Plotly Python Open Source Graphing Library Fundamentals](https://plotly.com/python/plotly-fundamentals/)"],"metadata":{"id":"rhF6taIAZCI3"}}]}