plotly-1.9.5+dfsg.orig/0000755000175000017500000000000012647020776014272 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/README.rst0000644000175000017500000000634012645550357015765 0ustar noahfxnoahfx======= plotly: ======= -------------------------- It's all about the graphs. -------------------------- The Nutshell ~~~~~~~~~~~~ Use this package to make collaborative, interactive, publication-quality graphs from Python. Here's how you import:: import plotly.plotly as py # for sending things to plotly import plotly.tools as tls # for mpl, config, etc. from plotly.graph_objs import * # __all__ is safely defined Here's how you sign in:: py.sign_in('PythonAPI', 'ubpiol2cve') # get your own at https://plot.ly/ Here's how you plot data or a figure:: py.plot(data_or_figure_here) Here's what you get: * an account on plotly * a unique url for your data/figures * an interactive web-application to edit your figure or make new figures * a platform on which to share your data/figures with the world You can also convert supported matplotlib figures:: py.plot_mpl(mplfig) Stop fighting with your figures; start designing them. Check out our Quickstart_ to get going. About ~~~~~ Plotly_ is an online collaborative data analysis and graphing tool. The Python API allows you to access all of Plotly's functionality from Python. Plotly figures are shared, tracked, and edited all online and the data is always accessible from the graph. That's it. Find out more, sign up, and start sharing by visiting us at https://plot.ly. Install via pip ~~~~~~~~~~~~~~~ Assuming you have already installed pip, you can simply enter the following in a terminal program:: $ pip install plotly Contributing! ~~~~~~~~~~~~~ If you want to contribute to making Plotly's Python API experience better, head to our `GitHub repo`_. Instructions for installing from here, updating the included submodules, and contributing are detailed there! Plotly, matplotlib, and mpld3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The matplotlylib sub-package allows you to convert matplotlib figures to plotly figures, with a one-liner:: py.plot_mpl(fig) Checkout the `Plotly and mpld3`_ IPython notebook for more infomataion. Introduction to working with out API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checkout the `Plotly and Python`_ IPython notebook to get a more in depth exposition of our Python API. Plotly's *guide book* ~~~~~~~~~~~~~~~~~~~~~ Still here? Don't worry, we've got more documentation for you. Checkout a *highly* complete `set of notebooks`_ for walk-throughs on all the features we offer! Details ~~~~~~~ The plotly package depends on requests, which will be installed by pip for you. To use the matplotlylib subpackage, you'll also need to have matplotlib 1.3.1 properly installed on your machine. The matpotlylib package is based on the mplexporter framework for crawling and exporting matplotlib images. Created by: Plotly_, `@plotlygraphs`_, `feedback@plot.ly`_ License: MIT .. _Plotly: https://plot.ly .. _Quickstart: https://plot.ly/python .. _GitHub repo: https://github.com/plotly/python-api .. _Plotly and mpld3: https://plot.ly/python/matplotlib-to-plotly-tutorial/ .. _Plotly and Python: https://plot.ly/python/overview/ .. _set of notebooks: https://plot.ly/python/user-guide/ .. _plotly profile: https://plot.ly/~mpld3/ .. _@plotlygraphs: https://twitter.com/plotlygraphs .. _feedback@plot.ly: feedback@plot.ly plotly-1.9.5+dfsg.orig/PKG-INFO0000644000175000017500000001142312647020776015370 0ustar noahfxnoahfxMetadata-Version: 1.1 Name: plotly Version: 1.9.5 Summary: Python plotting library for collaborative, interactive, publication-quality graphs. Home-page: https://plot.ly/python/ Author: Chris P Author-email: chris@plot.ly License: MIT Description: ======= plotly: ======= -------------------------- It's all about the graphs. -------------------------- The Nutshell ~~~~~~~~~~~~ Use this package to make collaborative, interactive, publication-quality graphs from Python. Here's how you import:: import plotly.plotly as py # for sending things to plotly import plotly.tools as tls # for mpl, config, etc. from plotly.graph_objs import * # __all__ is safely defined Here's how you sign in:: py.sign_in('PythonAPI', 'ubpiol2cve') # get your own at https://plot.ly/ Here's how you plot data or a figure:: py.plot(data_or_figure_here) Here's what you get: * an account on plotly * a unique url for your data/figures * an interactive web-application to edit your figure or make new figures * a platform on which to share your data/figures with the world You can also convert supported matplotlib figures:: py.plot_mpl(mplfig) Stop fighting with your figures; start designing them. Check out our Quickstart_ to get going. About ~~~~~ Plotly_ is an online collaborative data analysis and graphing tool. The Python API allows you to access all of Plotly's functionality from Python. Plotly figures are shared, tracked, and edited all online and the data is always accessible from the graph. That's it. Find out more, sign up, and start sharing by visiting us at https://plot.ly. Install via pip ~~~~~~~~~~~~~~~ Assuming you have already installed pip, you can simply enter the following in a terminal program:: $ pip install plotly Contributing! ~~~~~~~~~~~~~ If you want to contribute to making Plotly's Python API experience better, head to our `GitHub repo`_. Instructions for installing from here, updating the included submodules, and contributing are detailed there! Plotly, matplotlib, and mpld3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The matplotlylib sub-package allows you to convert matplotlib figures to plotly figures, with a one-liner:: py.plot_mpl(fig) Checkout the `Plotly and mpld3`_ IPython notebook for more infomataion. Introduction to working with out API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checkout the `Plotly and Python`_ IPython notebook to get a more in depth exposition of our Python API. Plotly's *guide book* ~~~~~~~~~~~~~~~~~~~~~ Still here? Don't worry, we've got more documentation for you. Checkout a *highly* complete `set of notebooks`_ for walk-throughs on all the features we offer! Details ~~~~~~~ The plotly package depends on requests, which will be installed by pip for you. To use the matplotlylib subpackage, you'll also need to have matplotlib 1.3.1 properly installed on your machine. The matpotlylib package is based on the mplexporter framework for crawling and exporting matplotlib images. Created by: Plotly_, `@plotlygraphs`_, `feedback@plot.ly`_ License: MIT .. _Plotly: https://plot.ly .. _Quickstart: https://plot.ly/python .. _GitHub repo: https://github.com/plotly/python-api .. _Plotly and mpld3: https://plot.ly/python/matplotlib-to-plotly-tutorial/ .. _Plotly and Python: https://plot.ly/python/overview/ .. _set of notebooks: https://plot.ly/python/user-guide/ .. _plotly profile: https://plot.ly/~mpld3/ .. _@plotlygraphs: https://twitter.com/plotlygraphs .. _feedback@plot.ly: feedback@plot.ly Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Topic :: Scientific/Engineering :: Visualization plotly-1.9.5+dfsg.orig/setup.py0000644000175000017500000000303512645550357016006 0ustar noahfxnoahfxfrom setuptools import setup exec (open('plotly/version.py').read()) def readme(): with open('README.rst') as f: return f.read() setup(name='plotly', version=__version__, use_2to3=False, author='Chris P', author_email='chris@plot.ly', maintainer='Chris P', maintainer_email='chris@plot.ly', url='https://plot.ly/python/', description="Python plotting library for collaborative, " "interactive, publication-quality graphs.", long_description=readme(), classifiers=[ 'Development Status :: 4 - Beta', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Topic :: Scientific/Engineering :: Visualization', ], license='MIT', packages=['plotly', 'plotly/plotly', 'plotly/plotly/chunked_requests', 'plotly/graph_objs', 'plotly/grid_objs', 'plotly/widgets', 'plotly/offline', 'plotly/matplotlylib', 'plotly/matplotlylib/mplexporter', 'plotly/matplotlylib/mplexporter/renderers'], package_data={'plotly': ['graph_reference/*.json', 'widgets/*.js', 'offline/*.js']}, install_requires=['requests', 'six', 'pytz'], zip_safe=False) plotly-1.9.5+dfsg.orig/plotly/0000755000175000017500000000000012647020776015615 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/grid_objs/0000755000175000017500000000000012647020776017557 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/grid_objs/__init__.py0000644000175000017500000000017212645550357021671 0ustar noahfxnoahfx"""" grid_objs ========= """ from __future__ import absolute_import from plotly.grid_objs.grid_objs import Grid, Column plotly-1.9.5+dfsg.orig/plotly/grid_objs/grid_objs.py0000644000175000017500000001336212645550357022101 0ustar noahfxnoahfx""" grid_objs ========= """ from __future__ import absolute_import import json from collections import MutableSequence from plotly import exceptions, utils __all__ = None class Column(object): """ Columns make up Plotly Grids and can be the source of data for Plotly Graphs. They have a name and an array of data. They can be uploaded to Plotly with the `plotly.plotly.grid_ops` class. Usage example 1: Upload a set of columns as a grid to Plotly ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') ``` Usage example 2: Make a graph based with data that is sourced from a newly uploaded Plotly columns ``` import plotly.plotly as py from plotly.grid_objs import Grid, Column from plotly.graph_objs import Scatter # Upload a grid column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') # Build a Plotly graph object sourced from the # grid's columns trace = Scatter(xsrc=grid[0], ysrc=grid[1]) py.plot([trace], filename='graph from grid') ``` """ def __init__(self, data, name): """ Initialize a Plotly column with `data` and `name`. `data` is an array of strings, numbers, or dates. `name` is the name of the column as it will apppear in the Plotly grid. Names must be unique to a grid. """ # TODO: data type checking self.data = data # TODO: name type checking self.name = name self.id = '' def __str__(self): max_chars = 10 jdata = json.dumps(self.data, cls=utils.PlotlyJSONEncoder) if len(jdata) > max_chars: data_string = jdata[:max_chars] + "...]" else: data_string = jdata string = '' return string.format(name=self.name, data=data_string, id=self.id) def __repr__(self): return 'Column("{0}", {1})'.format(self.data, self.name) def to_plotly_json(self): return {'name': self.name, 'data': self.data} class Grid(MutableSequence): """ Grid is Plotly's Python representation of Plotly Grids. Plotly Grids are tabular data made up of columns. They can be uploaded, appended to, and can source the data for Plotly graphs. A plotly.grid_objs.Grid object is essentially a list. Usage example 1: Upload a set of columns as a grid to Plotly ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') ``` Usage example 2: Make a graph based with data that is sourced from a newly uploaded Plotly columns ``` import plotly.plotly as py from plotly.grid_objs import Grid, Column from plotly.graph_objs import Scatter # Upload a grid column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') # Build a Plotly graph object sourced from the # grid's columns trace = Scatter(xsrc=grid[0], ysrc=grid[1]) py.plot([trace], filename='graph from grid') ``` """ def __init__(self, iterable_of_columns): """ Initialize a grid with an iterable of `plotly.grid_objs.Column objects Usage example: ``` column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) ``` """ # TODO: verify that columns are actually columns column_names = [column.name for column in iterable_of_columns] duplicate_name = utils.get_first_duplicate(column_names) if duplicate_name: err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name) raise exceptions.InputError(err) self._columns = list(iterable_of_columns) self.id = '' def __repr__(self): return self._columns.__repr__() def __getitem__(self, index): return self._columns[index] def __setitem__(self, index, column): self._validate_insertion(column) return self._columns.__setitem__(index, column) def __delitem__(self, index): del self._columns[index] def __len__(self): return len(self._columns) def insert(self, index, column): self._validate_insertion(column) self._columns.insert(index, column) def _validate_insertion(self, column): """ Raise an error if we're gonna add a duplicate column name """ existing_column_names = [col.name for col in self._columns] if column.name in existing_column_names: err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(column.name) raise exceptions.InputError(err) def _to_plotly_grid_json(self): grid_json = {'cols': {}} for column_index, column in enumerate(self): grid_json['cols'][column.name] = { 'data': column.data, 'order': column_index } return grid_json def get_column(self, column_name): """ Return the first column with name `column_name`. If no column with `column_name` exists in this grid, return None. """ for column in self._columns: if column.name == column_name: return column plotly-1.9.5+dfsg.orig/plotly/graph_reference/0000755000175000017500000000000012647020776020734 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/graph_reference/default-schema.json0000644000175000017500000276156212647020762024527 0ustar noahfxnoahfx{ "defs": { "metaKeys": [ "_isSubplotObj", "_isLinkedToArray", "_deprecated", "description", "role" ], "valObjects": { "angle": { "description": "A number (in degree) between -180 and 180.", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "any": { "description": "Any type.", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "axisid": { "description": "An axis id string (e.g. 'x', 'x2', 'x3', ...).", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "boolean": { "description": "A boolean (true/false) value.", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "color": { "description": "A string describing color. Supported formats: - hex (e.g. '#d3d3d3') - rgb (e.g. 'rgb(255, 0, 0)') - rgba (e.g. 'rgb(255, 0, 0, 0.5)') - hsl (e.g. 'hsl(0, 100%, 50%)') - hsv (e.g. 'hsv(0, 100%, 100%)') - named colors (full list: http://www.w3.org/TR/css3-color/#svg-color)", "otherOpts": [ "dflt", "arrayOk" ], "requiredOpts": [] }, "colorscale": { "description": "A Plotly colorscale either picked by a name: (any of Greys, YIGnBu, Greens, YIOrRd, Bluered, RdBu, Reds, Blues, Picnic, Rainbow, Portland, Jet, Hot, Blackbody, Earth, Electric, Viridis ) customized as an {array} of 2-element {arrays} where the first element is the normalized color level value (starting at *0* and ending at *1*), and the second item is a valid color string.", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "data_array": { "description": "An {array} of data. The value MUST be an {array}, or we ignore it.", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "enumerated": { "description": "Enumerated value type. The available values are listed in `values`.", "otherOpts": [ "dflt", "coerceNumber", "arrayOk" ], "requiredOpts": [ "values" ] }, "flaglist": { "description": "A string representing a combination of flags (order does not matter here). Combine any of the available `flags` with *+*. (e.g. ('lines+markers')). Values in `extras` cannot be combined.", "otherOpts": [ "dflt", "extras" ], "requiredOpts": [ "flags" ] }, "geoid": { "description": "A geo id string (e.g. 'geo', 'geo2', 'geo3', ...).", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "info_array": { "description": "An {array} of plot information.", "otherOpts": [ "dflt" ], "requiredOpts": [ "items" ] }, "integer": { "description": "An integer or an integer inside a string. When applicable, values greater (less) than `max` (`min`) are coerced to the `dflt`.", "otherOpts": [ "dflt", "min", "max" ], "requiredOpts": [] }, "number": { "description": "A number or a numeric value (e.g. a number inside a string). When applicable, values greater (less) than `max` (`min`) are coerced to the `dflt`.", "otherOpts": [ "dflt", "min", "max", "arrayOk" ], "requiredOpts": [] }, "sceneid": { "description": "A scene id string (e.g. 'scene', 'scene2', 'scene3', ...).", "otherOpts": [ "dflt" ], "requiredOpts": [] }, "string": { "description": "A string value. Numbers are converted to strings except for attributes with `strict` set to true.", "otherOpts": [ "dflt", "noBlank", "strict", "arrayOk", "values" ], "requiredOpts": [] } } }, "layout": { "layoutAttributes": { "angularaxis": { "domain": { "description": "Polar chart subplots are not supported yet. This key has currently no effect.", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "endpadding": { "role": "style", "valType": "number" }, "range": { "description": "Defines the start and end point of this angular axis.", "items": [ { "dflt": 0, "valType": "number" }, { "dflt": 360, "valType": "number" } ], "role": "info", "valType": "info_array" }, "role": "object", "showline": { "description": "Determines whether or not the line bounding this angular axis will be shown on the figure.", "role": "style", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the angular axis ticks will feature tick labels.", "role": "style", "valType": "boolean" }, "tickcolor": { "description": "Sets the color of the tick lines on this angular axis.", "role": "style", "valType": "color" }, "ticklen": { "description": "Sets the length of the tick lines on this angular axis.", "min": 0, "role": "style", "valType": "number" }, "tickorientation": { "description": "Sets the orientation (from the paper perspective) of the angular axis tick labels.", "role": "style", "valType": "enumerated", "values": [ "horizontal", "vertical" ] }, "ticksuffix": { "description": "Sets the length of the tick lines on this angular axis.", "role": "style", "valType": "string" }, "visible": { "description": "Determines whether or not this axis will be visible.", "role": "info", "valType": "boolean" } }, "annotations": { "items": { "annotation": { "_deprecated": { "ref": { "description": "Obsolete. Set `xref` and `yref` separately instead.", "role": "info", "valType": "string" } }, "align": { "description": "Sets the vertical alignment of the `text` with respect to the set `x` and `y` position. Has only an effect if `text` spans more two or more lines (i.e. `text` contains one or more
HTML tags).", "dflt": "center", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "arrowcolor": { "description": "Sets the color of the annotation arrow.", "role": "style", "valType": "color" }, "arrowhead": { "description": "Sets the annotation arrow head style.", "dflt": 1, "max": 8, "min": 0, "role": "style", "valType": "integer" }, "arrowsize": { "description": "Sets the size (in px) of annotation arrow head.", "dflt": 1, "min": 0.3, "role": "style", "valType": "number" }, "arrowwidth": { "description": "Sets the width (in px) of annotation arrow.", "min": 0.1, "role": "style", "valType": "number" }, "ax": { "description": "Sets the x component of the arrow tail about the arrow head. A positive (negative) component corresponds to an arrow pointing from right to left (left to right)", "dflt": -10, "role": "info", "valType": "number" }, "ay": { "description": "Sets the y component of the arrow tail about the arrow head. A positive (negative) component corresponds to an arrow pointing from bottom to top (top to bottom)", "dflt": -30, "role": "info", "valType": "number" }, "bgcolor": { "description": "Sets the background color of the annotation.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the color of the border enclosing the annotation `text`.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "borderpad": { "description": "Sets the padding (in px) between the `text` and the enclosing border.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "borderwidth": { "description": "Sets the width (in px) of the border enclosing the annotation `text`.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "font": { "color": { "role": "style", "valType": "color" }, "description": "Sets the annotation text font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "opacity": { "description": "Sets the opacity of the annotation (text + arrow).", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showarrow": { "description": "Determines whether or not the annotation is drawn with an arrow. If *true*, `text` is placed near the arrow's tail. If *false*, `text` lines up with the `x` and `y` provided.", "dflt": true, "role": "style", "valType": "boolean" }, "text": { "description": "Sets the text associated with this annotation. Plotly uses a subset of HTML tags to do things like newline (
), bold (), italics (), hyperlinks (). Tags , , are also supported.", "role": "info", "valType": "string" }, "textangle": { "description": "Sets the angle at which the `text` is drawn with respect to the horizontal.", "dflt": 0, "role": "style", "valType": "angle" }, "x": { "description": "Sets the annotation's x position. Note that dates and categories are converted to numbers.", "role": "info", "valType": "number" }, "xanchor": { "description": "Sets the annotation's horizontal position anchor This anchor binds the `x` position to the *left*, *center* or *right* of the annotation. For example, if `x` is set to 1, `xref` to *paper* and `xanchor` to *right* then the right-most portion of the annotation lines up with the right-most edge of the plotting area. If *auto*, the anchor is equivalent to *center* for data-referenced annotations whereas for paper-referenced, the anchor picked corresponds to the closest side.", "dflt": "auto", "role": "info", "valType": "enumerated", "values": [ "auto", "left", "center", "right" ] }, "xref": { "description": "Sets the annotation's x coordinate axis. If set to an x axis id (e.g. *x* or *x2*), the `x` position refers to an x coordinate If set to *paper*, the `x` position refers to the distance from the left side of the plotting area in normalized coordinates where 0 (1) corresponds to the left (right) side.", "role": "info", "valType": "enumerated", "values": [ "paper", "/^x([2-9]|[1-9][0-9]+)?$/" ] }, "y": { "description": "Sets the annotation's y position. Note that dates and categories are converted to numbers.", "role": "info", "valType": "number" }, "yanchor": { "description": "Sets the annotation's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the annotation. For example, if `y` is set to 1, `yref` to *paper* and `yanchor` to *top* then the top-most portion of the annotation lines up with the top-most edge of the plotting area. If *auto*, the anchor is equivalent to *middle* for data-referenced annotations whereas for paper-referenced, the anchor picked corresponds to the closest side.", "dflt": "auto", "role": "info", "valType": "enumerated", "values": [ "auto", "top", "middle", "bottom" ] }, "yref": { "description": "Sets the annotation's y coordinate axis. If set to an y axis id (e.g. *y* or *y2*), the `y` position refers to an y coordinate If set to *paper*, the `y` position refers to the distance from the bottom of the plotting area in normalized coordinates where 0 (1) corresponds to the bottom (top).", "role": "info", "valType": "enumerated", "values": [ "paper", "/^y([2-9]|[1-9][0-9]+)?$/" ] } } }, "role": "object" }, "autosize": { "description": "Determines whether or not the dimensions of the figure are computed as a function of the display size.", "role": "info", "valType": "enumerated", "values": [ true, false, "initial" ] }, "direction": { "description": "For polar plots only. Sets the direction corresponding to positive angles.", "role": "info", "valType": "enumerated", "values": [ "clockwise", "counterclockwise" ] }, "dragmode": { "description": "Determines the mode of drag interactions. *select* and *lasso* apply only to scatter traces with markers or text. *orbit* and *turntable* apply only to 3D scenes.", "role": "info", "valType": "enumerated", "values": [ "zoom", "pan", "select", "lasso", "orbit", "turntable" ] }, "font": { "color": { "dflt": "#444", "role": "style", "valType": "color" }, "description": "Sets the global font. Note that fonts used in traces and other layout components inherit from the global font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "dflt": "\"Open Sans\", verdana, arial, sans-serif", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "dflt": 12, "min": 1, "role": "style", "valType": "number" } }, "geo": { "_isSubplotObj": true, "bgcolor": { "description": "Set the background color of the map", "dflt": "#fff", "role": "style", "valType": "color" }, "coastlinecolor": { "description": "Sets the coastline color.", "dflt": "#444", "role": "style", "valType": "color" }, "coastlinewidth": { "description": "Sets the coastline stroke width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "countrycolor": { "description": "Sets line color of the country boundaries.", "dflt": "#444", "role": "style", "valType": "color" }, "countrywidth": { "description": "Sets line width (in px) of the country boundaries.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "domain": { "role": "object", "x": { "description": "Sets the horizontal domain of this map (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "y": { "description": "Sets the vertical domain of this map (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" } }, "framecolor": { "description": "Sets the color the frame.", "dflt": "#444", "role": "style", "valType": "color" }, "framewidth": { "description": "Sets the stroke width (in px) of the frame.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lakecolor": { "description": "Sets the color of the lakes.", "dflt": "#3399FF", "role": "style", "valType": "color" }, "landcolor": { "description": "Sets the land mass color.", "dflt": "#F0DC82", "role": "style", "valType": "color" }, "lataxis": { "dtick": { "description": "Sets the graticule's longitude/latitude tick step.", "role": "info", "valType": "number" }, "gridcolor": { "description": "Sets the graticule's stroke color.", "dflt": "#eee", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the graticule's stroke width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "range": { "description": "Sets the range of this axis (in degrees).", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "role": "object", "showgrid": { "description": "Sets whether or not graticule are shown on the map.", "dflt": false, "role": "info", "valType": "boolean" }, "tick0": { "description": "Sets the graticule's starting tick longitude/latitude.", "role": "info", "valType": "number" } }, "lonaxis": { "dtick": { "description": "Sets the graticule's longitude/latitude tick step.", "role": "info", "valType": "number" }, "gridcolor": { "description": "Sets the graticule's stroke color.", "dflt": "#eee", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the graticule's stroke width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "range": { "description": "Sets the range of this axis (in degrees).", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "role": "object", "showgrid": { "description": "Sets whether or not graticule are shown on the map.", "dflt": false, "role": "info", "valType": "boolean" }, "tick0": { "description": "Sets the graticule's starting tick longitude/latitude.", "role": "info", "valType": "number" } }, "oceancolor": { "description": "Sets the ocean color", "dflt": "#3399FF", "role": "style", "valType": "color" }, "projection": { "parallels": { "description": "For conic projection types only. Sets the parallels (tangent, secant) where the cone intersects the sphere.", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "role": "object", "rotation": { "lat": { "description": "Rotates the map along meridians (in degrees North).", "role": "info", "valType": "number" }, "lon": { "description": "Rotates the map along parallels (in degrees East).", "role": "info", "valType": "number" }, "role": "object", "roll": { "description": "Roll the map (in degrees) For example, a roll of *180* makes the map appear upside down.", "role": "info", "valType": "number" } }, "scale": { "description": "Zooms in or out on the map view.", "dflt": 1, "max": 10, "min": 0, "role": "info", "valType": "number" }, "type": { "description": "Sets the projection type.", "role": "info", "valType": "enumerated", "values": [ "equirectangular", "mercator", "orthographic", "natural earth", "kavrayskiy7", "miller", "robinson", "eckert4", "azimuthal equal area", "azimuthal equidistant", "conic equal area", "conic conformal", "conic equidistant", "gnomonic", "stereographic", "mollweide", "hammer", "transverse mercator", "albers usa" ] } }, "resolution": { "coerceNumber": true, "description": "Sets the resolution of the base layers. The values have units of km/mm e.g. 110 corresponds to a scale ratio of 1:110,000,000.", "dflt": 110, "role": "info", "valType": "enumerated", "values": [ 110, 50 ] }, "rivercolor": { "description": "Sets color of the rivers.", "dflt": "#3399FF", "role": "style", "valType": "color" }, "riverwidth": { "description": "Sets the stroke width (in px) of the rivers.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "scope": { "description": "Set the scope of the map.", "dflt": "world", "role": "info", "valType": "enumerated", "values": [ "world", "usa", "europe", "asia", "africa", "north america", "south america" ] }, "showcoastlines": { "description": "Sets whether or not the coastlines are drawn.", "role": "info", "valType": "boolean" }, "showcountries": { "description": "Sets whether or not country boundaries are drawn.", "role": "info", "valType": "boolean" }, "showframe": { "description": "Sets whether or not a frame is drawn around the map.", "role": "info", "valType": "boolean" }, "showlakes": { "description": "Sets whether or not lakes are drawn.", "dflt": false, "role": "info", "valType": "boolean" }, "showland": { "description": "Sets whether or not land masses are filled in color.", "dflt": false, "role": "info", "valType": "boolean" }, "showocean": { "description": "Sets whether or not oceans are filled in color.", "dflt": false, "role": "info", "valType": "boolean" }, "showrivers": { "description": "Sets whether or not rivers are drawn.", "dflt": false, "role": "info", "valType": "boolean" }, "showsubunits": { "description": "Sets whether or not boundaries of subunits within countries (e.g. states, provinces) are drawn.", "role": "info", "valType": "boolean" }, "subunitcolor": { "description": "Sets the color of the subunits boundaries.", "dflt": "#444", "role": "style", "valType": "color" }, "subunitwidth": { "description": "Sets the stroke width (in px) of the subunits boundaries.", "dflt": 1, "min": 0, "role": "style", "valType": "number" } }, "height": { "description": "Sets the plot's height (in px).", "dflt": 450, "min": 10, "role": "info", "valType": "number" }, "hidesources": { "description": "Determines whether or not a text link citing the data source is placed at the bottom-right cored of the figure. Has only an effect only on graphs that have been generated via forked graphs from the plotly service (at https://plot.ly or on-premise).", "dflt": false, "role": "info", "valType": "boolean" }, "hovermode": { "description": "Determines the mode of hover interactions.", "role": "info", "valType": "enumerated", "values": [ "x", "y", "closest", false ] }, "legend": { "bgcolor": { "description": "Sets the legend background color.", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the color of the border enclosing the legend.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) of the border enclosing the legend.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "font": { "color": { "role": "style", "valType": "color" }, "description": "Sets the font used to text the legend items.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "role": "object", "tracegroupgap": { "description": "Sets the amount of vertical space (in px) between legend groups.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "traceorder": { "description": "Determines the order at which the legend items are displayed. If *normal*, the items are displayed top-to-bottom in the same order as the input data. If *reversed*, the items are displayed in the opposite order as *normal*. If *grouped*, the items are displayed in groups (when a trace `legendgroup` is provided). if *grouped+reversed*, the items are displayed in the opposite order as *grouped*.", "extras": [ "normal" ], "flags": [ "reversed", "grouped" ], "role": "style", "valType": "flaglist" }, "x": { "description": "Sets the x position (in normalized coordinates) of the legend.", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets the legend's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the legend.", "dflt": "left", "role": "info", "valType": "enumerated", "values": [ "auto", "left", "center", "right" ] }, "y": { "description": "Sets the y position (in normalized coordinates) of the legend.", "dflt": 1, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets the legend's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the legend.", "dflt": "auto", "role": "info", "valType": "enumerated", "values": [ "auto", "top", "middle", "bottom" ] } }, "margin": { "autoexpand": { "dflt": true, "role": "info", "valType": "boolean" }, "b": { "description": "Sets the bottom margin (in px).", "dflt": 80, "min": 0, "role": "info", "valType": "number" }, "l": { "description": "Sets the left margin (in px).", "dflt": 80, "min": 0, "role": "info", "valType": "number" }, "pad": { "description": "Sets the amount of padding (in px) between the plotting area and the axis lines", "dflt": 0, "min": 0, "role": "info", "valType": "number" }, "r": { "description": "Sets the right margin (in px).", "dflt": 80, "min": 0, "role": "info", "valType": "number" }, "role": "object", "t": { "description": "Sets the top margin (in px).", "dflt": 100, "min": 0, "role": "info", "valType": "number" } }, "orientation": { "description": "For polar plots only. Rotates the entire polar by the given angle.", "role": "info", "valType": "angle" }, "paper_bgcolor": { "description": "Sets the color of paper where the graph is drawn.", "dflt": "#fff", "role": "style", "valType": "color" }, "plot_bgcolor": { "description": "Sets the color of plotting area in-between x and y axes.", "dflt": "#fff", "role": "style", "valType": "color" }, "radialaxis": { "domain": { "description": "Polar chart subplots are not supported yet. This key has currently no effect.", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "endpadding": { "role": "style", "valType": "number" }, "orientation": { "description": "Sets the orientation (an angle with respect to the origin) of the radial axis.", "role": "style", "valType": "number" }, "range": { "description": "Defines the start and end point of this radial axis.", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "role": "object", "showline": { "description": "Determines whether or not the line bounding this radial axis will be shown on the figure.", "role": "style", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the radial axis ticks will feature tick labels.", "role": "style", "valType": "boolean" }, "tickcolor": { "description": "Sets the color of the tick lines on this radial axis.", "role": "style", "valType": "color" }, "ticklen": { "description": "Sets the length of the tick lines on this radial axis.", "min": 0, "role": "style", "valType": "number" }, "tickorientation": { "description": "Sets the orientation (from the paper perspective) of the radial axis tick labels.", "role": "style", "valType": "enumerated", "values": [ "horizontal", "vertical" ] }, "ticksuffix": { "description": "Sets the length of the tick lines on this radial axis.", "role": "style", "valType": "string" }, "visible": { "description": "Determines whether or not this axis will be visible.", "role": "info", "valType": "boolean" } }, "scene": { "_deprecated": { "cameraposition": { "description": "Obsolete. Use `camera` instead.", "role": "info", "valType": "info_array" } }, "_isSubplotObj": true, "aspectmode": { "description": "If *cube*, this scene's axes are drawn as a cube, regardless of the axes' ranges. If *data*, this scene's axes are drawn in proportion with the axes' ranges. If *manual*, this scene's axes are drawn in proportion with the input of *aspectratio* (the default behavior if *aspectratio* is provided). If *auto*, this scene's axes are drawn using the results of *data* except when one axis is more than four times the size of the two others, where in that case the results of *cube* are used.", "dflt": "auto", "role": "info", "valType": "enumerated", "values": [ "auto", "cube", "data", "manual" ] }, "aspectratio": { "description": "Sets this scene's axis aspectratio.", "role": "object", "x": { "min": 0, "role": "info", "valType": "number" }, "y": { "min": 0, "role": "info", "valType": "number" }, "z": { "min": 0, "role": "info", "valType": "number" } }, "bgcolor": { "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "camera": { "center": { "description": "Sets the (x,y,z) components of the 'center' camera vector This vector determines the translation (x,y,z) space about the center of this scene. By default, there is no such translation.", "role": "object", "x": { "dflt": 0, "role": "info", "valType": "number" }, "y": { "dflt": 0, "role": "info", "valType": "number" }, "z": { "dflt": 0, "role": "info", "valType": "number" } }, "eye": { "description": "Sets the (x,y,z) components of the 'eye' camera vector. This vector determines the view point about the origin of this scene.", "role": "object", "x": { "dflt": 1.25, "role": "info", "valType": "number" }, "y": { "dflt": 1.25, "role": "info", "valType": "number" }, "z": { "dflt": 1.25, "role": "info", "valType": "number" } }, "role": "object", "up": { "description": "Sets the (x,y,z) components of the 'up' camera vector. This vector determines the up direction of this scene with respect to the page. The default is *{x: 0, y: 0, z: 1}* which means that the z axis points up.", "role": "object", "x": { "dflt": 0, "role": "info", "valType": "number" }, "y": { "dflt": 0, "role": "info", "valType": "number" }, "z": { "dflt": 1, "role": "info", "valType": "number" } } }, "domain": { "role": "object", "x": { "description": "Sets the horizontal domain of this scene (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "y": { "description": "Sets the vertical domain of this scene (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" } }, "role": "object", "xaxis": { "autorange": { "description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.", "dflt": true, "role": "style", "valType": "enumerated", "values": [ true, false, "reversed" ] }, "backgroundcolor": { "description": "Sets the background color of this axis' wall.", "dflt": "rgba(204, 204, 204, 0.5)", "role": "style", "valType": "color" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "fixedrange": { "description": "Determines whether or not this axis is zoom-able. If true, then zoom is disabled.", "dflt": false, "role": "info", "valType": "boolean" }, "gridcolor": { "description": "Sets the color of the grid lines.", "dflt": "rgb(204, 204, 204)", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the width (in px) of the grid lines.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "hoverformat": { "description": "Sets the hover text formatting rule for data values on this axis, using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "linecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "linewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ true, "ticks", false, "all", "allticks" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "range": { "description": "Sets the range of this axis. If the axis `type` is *log*, then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the date range from January 1st 1970 to November 4th, 2013, set the range from 0 to 1380844800000.0", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "rangemode": { "description": "If *normal*, the range is computed in relation to the extrema of the input data. If *tozero*`, the range extends to 0, regardless of the input data If *nonnegative*, the range is non-negative, regardless of the input data.", "dflt": "normal", "role": "style", "valType": "enumerated", "values": [ "normal", "tozero", "nonnegative" ] }, "role": "object", "showaxeslabels": { "description": "Sets whether or not this axis is labeled", "dflt": true, "role": "info", "valType": "boolean" }, "showbackground": { "description": "Sets whether or not this axis' wall has a background color.", "dflt": false, "role": "info", "valType": "boolean" }, "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showgrid": { "description": "Determines whether or not grid lines are drawn. If *true*, the grid lines are drawn at every tick mark.", "role": "style", "valType": "boolean" }, "showline": { "description": "Determines whether or not a line bounding this axis is drawn.", "dflt": false, "role": "style", "valType": "boolean" }, "showspikes": { "description": "Sets whether or not spikes starting from data points to this axis' wall are shown on hover.", "dflt": true, "role": "info", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "spikecolor": { "description": "Sets the color of the spikes.", "dflt": "rgb(0,0,0)", "role": "style", "valType": "color" }, "spikesides": { "description": "Sets whether or not spikes extending from the projection data points to this axis' wall boundaries are shown on hover.", "dflt": true, "role": "info", "valType": "boolean" }, "spikethickness": { "description": "Sets the thickness (in px) of the spikes.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of this axis.", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this axis' title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "type": { "description": "Sets the axis type. By default, plotly attempts to determined the axis type by looking into the data of the traces that referenced the axis in question.", "dflt": "-", "role": "info", "valType": "enumerated", "values": [ "-", "linear", "log", "date", "category" ] }, "zeroline": { "description": "Determines whether or not a line is drawn at along the 0 value of this axis. If *true*, the zero line is drawn on top of the grid lines.", "role": "style", "valType": "boolean" }, "zerolinecolor": { "description": "Sets the line color of the zero line.", "dflt": "#444", "role": "style", "valType": "color" }, "zerolinewidth": { "description": "Sets the width (in px) of the zero line.", "dflt": 1, "role": "style", "valType": "number" } }, "yaxis": { "autorange": { "description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.", "dflt": true, "role": "style", "valType": "enumerated", "values": [ true, false, "reversed" ] }, "backgroundcolor": { "description": "Sets the background color of this axis' wall.", "dflt": "rgba(204, 204, 204, 0.5)", "role": "style", "valType": "color" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "fixedrange": { "description": "Determines whether or not this axis is zoom-able. If true, then zoom is disabled.", "dflt": false, "role": "info", "valType": "boolean" }, "gridcolor": { "description": "Sets the color of the grid lines.", "dflt": "rgb(204, 204, 204)", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the width (in px) of the grid lines.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "hoverformat": { "description": "Sets the hover text formatting rule for data values on this axis, using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "linecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "linewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ true, "ticks", false, "all", "allticks" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "range": { "description": "Sets the range of this axis. If the axis `type` is *log*, then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the date range from January 1st 1970 to November 4th, 2013, set the range from 0 to 1380844800000.0", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "rangemode": { "description": "If *normal*, the range is computed in relation to the extrema of the input data. If *tozero*`, the range extends to 0, regardless of the input data If *nonnegative*, the range is non-negative, regardless of the input data.", "dflt": "normal", "role": "style", "valType": "enumerated", "values": [ "normal", "tozero", "nonnegative" ] }, "role": "object", "showaxeslabels": { "description": "Sets whether or not this axis is labeled", "dflt": true, "role": "info", "valType": "boolean" }, "showbackground": { "description": "Sets whether or not this axis' wall has a background color.", "dflt": false, "role": "info", "valType": "boolean" }, "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showgrid": { "description": "Determines whether or not grid lines are drawn. If *true*, the grid lines are drawn at every tick mark.", "role": "style", "valType": "boolean" }, "showline": { "description": "Determines whether or not a line bounding this axis is drawn.", "dflt": false, "role": "style", "valType": "boolean" }, "showspikes": { "description": "Sets whether or not spikes starting from data points to this axis' wall are shown on hover.", "dflt": true, "role": "info", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "spikecolor": { "description": "Sets the color of the spikes.", "dflt": "rgb(0,0,0)", "role": "style", "valType": "color" }, "spikesides": { "description": "Sets whether or not spikes extending from the projection data points to this axis' wall boundaries are shown on hover.", "dflt": true, "role": "info", "valType": "boolean" }, "spikethickness": { "description": "Sets the thickness (in px) of the spikes.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of this axis.", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this axis' title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "type": { "description": "Sets the axis type. By default, plotly attempts to determined the axis type by looking into the data of the traces that referenced the axis in question.", "dflt": "-", "role": "info", "valType": "enumerated", "values": [ "-", "linear", "log", "date", "category" ] }, "zeroline": { "description": "Determines whether or not a line is drawn at along the 0 value of this axis. If *true*, the zero line is drawn on top of the grid lines.", "role": "style", "valType": "boolean" }, "zerolinecolor": { "description": "Sets the line color of the zero line.", "dflt": "#444", "role": "style", "valType": "color" }, "zerolinewidth": { "description": "Sets the width (in px) of the zero line.", "dflt": 1, "role": "style", "valType": "number" } }, "zaxis": { "autorange": { "description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.", "dflt": true, "role": "style", "valType": "enumerated", "values": [ true, false, "reversed" ] }, "backgroundcolor": { "description": "Sets the background color of this axis' wall.", "dflt": "rgba(204, 204, 204, 0.5)", "role": "style", "valType": "color" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "fixedrange": { "description": "Determines whether or not this axis is zoom-able. If true, then zoom is disabled.", "dflt": false, "role": "info", "valType": "boolean" }, "gridcolor": { "description": "Sets the color of the grid lines.", "dflt": "rgb(204, 204, 204)", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the width (in px) of the grid lines.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "hoverformat": { "description": "Sets the hover text formatting rule for data values on this axis, using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "linecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "linewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ true, "ticks", false, "all", "allticks" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "range": { "description": "Sets the range of this axis. If the axis `type` is *log*, then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the date range from January 1st 1970 to November 4th, 2013, set the range from 0 to 1380844800000.0", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "rangemode": { "description": "If *normal*, the range is computed in relation to the extrema of the input data. If *tozero*`, the range extends to 0, regardless of the input data If *nonnegative*, the range is non-negative, regardless of the input data.", "dflt": "normal", "role": "style", "valType": "enumerated", "values": [ "normal", "tozero", "nonnegative" ] }, "role": "object", "showaxeslabels": { "description": "Sets whether or not this axis is labeled", "dflt": true, "role": "info", "valType": "boolean" }, "showbackground": { "description": "Sets whether or not this axis' wall has a background color.", "dflt": false, "role": "info", "valType": "boolean" }, "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showgrid": { "description": "Determines whether or not grid lines are drawn. If *true*, the grid lines are drawn at every tick mark.", "role": "style", "valType": "boolean" }, "showline": { "description": "Determines whether or not a line bounding this axis is drawn.", "dflt": false, "role": "style", "valType": "boolean" }, "showspikes": { "description": "Sets whether or not spikes starting from data points to this axis' wall are shown on hover.", "dflt": true, "role": "info", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "spikecolor": { "description": "Sets the color of the spikes.", "dflt": "rgb(0,0,0)", "role": "style", "valType": "color" }, "spikesides": { "description": "Sets whether or not spikes extending from the projection data points to this axis' wall boundaries are shown on hover.", "dflt": true, "role": "info", "valType": "boolean" }, "spikethickness": { "description": "Sets the thickness (in px) of the spikes.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of this axis.", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this axis' title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "type": { "description": "Sets the axis type. By default, plotly attempts to determined the axis type by looking into the data of the traces that referenced the axis in question.", "dflt": "-", "role": "info", "valType": "enumerated", "values": [ "-", "linear", "log", "date", "category" ] }, "zeroline": { "description": "Determines whether or not a line is drawn at along the 0 value of this axis. If *true*, the zero line is drawn on top of the grid lines.", "role": "style", "valType": "boolean" }, "zerolinecolor": { "description": "Sets the line color of the zero line.", "dflt": "#444", "role": "style", "valType": "color" }, "zerolinewidth": { "description": "Sets the width (in px) of the zero line.", "dflt": 1, "role": "style", "valType": "number" } } }, "separators": { "description": "Sets the decimal and thousand separators. For example, *. * puts a '.' before decimals and a space between thousands.", "dflt": ".,", "role": "style", "valType": "string" }, "shapes": { "items": { "shape": { "fillcolor": { "description": "Sets the color filling the shape's interior.", "dflt": "rgba(0,0,0,0)", "role": "info", "valType": "color" }, "line": { "color": { "description": "Sets the line color.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines. Set to a dash string type or a dash length in px.", "dflt": "solid", "role": "style", "valType": "string", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "opacity": { "description": "Sets the opacity of the shape.", "dflt": 1, "max": 1, "min": 0, "role": "info", "valType": "number" }, "path": { "description": "For `type` *path* - a valid SVG path but with the pixel values replaced by data values. There are a few restrictions / quirks only absolute instructions, not relative. So the allowed segments are: M, L, H, V, Q, C, T, S, and Z arcs (A) are not allowed because radius rx and ry are relative. In the future we could consider supporting relative commands, but we would have to decide on how to handle date and log axes. Note that even as is, Q and C Bezier paths that are smooth on linear axes may not be smooth on log, and vice versa. no chained \"polybezier\" commands - specify the segment type for each one. On category axes, values are numbers scaled to the serial numbers of categories because using the categories themselves there would be no way to describe fractional positions On data axes: because space and T are both normal components of path strings, we can't use either to separate date from time parts. Therefore we'll use underscore for this purpose: 2015-02-21_13:45:56.789", "role": "info", "valType": "string" }, "role": "object", "type": { "description": "Specifies the shape type to be drawn. If *line*, a line is drawn from (`x0`,`y0`) to (`x1`,`y1`) If *circle*, a circle is drawn from ((`x0`+`x1`)/2, (`y0`+`y1`)/2)) with radius (|(`x0`+`x1`)/2 - `x0`|, |(`y0`+`y1`)/2 -`y0`)|) If *rect*, a rectangle is drawn linking (`x0`,`y0`), (`x1`,`y0`), (`x1`,`y1`), (`x0`,`y1`), (`x0`,`y0`) If *path*, draw a custom SVG path using `path`.", "role": "info", "valType": "enumerated", "values": [ "circle", "rect", "path", "line" ] }, "x0": { "description": "Sets the shape's starting x position. See `type` for more info.", "role": "info", "valType": "any" }, "x1": { "description": "Sets the shape's end x position. See `type` for more info.", "role": "info", "valType": "any" }, "xref": { "description": "Sets the shape's x coordinate axis. If set to an x axis id (e.g. *x* or *x2*), the `x` position refers to an x coordinate If set to *paper*, the `x` position refers to the distance from the left side of the plotting area in normalized coordinates where *0* (*1*) corresponds to the left (right) side.", "role": "info", "valType": "enumerated", "values": [ "paper", "/^x([2-9]|[1-9][0-9]+)?$/" ] }, "y0": { "description": "Sets the shape's starting y position. See `type` for more info.", "role": "info", "valType": "any" }, "y1": { "description": "Sets the shape's end y position. See `type` for more info.", "role": "info", "valType": "any" }, "yref": { "description": "Sets the annotation's y coordinate axis. If set to an y axis id (e.g. *y* or *y2*), the `y` position refers to an y coordinate If set to *paper*, the `y` position refers to the distance from the bottom of the plotting area in normalized coordinates where *0* (*1*) corresponds to the bottom (top).", "role": "info", "valType": "enumerated", "values": [ "paper", "/^y([2-9]|[1-9][0-9]+)?$/" ] } } }, "role": "object" }, "showlegend": { "description": "Determines whether or not a legend is drawn.", "role": "info", "valType": "boolean" }, "smith": { "dflt": false, "role": "info", "valType": "enumerated", "values": [ false ] }, "title": { "description": "Sets the plot's title.", "dflt": "Click to enter Plot title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "width": { "description": "Sets the plot's width (in px).", "dflt": 700, "min": 10, "role": "info", "valType": "number" }, "xaxis": { "_deprecated": { "autotick": { "description": "Obsolete. Set `tickmode` to *auto* for old `autotick` *true* behavior. Set `tickmode` to *linear* for `autotick` *false*.", "role": "info", "valType": "boolean" } }, "_isSubplotObj": true, "anchor": { "description": "If set to an opposite-letter axis id (e.g. `xaxis2`, `yaxis`), this axis is bound to the corresponding opposite-letter axis. If set to *free*, this axis' position is determined by `position`.", "role": "info", "valType": "enumerated", "values": [ "free", "/^x([2-9]|[1-9][0-9]+)?$/", "/^y([2-9]|[1-9][0-9]+)?$/" ] }, "autorange": { "description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.", "dflt": true, "role": "style", "valType": "enumerated", "values": [ true, false, "reversed" ] }, "domain": { "description": "Sets the domain of this axis (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "fixedrange": { "description": "Determines whether or not this axis is zoom-able. If true, then zoom is disabled.", "dflt": false, "role": "info", "valType": "boolean" }, "gridcolor": { "description": "Sets the color of the grid lines.", "dflt": "#eee", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the width (in px) of the grid lines.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "hoverformat": { "description": "Sets the hover text formatting rule for data values on this axis, using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "linecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "linewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ true, "ticks", false, "all", "allticks" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "overlaying": { "description": "If set a same-letter axis id, this axis is overlaid on top of the corresponding same-letter axis. If *false*, this axis does not overlay any same-letter axes.", "role": "info", "valType": "enumerated", "values": [ "free", "/^x([2-9]|[1-9][0-9]+)?$/", "/^y([2-9]|[1-9][0-9]+)?$/" ] }, "position": { "description": "Sets the position of this axis in the plotting space (in normalized coordinates). Only has an effect if `anchor` is set to *free*.", "dflt": 0, "max": 1, "min": 0, "role": "style", "valType": "number" }, "range": { "description": "Sets the range of this axis. If the axis `type` is *log*, then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the date range from January 1st 1970 to November 4th, 2013, set the range from 0 to 1380844800000.0", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "rangemode": { "description": "If *normal*, the range is computed in relation to the extrema of the input data. If *tozero*`, the range extends to 0, regardless of the input data If *nonnegative*, the range is non-negative, regardless of the input data.", "dflt": "normal", "role": "style", "valType": "enumerated", "values": [ "normal", "tozero", "nonnegative" ] }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showgrid": { "description": "Determines whether or not grid lines are drawn. If *true*, the grid lines are drawn at every tick mark.", "role": "style", "valType": "boolean" }, "showline": { "description": "Determines whether or not a line bounding this axis is drawn.", "dflt": false, "role": "style", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "side": { "description": "Determines whether a x (y) axis is positioned at the *bottom* (*left*) or *top* (*right*) of the plotting area.", "role": "info", "valType": "enumerated", "values": [ "top", "bottom", "left", "right" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of this axis.", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this axis' title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "type": { "description": "Sets the axis type. By default, plotly attempts to determined the axis type by looking into the data of the traces that referenced the axis in question.", "dflt": "-", "role": "info", "valType": "enumerated", "values": [ "-", "linear", "log", "date", "category" ] }, "zeroline": { "description": "Determines whether or not a line is drawn at along the 0 value of this axis. If *true*, the zero line is drawn on top of the grid lines.", "role": "style", "valType": "boolean" }, "zerolinecolor": { "description": "Sets the line color of the zero line.", "dflt": "#444", "role": "style", "valType": "color" }, "zerolinewidth": { "description": "Sets the width (in px) of the zero line.", "dflt": 1, "role": "style", "valType": "number" } }, "yaxis": { "_deprecated": { "autotick": { "description": "Obsolete. Set `tickmode` to *auto* for old `autotick` *true* behavior. Set `tickmode` to *linear* for `autotick` *false*.", "role": "info", "valType": "boolean" } }, "_isSubplotObj": true, "anchor": { "description": "If set to an opposite-letter axis id (e.g. `xaxis2`, `yaxis`), this axis is bound to the corresponding opposite-letter axis. If set to *free*, this axis' position is determined by `position`.", "role": "info", "valType": "enumerated", "values": [ "free", "/^x([2-9]|[1-9][0-9]+)?$/", "/^y([2-9]|[1-9][0-9]+)?$/" ] }, "autorange": { "description": "Determines whether or not the range of this axis is computed in relation to the input data. See `rangemode` for more info. If `range` is provided, then `autorange` is set to *false*.", "dflt": true, "role": "style", "valType": "enumerated", "values": [ true, false, "reversed" ] }, "domain": { "description": "Sets the domain of this axis (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "fixedrange": { "description": "Determines whether or not this axis is zoom-able. If true, then zoom is disabled.", "dflt": false, "role": "info", "valType": "boolean" }, "gridcolor": { "description": "Sets the color of the grid lines.", "dflt": "#eee", "role": "style", "valType": "color" }, "gridwidth": { "description": "Sets the width (in px) of the grid lines.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "hoverformat": { "description": "Sets the hover text formatting rule for data values on this axis, using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "linecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "linewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "mirror": { "description": "Determines if the axis lines or/and ticks are mirrored to the opposite side of the plotting area. If *true*, the axis lines are mirrored. If *ticks*, the axis lines and ticks are mirrored. If *false*, mirroring is disable. If *all*, axis lines are mirrored on all shared-axes subplots. If *allticks*, axis lines and ticks are mirrored on all shared-axes subplots.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ true, "ticks", false, "all", "allticks" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "overlaying": { "description": "If set a same-letter axis id, this axis is overlaid on top of the corresponding same-letter axis. If *false*, this axis does not overlay any same-letter axes.", "role": "info", "valType": "enumerated", "values": [ "free", "/^x([2-9]|[1-9][0-9]+)?$/", "/^y([2-9]|[1-9][0-9]+)?$/" ] }, "position": { "description": "Sets the position of this axis in the plotting space (in normalized coordinates). Only has an effect if `anchor` is set to *free*.", "dflt": 0, "max": 1, "min": 0, "role": "style", "valType": "number" }, "range": { "description": "Sets the range of this axis. If the axis `type` is *log*, then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the date range from January 1st 1970 to November 4th, 2013, set the range from 0 to 1380844800000.0", "items": [ { "valType": "number" }, { "valType": "number" } ], "role": "info", "valType": "info_array" }, "rangemode": { "description": "If *normal*, the range is computed in relation to the extrema of the input data. If *tozero*`, the range extends to 0, regardless of the input data If *nonnegative*, the range is non-negative, regardless of the input data.", "dflt": "normal", "role": "style", "valType": "enumerated", "values": [ "normal", "tozero", "nonnegative" ] }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showgrid": { "description": "Determines whether or not grid lines are drawn. If *true*, the grid lines are drawn at every tick mark.", "role": "style", "valType": "boolean" }, "showline": { "description": "Determines whether or not a line bounding this axis is drawn.", "dflt": false, "role": "style", "valType": "boolean" }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "side": { "description": "Determines whether a x (y) axis is positioned at the *bottom* (*left*) or *top* (*right*) of the plotting area.", "role": "info", "valType": "enumerated", "values": [ "top", "bottom", "left", "right" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of this axis.", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this axis' title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "type": { "description": "Sets the axis type. By default, plotly attempts to determined the axis type by looking into the data of the traces that referenced the axis in question.", "dflt": "-", "role": "info", "valType": "enumerated", "values": [ "-", "linear", "log", "date", "category" ] }, "zeroline": { "description": "Determines whether or not a line is drawn at along the 0 value of this axis. If *true*, the zero line is drawn on top of the grid lines.", "role": "style", "valType": "boolean" }, "zerolinecolor": { "description": "Sets the line color of the zero line.", "dflt": "#444", "role": "style", "valType": "color" }, "zerolinewidth": { "description": "Sets the width (in px) of the zero line.", "dflt": 1, "role": "style", "valType": "number" } } } }, "traces": { "area": { "attributes": { "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "marker": { "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "opacity": { "arrayOk": true, "description": "Sets the marker opacity.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "opacitysrc": { "description": "Sets the source reference on plot.ly for opacity .", "role": "info", "valType": "string" }, "role": "object", "size": { "arrayOk": true, "description": "Sets the marker size (in px).", "dflt": 6, "min": 0, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" }, "symbol": { "arrayOk": true, "description": "Sets the marker symbol type. Adding 100 is equivalent to appending *-open* to a symbol name. Adding 200 is equivalent to appending *-dot* to a symbol name. Adding 300 is equivalent to appending *-open-dot* or *dot-open* to a symbol name.", "dflt": "circle", "role": "style", "valType": "enumerated", "values": [ 0, "circle", 100, "circle-open", 200, "circle-dot", 300, "circle-open-dot", 1, "square", 101, "square-open", 201, "square-dot", 301, "square-open-dot", 2, "diamond", 102, "diamond-open", 202, "diamond-dot", 302, "diamond-open-dot", 3, "cross", 103, "cross-open", 203, "cross-dot", 303, "cross-open-dot", 4, "x", 104, "x-open", 204, "x-dot", 304, "x-open-dot", 5, "triangle-up", 105, "triangle-up-open", 205, "triangle-up-dot", 305, "triangle-up-open-dot", 6, "triangle-down", 106, "triangle-down-open", 206, "triangle-down-dot", 306, "triangle-down-open-dot", 7, "triangle-left", 107, "triangle-left-open", 207, "triangle-left-dot", 307, "triangle-left-open-dot", 8, "triangle-right", 108, "triangle-right-open", 208, "triangle-right-dot", 308, "triangle-right-open-dot", 9, "triangle-ne", 109, "triangle-ne-open", 209, "triangle-ne-dot", 309, "triangle-ne-open-dot", 10, "triangle-se", 110, "triangle-se-open", 210, "triangle-se-dot", 310, "triangle-se-open-dot", 11, "triangle-sw", 111, "triangle-sw-open", 211, "triangle-sw-dot", 311, "triangle-sw-open-dot", 12, "triangle-nw", 112, "triangle-nw-open", 212, "triangle-nw-dot", 312, "triangle-nw-open-dot", 13, "pentagon", 113, "pentagon-open", 213, "pentagon-dot", 313, "pentagon-open-dot", 14, "hexagon", 114, "hexagon-open", 214, "hexagon-dot", 314, "hexagon-open-dot", 15, "hexagon2", 115, "hexagon2-open", 215, "hexagon2-dot", 315, "hexagon2-open-dot", 16, "octagon", 116, "octagon-open", 216, "octagon-dot", 316, "octagon-open-dot", 17, "star", 117, "star-open", 217, "star-dot", 317, "star-open-dot", 18, "hexagram", 118, "hexagram-open", 218, "hexagram-dot", 318, "hexagram-open-dot", 19, "star-triangle-up", 119, "star-triangle-up-open", 219, "star-triangle-up-dot", 319, "star-triangle-up-open-dot", 20, "star-triangle-down", 120, "star-triangle-down-open", 220, "star-triangle-down-dot", 320, "star-triangle-down-open-dot", 21, "star-square", 121, "star-square-open", 221, "star-square-dot", 321, "star-square-open-dot", 22, "star-diamond", 122, "star-diamond-open", 222, "star-diamond-dot", 322, "star-diamond-open-dot", 23, "diamond-tall", 123, "diamond-tall-open", 223, "diamond-tall-dot", 323, "diamond-tall-open-dot", 24, "diamond-wide", 124, "diamond-wide-open", 224, "diamond-wide-dot", 324, "diamond-wide-open-dot", 25, "hourglass", 125, "hourglass-open", 26, "bowtie", 126, "bowtie-open", 27, "circle-cross", 127, "circle-cross-open", 28, "circle-x", 128, "circle-x-open", 29, "square-cross", 129, "square-cross-open", 30, "square-x", 130, "square-x-open", 31, "diamond-cross", 131, "diamond-cross-open", 32, "diamond-x", 132, "diamond-x-open", 33, "cross-thin", 133, "cross-thin-open", 34, "x-thin", 134, "x-thin-open", 35, "asterisk", 135, "asterisk-open", 36, "hash", 136, "hash-open", 236, "hash-dot", 336, "hash-open-dot", 37, "y-up", 137, "y-up-open", 38, "y-down", 138, "y-down-open", 39, "y-left", 139, "y-left-open", 40, "y-right", 140, "y-right-open", 41, "line-ew", 141, "line-ew-open", 42, "line-ns", 142, "line-ns-open", 43, "line-ne", 143, "line-ne-open", 44, "line-nw", 144, "line-nw-open" ] }, "symbolsrc": { "description": "Sets the source reference on plot.ly for symbol .", "role": "info", "valType": "string" } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "r": { "description": "For polar chart only.Sets the radial coordinates.", "role": "data", "valType": "data_array" }, "rsrc": { "description": "Sets the source reference on plot.ly for r .", "role": "info", "valType": "string" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "t": { "description": "For polar chart only.Sets the angular coordinates.", "role": "data", "valType": "data_array" }, "tsrc": { "description": "Sets the source reference on plot.ly for t .", "role": "info", "valType": "string" }, "type": "area", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] } } }, "bar": { "attributes": { "_deprecated": { "bardir": { "description": "Renamed to `orientation`.", "role": "info", "valType": "enumerated", "values": [ "v", "h" ] } }, "dx": { "description": "Sets the x coordinate step. See `x0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "dy": { "description": "Sets the y coordinate step. See `y0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "error_x": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "error_y": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "marker": { "autocolorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not the colorscale is picked using values inside `marker.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines the whether or not the color domain is computed automatically.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "line": { "autocolorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines whether or not the colorscale is picked using the sign of values inside `marker.line.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "showscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not a colorbar is displayed.", "dflt": false, "role": "info", "valType": "boolean" } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "orientation": { "description": "Sets the orientation of the bars. With *v* (*h*), the value of the each bar spans along the vertical (horizontal).", "role": "info", "valType": "enumerated", "values": [ "v", "h" ] }, "r": { "description": "For polar chart only.Sets the radial coordinates.", "role": "data", "valType": "data_array" }, "rsrc": { "description": "Sets the source reference on plot.ly for r .", "role": "info", "valType": "string" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "t": { "description": "For polar chart only.Sets the angular coordinates.", "role": "data", "valType": "data_array" }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates.", "dflt": "", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "tsrc": { "description": "Sets the source reference on plot.ly for t .", "role": "info", "valType": "string" }, "type": "bar", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "x0": { "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", "dflt": 0, "role": "info", "valType": "any" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "y0": { "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", "dflt": 0, "role": "info", "valType": "any" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" } }, "description": "The data visualized by the span of the bars is set in `y` if `orientation` is set th *v* (the default) and the labels are set in `x`. By setting `orientation` to *h*, the roles are interchanged.", "layoutAttributes": { "bargap": { "description": "Sets the gap (in plot fraction) between bars of adjacent location coordinates.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "bargroupgap": { "description": "Sets the gap (in plot fraction) between bars of the same location coordinate.", "dflt": 0, "max": 1, "min": 0, "role": "style", "valType": "number" }, "barmode": { "description": "Determines how bars at the same location coordinate are displayed on the graph. With *stack*, the bars are stacked on top of one another With *group*, the bars are plotted next to one another centered around the shared location. With *overlay*, the bars are plotted over one another, you might need to an *opacity* to see multiple bars.", "dflt": "group", "role": "info", "valType": "enumerated", "values": [ "stack", "group", "overlay" ] }, "barnorm": { "description": "Sets the normalization for bar traces on the graph. With *fraction*, the value of each bar is divide by the sum of the values at the location coordinate. With *percent*, the results form *fraction* are presented in percents.", "dflt": "", "role": "info", "valType": "enumerated", "values": [ "", "fraction", "percent" ] } } }, "box": { "attributes": { "boxmean": { "description": "If *true*, the mean of the box(es)' underlying distribution is drawn as a dashed line inside the box(es). If *sd* the standard deviation is also drawn.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ true, "sd", false ] }, "boxpoints": { "description": "If *outliers*, only the sample points lying outside the whiskers are shown If *suspectedoutliers*, the outlier points are shown and points either less than 4*Q1-3*Q3 or greater than 4*Q3-3*Q1 are highlighted (see `outliercolor`) If *all*, all sample points are shown If *false*, only the box(es) are shown with no sample points", "dflt": "outliers", "role": "style", "valType": "enumerated", "values": [ "all", "outliers", "suspectedoutliers", false ] }, "fillcolor": { "description": "Sets the fill color.", "role": "style", "valType": "color" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "jitter": { "description": "Sets the amount of jitter in the sample points drawn. If *0*, the sample points align along the distribution axis. If *1*, the sample points are drawn in a random jitter of width equal to the width of the box(es).", "max": 1, "min": 0, "role": "style", "valType": "number" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the color of line bounding the box(es).", "role": "style", "valType": "color" }, "role": "object", "width": { "description": "Sets the width (in px) of line bounding the box(es).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "marker": { "color": { "arrayOk": false, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "line": { "color": { "arrayOk": false, "description": "Sets the color of the lines bounding the marker points.", "dflt": "#444", "role": "style", "valType": "color" }, "outliercolor": { "description": "Sets the border line color of the outlier sample points. Defaults to marker.color", "role": "style", "valType": "color" }, "outlierwidth": { "description": "Sets the border line width (in px) of the outlier sample points.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "width": { "arrayOk": false, "description": "Sets the width (in px) of the lines bounding the marker points.", "dflt": 0, "min": 0, "role": "style", "valType": "number" } }, "opacity": { "arrayOk": false, "description": "Sets the marker opacity.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "outliercolor": { "description": "Sets the color of the outlier sample points.", "dflt": "rgba(0, 0, 0, 0)", "role": "style", "valType": "color" }, "role": "object", "size": { "arrayOk": false, "description": "Sets the marker size (in px).", "dflt": 6, "min": 0, "role": "style", "valType": "number" }, "symbol": { "arrayOk": false, "description": "Sets the marker symbol type. Adding 100 is equivalent to appending *-open* to a symbol name. Adding 200 is equivalent to appending *-dot* to a symbol name. Adding 300 is equivalent to appending *-open-dot* or *dot-open* to a symbol name.", "dflt": "circle", "role": "style", "valType": "enumerated", "values": [ 0, "circle", 100, "circle-open", 200, "circle-dot", 300, "circle-open-dot", 1, "square", 101, "square-open", 201, "square-dot", 301, "square-open-dot", 2, "diamond", 102, "diamond-open", 202, "diamond-dot", 302, "diamond-open-dot", 3, "cross", 103, "cross-open", 203, "cross-dot", 303, "cross-open-dot", 4, "x", 104, "x-open", 204, "x-dot", 304, "x-open-dot", 5, "triangle-up", 105, "triangle-up-open", 205, "triangle-up-dot", 305, "triangle-up-open-dot", 6, "triangle-down", 106, "triangle-down-open", 206, "triangle-down-dot", 306, "triangle-down-open-dot", 7, "triangle-left", 107, "triangle-left-open", 207, "triangle-left-dot", 307, "triangle-left-open-dot", 8, "triangle-right", 108, "triangle-right-open", 208, "triangle-right-dot", 308, "triangle-right-open-dot", 9, "triangle-ne", 109, "triangle-ne-open", 209, "triangle-ne-dot", 309, "triangle-ne-open-dot", 10, "triangle-se", 110, "triangle-se-open", 210, "triangle-se-dot", 310, "triangle-se-open-dot", 11, "triangle-sw", 111, "triangle-sw-open", 211, "triangle-sw-dot", 311, "triangle-sw-open-dot", 12, "triangle-nw", 112, "triangle-nw-open", 212, "triangle-nw-dot", 312, "triangle-nw-open-dot", 13, "pentagon", 113, "pentagon-open", 213, "pentagon-dot", 313, "pentagon-open-dot", 14, "hexagon", 114, "hexagon-open", 214, "hexagon-dot", 314, "hexagon-open-dot", 15, "hexagon2", 115, "hexagon2-open", 215, "hexagon2-dot", 315, "hexagon2-open-dot", 16, "octagon", 116, "octagon-open", 216, "octagon-dot", 316, "octagon-open-dot", 17, "star", 117, "star-open", 217, "star-dot", 317, "star-open-dot", 18, "hexagram", 118, "hexagram-open", 218, "hexagram-dot", 318, "hexagram-open-dot", 19, "star-triangle-up", 119, "star-triangle-up-open", 219, "star-triangle-up-dot", 319, "star-triangle-up-open-dot", 20, "star-triangle-down", 120, "star-triangle-down-open", 220, "star-triangle-down-dot", 320, "star-triangle-down-open-dot", 21, "star-square", 121, "star-square-open", 221, "star-square-dot", 321, "star-square-open-dot", 22, "star-diamond", 122, "star-diamond-open", 222, "star-diamond-dot", 322, "star-diamond-open-dot", 23, "diamond-tall", 123, "diamond-tall-open", 223, "diamond-tall-dot", 323, "diamond-tall-open-dot", 24, "diamond-wide", 124, "diamond-wide-open", 224, "diamond-wide-dot", 324, "diamond-wide-open-dot", 25, "hourglass", 125, "hourglass-open", 26, "bowtie", 126, "bowtie-open", 27, "circle-cross", 127, "circle-cross-open", 28, "circle-x", 128, "circle-x-open", 29, "square-cross", 129, "square-cross-open", 30, "square-x", 130, "square-x-open", 31, "diamond-cross", 131, "diamond-cross-open", 32, "diamond-x", 132, "diamond-x-open", 33, "cross-thin", 133, "cross-thin-open", 34, "x-thin", 134, "x-thin-open", 35, "asterisk", 135, "asterisk-open", 36, "hash", 136, "hash-open", 236, "hash-dot", 336, "hash-open-dot", 37, "y-up", 137, "y-up-open", 38, "y-down", 138, "y-down-open", 39, "y-left", 139, "y-left-open", 40, "y-right", 140, "y-right-open", 41, "line-ew", 141, "line-ew-open", 42, "line-ns", 142, "line-ns-open", 43, "line-ne", 143, "line-ne-open", 44, "line-nw", 144, "line-nw-open" ] } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "orientation": { "description": "Sets the orientation of the box(es). If *v* (*h*), the distribution is visualized along the vertical (horizontal).", "role": "style", "valType": "enumerated", "values": [ "v", "h" ] }, "pointpos": { "description": "Sets the position of the sample points in relation to the box(es). If *0*, the sample points are places over the center of the box(es). Positive (negative) values correspond to positions to the right (left) for vertical boxes and above (below) for horizontal boxes", "max": 2, "min": -2, "role": "style", "valType": "number" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "type": "box", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "whiskerwidth": { "description": "Sets the width of the whiskers relative to the box' width. For example, with 1, the whiskers are as wide as the box(es).", "dflt": 0.5, "max": 1, "min": 0, "role": "style", "valType": "number" }, "x": { "description": "Sets the x sample data or coordinates. See overview for more info.", "role": "data", "valType": "data_array" }, "x0": { "description": "Sets the x coordinate of the box. See overview for more info.", "role": "info", "valType": "any" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y sample data or coordinates. See overview for more info.", "role": "data", "valType": "data_array" }, "y0": { "description": "Sets the y coordinate of the box. See overview for more info.", "role": "info", "valType": "any" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" } }, "description": "In vertical (horizontal) box plots, statistics are computed using `y` (`x`) values. By supplying an `x` (`y`) array, one box per distinct x (y) value is drawn If no `x` (`y`) {array} is provided, a single box is drawn. That box position is then positioned with with `name` or with `x0` (`y0`) if provided. Each box spans from quartile 1 (Q1) to quartile 3 (Q3). The second quartile (Q2) is marked by a line inside the box. By default, the whiskers correspond to the box' edges +/- 1.5 times the interquartile range (IQR = Q3-Q1), see *boxpoints* for other options.", "layoutAttributes": { "boxgap": { "description": "Sets the gap (in plot fraction) between boxes of adjacent location coordinates.", "dflt": 0.3, "max": 1, "min": 0, "role": "style", "valType": "number" }, "boxgroupgap": { "description": "Sets the gap (in plot fraction) between boxes of the same location coordinate.", "dflt": 0.3, "max": 1, "min": 0, "role": "style", "valType": "number" }, "boxmode": { "description": "Determines how boxes at the same location coordinate are displayed on the graph. If *group*, the boxes are plotted next to one another centered around the shared location. If *overlay*, the boxes are plotted over one another, you might need to set *opacity* to see them multiple boxes.", "dflt": "overlay", "role": "info", "valType": "enumerated", "values": [ "group", "overlay" ] } } }, "choropleth": { "attributes": { "autocolorscale": { "description": "Determines whether or not the colorscale is picked using the sign of the input z values.", "dflt": true, "role": "style", "valType": "boolean" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "geo": { "description": "Sets a reference between this trace's geospatial coordinates and a geographic map. If *geo* (the default value), the geospatial coordinates refer to `layout.geo`. If *geo2*, the geospatial coordinates refer to `layout.geo2`, and so on.", "dflt": "geo", "role": "info", "valType": "geoid" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "location", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "locationmode": { "description": "Determines the set of locations used to match entries in `locations` to regions on the map.", "dflt": "ISO-3", "role": "info", "valType": "enumerated", "values": [ "ISO-3", "USA-states", "country names" ] }, "locations": { "description": "Sets the coordinates via location IDs or names. See `locationmode` for more info.", "role": "data", "valType": "data_array" }, "locationssrc": { "description": "Sets the source reference on plot.ly for locations .", "role": "info", "valType": "string" }, "marker": { "line": { "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "role": "object" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "description": "Sets the text elements associated with each location.", "role": "data", "valType": "data_array" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "choropleth", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "z": { "description": "Sets the color values.", "role": "data", "valType": "data_array" }, "zauto": { "description": "Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "info", "valType": "boolean" }, "zmax": { "description": "Sets the upper bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zmin": { "description": "Sets the lower bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The data that describes the choropleth value-to-color mapping is set in `z`. The geographic locations corresponding to each value in `z` are set in `locations`." }, "contour": { "attributes": { "autocolorscale": { "description": "Determines whether or not the colorscale is picked using the sign of the input z values.", "dflt": false, "role": "style", "valType": "boolean" }, "autocontour": { "description": "Determines whether of not the contour level attributes at picked by an algorithm. If *true*, the number of contour levels can be set in `ncontours`. If *false*, set the contour level attributes in `contours`.", "dflt": true, "role": "style", "valType": "boolean" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "connectgaps": { "description": "Determines whether or not gaps (i.e. {nan} or missing values) in the `z` data are filled in.", "dflt": false, "role": "info", "valType": "boolean" }, "contours": { "coloring": { "description": "Determines the coloring method showing the contour values. If *fill*, coloring is done evenly between each contour level If *heatmap*, a heatmap gradient is coloring is applied between each contour level. If *lines*, coloring is done on the contour lines. If *none*, no coloring is applied on this trace.", "dflt": "fill", "role": "style", "valType": "enumerated", "values": [ "fill", "heatmap", "lines", "none" ] }, "end": { "description": "Sets the end contour level value.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "showlines": { "description": "Determines whether or not the contour lines are drawn. Has only an effect if `contours.coloring` is set to *fill*.", "dflt": true, "role": "style", "valType": "boolean" }, "size": { "description": "Sets the step between each contour level.", "dflt": null, "role": "style", "valType": "number" }, "start": { "description": "Sets the starting contour level value.", "dflt": null, "role": "style", "valType": "number" } }, "dx": { "description": "Sets the x coordinate step. See `x0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "dy": { "description": "Sets the y coordinate step. See `y0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the color of the contour level. Has no if `contours.coloring` is set to *lines*.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines. Set to a dash string type or a dash length in px.", "dflt": "solid", "role": "style", "valType": "string", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "smoothing": { "description": "Sets the amount of smoothing for the contour lines, where *0* corresponds to no smoothing.", "dflt": 1, "max": 1.3, "min": 0, "role": "style", "valType": "number" }, "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "ncontours": { "description": "Sets the number of contour levels.", "dflt": 0, "role": "style", "valType": "integer" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "description": "Sets the text elements associated with each z value.", "role": "data", "valType": "data_array" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "transpose": { "description": "Transposes the z data.", "dflt": false, "role": "info", "valType": "boolean" }, "type": "contour", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "x0": { "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", "dflt": 0, "role": "info", "valType": "any" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "xtype": { "description": "If *array*, the heatmap's x coordinates are given by *x* (the default behavior when `x` is provided). If *scaled*, the heatmap's x coordinates are given by *x0* and *dx* (the default behavior when `x` is not provided).", "role": "info", "valType": "enumerated", "values": [ "array", "scaled" ] }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "y0": { "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", "dflt": 0, "role": "info", "valType": "any" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "ytype": { "description": "If *array*, the heatmap's y coordinates are given by *y* (the default behavior when `y` is provided) If *scaled*, the heatmap's y coordinates are given by *y0* and *dy* (the default behavior when `y` is not provided)", "role": "info", "valType": "enumerated", "values": [ "array", "scaled" ] }, "z": { "description": "Sets the z data.", "role": "data", "valType": "data_array" }, "zauto": { "description": "Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "info", "valType": "boolean" }, "zmax": { "description": "Sets the upper bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zmin": { "description": "Sets the lower bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The data from which contour lines are computed is set in `z`. Data in `z` must be a {2D array} of numbers. Say that `z` has N rows and M columns, then by default, these N rows correspond to N y coordinates (set in `y` or auto-generated) and the M columns correspond to M x coordinates (set in `x` or auto-generated). By setting `transpose` to *true*, the above behavior is flipped." }, "heatmap": { "attributes": { "autocolorscale": { "description": "Determines whether or not the colorscale is picked using the sign of the input z values.", "dflt": false, "role": "style", "valType": "boolean" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "connectgaps": { "description": "Determines whether or not gaps (i.e. {nan} or missing values) in the `z` data are filled in.", "dflt": false, "role": "info", "valType": "boolean" }, "dx": { "description": "Sets the x coordinate step. See `x0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "dy": { "description": "Sets the y coordinate step. See `y0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "description": "Sets the text elements associated with each z value.", "role": "data", "valType": "data_array" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "transpose": { "description": "Transposes the z data.", "dflt": false, "role": "info", "valType": "boolean" }, "type": "heatmap", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "x0": { "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", "dflt": 0, "role": "info", "valType": "any" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "xtype": { "description": "If *array*, the heatmap's x coordinates are given by *x* (the default behavior when `x` is provided). If *scaled*, the heatmap's x coordinates are given by *x0* and *dx* (the default behavior when `x` is not provided).", "role": "info", "valType": "enumerated", "values": [ "array", "scaled" ] }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "y0": { "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", "dflt": 0, "role": "info", "valType": "any" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "ytype": { "description": "If *array*, the heatmap's y coordinates are given by *y* (the default behavior when `y` is provided) If *scaled*, the heatmap's y coordinates are given by *y0* and *dy* (the default behavior when `y` is not provided)", "role": "info", "valType": "enumerated", "values": [ "array", "scaled" ] }, "z": { "description": "Sets the z data.", "role": "data", "valType": "data_array" }, "zauto": { "description": "Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "info", "valType": "boolean" }, "zmax": { "description": "Sets the upper bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zmin": { "description": "Sets the lower bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zsmooth": { "description": "Picks a smoothing algorithm use to smooth `z` data.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ "fast", "best", false ] }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The data that describes the heatmap value-to-color mapping is set in `z`. Data in `z` can either be a {2D array} of values (ragged or not) or a 1D array of values. In the case where `z` is a {2D array}, say that `z` has N rows and M columns. Then, by default, the resulting heatmap will have N partitions along the y axis and M partitions along the x axis. In other words, the i-th row/ j-th column cell in `z` is mapped to the i-th partition of the y axis (starting from the bottom of the plot) and the j-th partition of the x-axis (starting from the left of the plot). This behavior can be flipped by using `transpose`. Moreover, `x` (`y`) can be provided with M or M+1 (N or N+1) elements. If M (N), then the coordinates correspond to the center of the heatmap cells and the cells have equal width. If M+1 (N+1), then the coordinates correspond to the edges of the heatmap cells. In the case where `z` is a 1D {array}, the x and y coordinates must be provided in `x` and `y` respectively to form data triplets." }, "histogram": { "attributes": { "_deprecated": { "bardir": { "description": "Renamed to `orientation`.", "role": "info", "valType": "enumerated", "values": [ "v", "h" ] } }, "autobinx": { "description": "Determines whether or not the x axis bin attributes are picked by an algorithm.", "dflt": true, "role": "style", "valType": "boolean" }, "autobiny": { "description": "Determines whether or not the y axis bin attributes are picked by an algorithm.", "dflt": true, "role": "style", "valType": "boolean" }, "error_x": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "error_y": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "histfunc": { "description": "Specifies the binning function used for this histogram trace. If *count*, the histogram values are computed by counting the number of values lying inside each bin. If *sum*, *avg*, *min*, *max*, the histogram values are computed using the sum, the average, the minimum or the maximum of the values lying inside each bin respectively.", "dflt": "count", "role": "style", "valType": "enumerated", "values": [ "count", "sum", "avg", "min", "max" ] }, "histnorm": { "description": "Specifies the type of normalization used for this histogram trace. If **, the span of each bar corresponds to the number of occurrences (i.e. the number of data points lying inside the bins). If *percent*, the span of each bar corresponds to the percentage of occurrences with respect to the total number of sample points (here, the sum of all bin area equals 100%). If *density*, the span of each bar corresponds to the number of occurrences in a bin divided by the size of the bin interval (here, the sum of all bin area equals the total number of sample points). If *probability density*, the span of each bar corresponds to the probability that an event will fall into the corresponding bin (here, the sum of all bin area equals 1).", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "", "percent", "probability", "density", "probability density" ] }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "marker": { "autocolorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not the colorscale is picked using values inside `marker.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines the whether or not the color domain is computed automatically.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "line": { "autocolorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines whether or not the colorscale is picked using the sign of values inside `marker.line.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "showscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not a colorbar is displayed.", "dflt": false, "role": "info", "valType": "boolean" } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "nbinsx": { "description": "Sets the number of x axis bins.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "nbinsy": { "description": "Sets the number of y axis bins.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "orientation": { "description": "Sets the orientation of the bars. With *v* (*h*), the value of the each bar spans along the vertical (horizontal).", "role": "info", "valType": "enumerated", "values": [ "v", "h" ] }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates.", "dflt": "", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "histogram", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the sample data to be binned on the x axis.", "role": "data", "valType": "data_array" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xbins": { "end": { "description": "Sets the end value for the x axis bins.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "size": { "description": "Sets the step in-between value each x axis bin.", "dflt": 1, "role": "style", "valType": "any" }, "start": { "description": "Sets the starting value for the x axis bins.", "dflt": null, "role": "style", "valType": "number" } }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the sample data to be binned on the y axis.", "role": "data", "valType": "data_array" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ybins": { "end": { "description": "Sets the end value for the y axis bins.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "size": { "description": "Sets the step in-between value each y axis bin.", "dflt": 1, "role": "style", "valType": "any" }, "start": { "description": "Sets the starting value for the y axis bins.", "dflt": null, "role": "style", "valType": "number" } }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" } }, "description": "The sample data from which statistics are computed is set in `x` for vertically spanning histograms and in `y` for horizontally spanning histograms. Binning options are set `xbins` and `ybins` respectively if no aggregation data is provided.", "layoutAttributes": { "bargap": { "description": "Sets the gap (in plot fraction) between bars of adjacent location coordinates.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "bargroupgap": { "description": "Sets the gap (in plot fraction) between bars of the same location coordinate.", "dflt": 0, "max": 1, "min": 0, "role": "style", "valType": "number" }, "barmode": { "description": "Determines how bars at the same location coordinate are displayed on the graph. With *stack*, the bars are stacked on top of one another With *group*, the bars are plotted next to one another centered around the shared location. With *overlay*, the bars are plotted over one another, you might need to an *opacity* to see multiple bars.", "dflt": "group", "role": "info", "valType": "enumerated", "values": [ "stack", "group", "overlay" ] }, "barnorm": { "description": "Sets the normalization for bar traces on the graph. With *fraction*, the value of each bar is divide by the sum of the values at the location coordinate. With *percent*, the results form *fraction* are presented in percents.", "dflt": "", "role": "info", "valType": "enumerated", "values": [ "", "fraction", "percent" ] } } }, "histogram2d": { "attributes": { "autobinx": { "description": "Determines whether or not the x axis bin attributes are picked by an algorithm.", "dflt": true, "role": "style", "valType": "boolean" }, "autobiny": { "description": "Determines whether or not the y axis bin attributes are picked by an algorithm.", "dflt": true, "role": "style", "valType": "boolean" }, "autocolorscale": { "description": "Determines whether or not the colorscale is picked using the sign of the input z values.", "dflt": false, "role": "style", "valType": "boolean" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "histfunc": { "description": "Specifies the binning function used for this histogram trace. If *count*, the histogram values are computed by counting the number of values lying inside each bin. If *sum*, *avg*, *min*, *max*, the histogram values are computed using the sum, the average, the minimum or the maximum of the values lying inside each bin respectively.", "dflt": "count", "role": "style", "valType": "enumerated", "values": [ "count", "sum", "avg", "min", "max" ] }, "histnorm": { "description": "Specifies the type of normalization used for this histogram trace. If **, the span of each bar corresponds to the number of occurrences (i.e. the number of data points lying inside the bins). If *percent*, the span of each bar corresponds to the percentage of occurrences with respect to the total number of sample points (here, the sum of all bin area equals 100%). If *density*, the span of each bar corresponds to the number of occurrences in a bin divided by the size of the bin interval (here, the sum of all bin area equals the total number of sample points). If *probability density*, the span of each bar corresponds to the probability that an event will fall into the corresponding bin (here, the sum of all bin area equals 1).", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "", "percent", "probability", "density", "probability density" ] }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "marker": { "color": { "description": "Sets the aggregation data.", "role": "data", "valType": "data_array" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "role": "object" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "nbinsx": { "description": "Sets the number of x axis bins.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "nbinsy": { "description": "Sets the number of y axis bins.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "type": "histogram2d", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the sample data to be binned on the x axis.", "role": "data", "valType": "data_array" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xbins": { "end": { "description": "Sets the end value for the x axis bins.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "size": { "description": "Sets the step in-between value each x axis bin.", "dflt": 1, "role": "style", "valType": "any" }, "start": { "description": "Sets the starting value for the x axis bins.", "dflt": null, "role": "style", "valType": "number" } }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the sample data to be binned on the y axis.", "role": "data", "valType": "data_array" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ybins": { "end": { "description": "Sets the end value for the y axis bins.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "size": { "description": "Sets the step in-between value each y axis bin.", "dflt": 1, "role": "style", "valType": "any" }, "start": { "description": "Sets the starting value for the y axis bins.", "dflt": null, "role": "style", "valType": "number" } }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "z": { "description": "Sets the aggregation data.", "role": "data", "valType": "data_array" }, "zauto": { "description": "Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "info", "valType": "boolean" }, "zmax": { "description": "Sets the upper bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zmin": { "description": "Sets the lower bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zsmooth": { "description": "Picks a smoothing algorithm use to smooth `z` data.", "dflt": false, "role": "style", "valType": "enumerated", "values": [ "fast", "best", false ] }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The sample data from which statistics are computed is set in `x` and `y` (where `x` and `y` represent marginal distributions, binning is set in `xbins` and `ybins` in this case) or `z` (where `z` represent the 2D distribution and binning set, binning is set by `x` and `y` in this case). The resulting distribution is visualized as a heatmap.", "hrName": "histogram_2d" }, "histogram2dcontour": { "attributes": { "autobinx": { "description": "Determines whether or not the x axis bin attributes are picked by an algorithm.", "dflt": true, "role": "style", "valType": "boolean" }, "autobiny": { "description": "Determines whether or not the y axis bin attributes are picked by an algorithm.", "dflt": true, "role": "style", "valType": "boolean" }, "autocolorscale": { "description": "Determines whether or not the colorscale is picked using the sign of the input z values.", "dflt": false, "role": "style", "valType": "boolean" }, "autocontour": { "description": "Determines whether of not the contour level attributes at picked by an algorithm. If *true*, the number of contour levels can be set in `ncontours`. If *false*, set the contour level attributes in `contours`.", "dflt": true, "role": "style", "valType": "boolean" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "contours": { "coloring": { "description": "Determines the coloring method showing the contour values. If *fill*, coloring is done evenly between each contour level If *heatmap*, a heatmap gradient is coloring is applied between each contour level. If *lines*, coloring is done on the contour lines. If *none*, no coloring is applied on this trace.", "dflt": "fill", "role": "style", "valType": "enumerated", "values": [ "fill", "heatmap", "lines", "none" ] }, "end": { "description": "Sets the end contour level value.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "showlines": { "description": "Determines whether or not the contour lines are drawn. Has only an effect if `contours.coloring` is set to *fill*.", "dflt": true, "role": "style", "valType": "boolean" }, "size": { "description": "Sets the step between each contour level.", "dflt": null, "role": "style", "valType": "number" }, "start": { "description": "Sets the starting contour level value.", "dflt": null, "role": "style", "valType": "number" } }, "histfunc": { "description": "Specifies the binning function used for this histogram trace. If *count*, the histogram values are computed by counting the number of values lying inside each bin. If *sum*, *avg*, *min*, *max*, the histogram values are computed using the sum, the average, the minimum or the maximum of the values lying inside each bin respectively.", "dflt": "count", "role": "style", "valType": "enumerated", "values": [ "count", "sum", "avg", "min", "max" ] }, "histnorm": { "description": "Specifies the type of normalization used for this histogram trace. If **, the span of each bar corresponds to the number of occurrences (i.e. the number of data points lying inside the bins). If *percent*, the span of each bar corresponds to the percentage of occurrences with respect to the total number of sample points (here, the sum of all bin area equals 100%). If *density*, the span of each bar corresponds to the number of occurrences in a bin divided by the size of the bin interval (here, the sum of all bin area equals the total number of sample points). If *probability density*, the span of each bar corresponds to the probability that an event will fall into the corresponding bin (here, the sum of all bin area equals 1).", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "", "percent", "probability", "density", "probability density" ] }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the color of the contour level. Has no if `contours.coloring` is set to *lines*.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines. Set to a dash string type or a dash length in px.", "dflt": "solid", "role": "style", "valType": "string", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "smoothing": { "description": "Sets the amount of smoothing for the contour lines, where *0* corresponds to no smoothing.", "dflt": 1, "max": 1.3, "min": 0, "role": "style", "valType": "number" }, "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "marker": { "color": { "description": "Sets the aggregation data.", "role": "data", "valType": "data_array" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "role": "object" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "nbinsx": { "description": "Sets the number of x axis bins.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "nbinsy": { "description": "Sets the number of y axis bins.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "ncontours": { "description": "Sets the number of contour levels.", "dflt": 0, "role": "style", "valType": "integer" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "type": "histogram2dcontour", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the sample data to be binned on the x axis.", "role": "data", "valType": "data_array" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xbins": { "end": { "description": "Sets the end value for the x axis bins.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "size": { "description": "Sets the step in-between value each x axis bin.", "dflt": 1, "role": "style", "valType": "any" }, "start": { "description": "Sets the starting value for the x axis bins.", "dflt": null, "role": "style", "valType": "number" } }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the sample data to be binned on the y axis.", "role": "data", "valType": "data_array" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ybins": { "end": { "description": "Sets the end value for the y axis bins.", "dflt": null, "role": "style", "valType": "number" }, "role": "object", "size": { "description": "Sets the step in-between value each y axis bin.", "dflt": 1, "role": "style", "valType": "any" }, "start": { "description": "Sets the starting value for the y axis bins.", "dflt": null, "role": "style", "valType": "number" } }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "z": { "description": "Sets the aggregation data.", "role": "data", "valType": "data_array" }, "zauto": { "description": "Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "info", "valType": "boolean" }, "zmax": { "description": "Sets the upper bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zmin": { "description": "Sets the lower bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The sample data from which statistics are computed is set in `x` and `y` (where `x` and `y` represent marginal distributions, binning is set in `xbins` and `ybins` in this case) or `z` (where `z` represent the 2D distribution and binning set, binning is set by `x` and `y` in this case). The resulting distribution is visualized as a contour plot.", "hrName": "histogram_2d_contour" }, "mesh3d": { "attributes": { "alphahull": { "description": "Sets the shape of the mesh If *-1*, Delaunay triangulation is used If *>0*, the alpha-shape algorithm is used If *0*, the convex-hull algorithm is used An alternative to the `i`, `j`, `k` indices triplets.", "dflt": -1, "role": "style", "valType": "number" }, "color": { "description": "Sets the color of the whole mesh", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "contour": { "color": { "dflt": "#000", "role": "style", "valType": "color" }, "role": "object", "show": { "description": "Sets whether or not dynamic contours are shown on hover", "dflt": false, "role": "info", "valType": "boolean" }, "width": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" } }, "delaunayaxis": { "description": "Sets the Delaunay axis from which the triangulation of the mesh takes place. An alternative to setting the `i`, `j`, `k` indices triplets.", "dflt": "z", "role": "info", "valType": "enumerated", "values": [ "x", "y", "z" ] }, "facecolor": { "description": "Sets the color of each face Overrides *color* and *vertexcolor*.", "role": "data", "valType": "data_array" }, "facecolorsrc": { "description": "Sets the source reference on plot.ly for facecolor .", "role": "info", "valType": "string" }, "flatshading": { "description": "Determines whether or not normal smoothing is applied to the meshes, creating meshes with a low-poly look.", "dflt": false, "role": "style", "valType": "boolean" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "i": { "description": "Sets the indices of x coordinates of the vertices", "role": "data", "valType": "data_array" }, "intensity": { "description": "Sets the vertex intensity values, used for plotting fields on meshes", "role": "data", "valType": "data_array" }, "intensitysrc": { "description": "Sets the source reference on plot.ly for intensity .", "role": "info", "valType": "string" }, "isrc": { "description": "Sets the source reference on plot.ly for i .", "role": "info", "valType": "string" }, "j": { "description": "Sets the indices of y coordinates of the vertices", "role": "data", "valType": "data_array" }, "jsrc": { "description": "Sets the source reference on plot.ly for j .", "role": "info", "valType": "string" }, "k": { "description": "Sets the indices of z coordinates of the vertices", "role": "data", "valType": "data_array" }, "ksrc": { "description": "Sets the source reference on plot.ly for k .", "role": "info", "valType": "string" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "lighting": { "ambient": { "dflt": 0.8, "max": 1, "min": 0, "role": "style", "valType": "number" }, "diffuse": { "dflt": 0.8, "max": 1, "min": 0, "role": "style", "valType": "number" }, "fresnel": { "dflt": 0.2, "max": 5, "min": 0, "role": "style", "valType": "number" }, "role": "object", "roughness": { "dflt": 0.5, "max": 1, "min": 0, "role": "style", "valType": "number" }, "specular": { "dflt": 0.05, "max": 2, "min": 0, "role": "style", "valType": "number" } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "scene": { "description": "Sets a reference between this trace's 3D coordinate system and a 3D scene. If *scene* (the default value), the (x,y,z) coordinates refer to `layout.scene`. If *scene2*, the (x,y,z) coordinates refer to `layout.scene2`, and so on.", "dflt": "scene", "role": "info", "valType": "sceneid" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "type": "mesh3d", "uid": { "dflt": "", "role": "info", "valType": "string" }, "vertexcolor": { "description": "Sets the color of each vertex Overrides *color*.", "role": "data", "valType": "data_array" }, "vertexcolorsrc": { "description": "Sets the source reference on plot.ly for vertexcolor .", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates of the vertices", "role": "data", "valType": "data_array" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y coordinates of the vertices", "role": "data", "valType": "data_array" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "z": { "description": "Sets the z coordinates of the vertices", "role": "data", "valType": "data_array" }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "Draws sets of triangles with coordinates given by three 1-dimensional arrays in `x`, `y`, `z` and (1) a sets of `i`, `j`, `k` indices (2) Delaunay triangulation or (3) the Alpha-shape algorithm or (4) the Convex-hull algorithm" }, "pie": { "attributes": { "direction": { "description": "Specifies the direction at which succeeding sectors follow one another.", "dflt": "counterclockwise", "role": "style", "valType": "enumerated", "values": [ "clockwise", "counterclockwise" ] }, "dlabel": { "description": "Sets the label step. See `label0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "domain": { "role": "object", "x": { "description": "Sets the horizontal domain of this pie trace (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" }, "y": { "description": "Sets the vertical domain of this pie trace (in plot fraction).", "dflt": [ 0, 1 ], "items": [ { "max": 1, "min": 0, "valType": "number" }, { "max": 1, "min": 0, "valType": "number" } ], "role": "info", "valType": "info_array" } }, "hole": { "description": "Sets the fraction of the radius to cut out of the pie. Use this to make a donut chart.", "dflt": 0, "max": 1, "min": 0, "role": "style", "valType": "number" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "label", "text", "value", "percent", "name" ], "role": "info", "valType": "flaglist" }, "insidetextfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the font used for `textinfo` lying inside the pie.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "label0": { "description": "Alternate to `labels`. Builds a numeric set of labels. Use with `dlabel` where `label0` is the starting label and `dlabel` the step.", "dflt": 0, "role": "info", "valType": "number" }, "labels": { "description": "Sets the sector labels.", "role": "data", "valType": "data_array" }, "labelssrc": { "description": "Sets the source reference on plot.ly for labels .", "role": "info", "valType": "string" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "marker": { "colors": { "description": "Sets the color of each sector of this pie chart. If not specified, the default trace color set is used to pick the sector colors.", "role": "data", "valType": "data_array" }, "colorssrc": { "description": "Sets the source reference on plot.ly for colors .", "role": "info", "valType": "string" }, "line": { "color": { "arrayOk": true, "description": "Sets the color of the line enclosing each sector.", "dflt": "#444", "role": "style", "valType": "color" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the line enclosing each sector.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "role": "object" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "outsidetextfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the font used for `textinfo` lying outside the pie.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "pull": { "arrayOk": true, "description": "Sets the fraction of larger radius to pull the sectors out from the center. This can be a constant to pull all slices apart from each other equally or an array to highlight one or more slices.", "dflt": 0, "max": 1, "min": 0, "role": "style", "valType": "number" }, "pullsrc": { "description": "Sets the source reference on plot.ly for pull .", "role": "info", "valType": "string" }, "rotation": { "description": "Instead of the first slice starting at 12 o'clock, rotate to some other angle.", "dflt": 0, "max": 360, "min": -360, "role": "style", "valType": "number" }, "scalegroup": { "description": "If there are multiple pies that should be sized according to their totals, link them by providing a non-empty group id here shared by every trace in the same group.", "dflt": "", "role": "info", "valType": "string" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "sort": { "description": "Determines whether or not the sectors of reordered from largest to smallest.", "dflt": true, "role": "style", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "description": "Sets text elements associated with each sector.", "role": "data", "valType": "data_array" }, "textfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the font used for `textinfo`.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "textinfo": { "description": "Determines which trace information appear on the graph.", "extras": [ "none" ], "flags": [ "label", "text", "value", "percent" ], "role": "info", "valType": "flaglist" }, "textposition": { "arrayOk": true, "description": "Specifies the location of the `textinfo`.", "dflt": "auto", "role": "info", "valType": "enumerated", "values": [ "inside", "outside", "auto", "none" ] }, "textpositionsrc": { "description": "Sets the source reference on plot.ly for textposition .", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "pie", "uid": { "dflt": "", "role": "info", "valType": "string" }, "values": { "description": "Sets the values of the sectors of this pie chart.", "role": "data", "valType": "data_array" }, "valuessrc": { "description": "Sets the source reference on plot.ly for values .", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] } }, "description": "A data visualized by the sectors of the pie is set in `values`. The sector labels are set in `labels`. The sector colors are set in `marker.colors`", "layoutAttributes": { "hiddenlabels": { "role": "data", "valType": "data_array" }, "hiddenlabelssrc": { "description": "Sets the source reference on plot.ly for hiddenlabels .", "role": "info", "valType": "string" } } }, "scatter": { "attributes": { "connectgaps": { "description": "Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected.", "dflt": false, "role": "info", "valType": "boolean" }, "dx": { "description": "Sets the x coordinate step. See `x0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "dy": { "description": "Sets the y coordinate step. See `y0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "error_x": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "error_y": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "fill": { "description": "Sets the area to fill with a solid color. Use with `fillcolor`.", "dflt": "none", "role": "style", "valType": "enumerated", "values": [ "none", "tozeroy", "tozerox", "tonexty", "tonextx" ] }, "fillcolor": { "description": "Sets the fill color.", "role": "style", "valType": "color" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the line color.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines. Set to a dash string type or a dash length in px.", "dflt": "solid", "role": "style", "valType": "string", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "shape": { "description": "Determines the line shape. With *spline* the lines are drawn using spline interpolation. The other available values correspond to step-wise line shapes.", "dflt": "linear", "role": "style", "valType": "enumerated", "values": [ "linear", "spline", "hv", "vh", "hvh", "vhv" ] }, "smoothing": { "description": "Has only an effect if `shape` is set to *spline* Sets the amount of smoothing. *0* corresponds to no smoothing (equivalent to a *linear* shape).", "dflt": 1, "max": 1.3, "min": 0, "role": "style", "valType": "number" }, "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "marker": { "autocolorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not the colorscale is picked using values inside `marker.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines the whether or not the color domain is computed automatically.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "line": { "autocolorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines whether or not the colorscale is picked using the sign of values inside `marker.line.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "maxdisplayed": { "description": "Sets a maximum number of points to be drawn on the graph. *0* corresponds to no limit.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "opacity": { "arrayOk": true, "description": "Sets the marker opacity.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "opacitysrc": { "description": "Sets the source reference on plot.ly for opacity .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "showscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not a colorbar is displayed.", "dflt": false, "role": "info", "valType": "boolean" }, "size": { "arrayOk": true, "description": "Sets the marker size (in px).", "dflt": 6, "min": 0, "role": "style", "valType": "number" }, "sizemin": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the minimum size (in px) of the rendered marker points.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "sizemode": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the rule for which the data in `size` is converted to pixels.", "dflt": "diameter", "role": "info", "valType": "enumerated", "values": [ "diameter", "area" ] }, "sizeref": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the scale factor used to determine the rendered size of marker points. Use with `sizemin` and `sizemode`.", "dflt": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" }, "symbol": { "arrayOk": true, "description": "Sets the marker symbol type. Adding 100 is equivalent to appending *-open* to a symbol name. Adding 200 is equivalent to appending *-dot* to a symbol name. Adding 300 is equivalent to appending *-open-dot* or *dot-open* to a symbol name.", "dflt": "circle", "role": "style", "valType": "enumerated", "values": [ 0, "circle", 100, "circle-open", 200, "circle-dot", 300, "circle-open-dot", 1, "square", 101, "square-open", 201, "square-dot", 301, "square-open-dot", 2, "diamond", 102, "diamond-open", 202, "diamond-dot", 302, "diamond-open-dot", 3, "cross", 103, "cross-open", 203, "cross-dot", 303, "cross-open-dot", 4, "x", 104, "x-open", 204, "x-dot", 304, "x-open-dot", 5, "triangle-up", 105, "triangle-up-open", 205, "triangle-up-dot", 305, "triangle-up-open-dot", 6, "triangle-down", 106, "triangle-down-open", 206, "triangle-down-dot", 306, "triangle-down-open-dot", 7, "triangle-left", 107, "triangle-left-open", 207, "triangle-left-dot", 307, "triangle-left-open-dot", 8, "triangle-right", 108, "triangle-right-open", 208, "triangle-right-dot", 308, "triangle-right-open-dot", 9, "triangle-ne", 109, "triangle-ne-open", 209, "triangle-ne-dot", 309, "triangle-ne-open-dot", 10, "triangle-se", 110, "triangle-se-open", 210, "triangle-se-dot", 310, "triangle-se-open-dot", 11, "triangle-sw", 111, "triangle-sw-open", 211, "triangle-sw-dot", 311, "triangle-sw-open-dot", 12, "triangle-nw", 112, "triangle-nw-open", 212, "triangle-nw-dot", 312, "triangle-nw-open-dot", 13, "pentagon", 113, "pentagon-open", 213, "pentagon-dot", 313, "pentagon-open-dot", 14, "hexagon", 114, "hexagon-open", 214, "hexagon-dot", 314, "hexagon-open-dot", 15, "hexagon2", 115, "hexagon2-open", 215, "hexagon2-dot", 315, "hexagon2-open-dot", 16, "octagon", 116, "octagon-open", 216, "octagon-dot", 316, "octagon-open-dot", 17, "star", 117, "star-open", 217, "star-dot", 317, "star-open-dot", 18, "hexagram", 118, "hexagram-open", 218, "hexagram-dot", 318, "hexagram-open-dot", 19, "star-triangle-up", 119, "star-triangle-up-open", 219, "star-triangle-up-dot", 319, "star-triangle-up-open-dot", 20, "star-triangle-down", 120, "star-triangle-down-open", 220, "star-triangle-down-dot", 320, "star-triangle-down-open-dot", 21, "star-square", 121, "star-square-open", 221, "star-square-dot", 321, "star-square-open-dot", 22, "star-diamond", 122, "star-diamond-open", 222, "star-diamond-dot", 322, "star-diamond-open-dot", 23, "diamond-tall", 123, "diamond-tall-open", 223, "diamond-tall-dot", 323, "diamond-tall-open-dot", 24, "diamond-wide", 124, "diamond-wide-open", 224, "diamond-wide-dot", 324, "diamond-wide-open-dot", 25, "hourglass", 125, "hourglass-open", 26, "bowtie", 126, "bowtie-open", 27, "circle-cross", 127, "circle-cross-open", 28, "circle-x", 128, "circle-x-open", 29, "square-cross", 129, "square-cross-open", 30, "square-x", 130, "square-x-open", 31, "diamond-cross", 131, "diamond-cross-open", 32, "diamond-x", 132, "diamond-x-open", 33, "cross-thin", 133, "cross-thin-open", 34, "x-thin", 134, "x-thin-open", 35, "asterisk", 135, "asterisk-open", 36, "hash", 136, "hash-open", 236, "hash-dot", 336, "hash-open-dot", 37, "y-up", 137, "y-up-open", 38, "y-down", 138, "y-down-open", 39, "y-left", 139, "y-left-open", 40, "y-right", 140, "y-right-open", 41, "line-ew", 141, "line-ew-open", 42, "line-ns", 142, "line-ns-open", 43, "line-ne", 143, "line-ne-open", 44, "line-nw", 144, "line-nw-open" ] }, "symbolsrc": { "description": "Sets the source reference on plot.ly for symbol .", "role": "info", "valType": "string" } }, "mode": { "description": "Determines the drawing mode for this scatter trace. If the provided `mode` includes *text* then the `text` elements appear at the coordinates. Otherwise, the `text` elements appear on hover. If there are less than 20 points, then the default is *lines+markers*. Otherwise, *lines*.", "extras": [ "none" ], "flags": [ "lines", "markers", "text" ], "role": "info", "valType": "flaglist" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "r": { "description": "For polar chart only.Sets the radial coordinates.", "role": "data", "valType": "data_array" }, "rsrc": { "description": "Sets the source reference on plot.ly for r .", "role": "info", "valType": "string" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "t": { "description": "For polar chart only.Sets the angular coordinates.", "role": "data", "valType": "data_array" }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates.", "dflt": "", "role": "info", "valType": "string" }, "textfont": { "color": { "arrayOk": true, "role": "style", "valType": "color" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "description": "Sets the text font.", "family": { "arrayOk": true, "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "familysrc": { "description": "Sets the source reference on plot.ly for family .", "role": "info", "valType": "string" }, "role": "object", "size": { "arrayOk": true, "min": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" } }, "textposition": { "arrayOk": true, "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", "dflt": "middle center", "role": "style", "valType": "enumerated", "values": [ "top left", "top center", "top right", "middle left", "middle center", "middle right", "bottom left", "bottom center", "bottom right" ] }, "textpositionsrc": { "description": "Sets the source reference on plot.ly for textposition .", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "tsrc": { "description": "Sets the source reference on plot.ly for t .", "role": "info", "valType": "string" }, "type": "scatter", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "x0": { "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", "dflt": 0, "role": "info", "valType": "any" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "y0": { "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", "dflt": 0, "role": "info", "valType": "any" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" } }, "description": "The scatter trace type encompasses line charts, scatter charts, text charts, and bubble charts. The data visualized as scatter point or lines is set in `x` and `y`. Text (appearing either on the chart or on hover only) is via `text`. Bubble charts are achieved by setting `marker.size` and/or `marker.color` to a numerical arrays." }, "scatter3d": { "attributes": { "error_x": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "error_y": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "error_z": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the line color.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines. Set to a dash string type or a dash length in px.", "dflt": "solid", "role": "style", "valType": "string", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "marker": { "autocolorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not the colorscale is picked using values inside `marker.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines the whether or not the color domain is computed automatically.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "line": { "autocolorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines whether or not the colorscale is picked using the sign of values inside `marker.line.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "width": { "arrayOk": false, "description": "Sets the width (in px) of the lines bounding the marker points.", "min": 0, "role": "style", "valType": "number" } }, "opacity": { "arrayOk": false, "description": "Sets the marker opacity. Note that the marker opacity for scatter3d traces must be a scalar value for performance reasons. To set a blending opacity value (i.e. which is not transparent), set *marker.color* to an rgba color and use its alpha channel.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "showscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not a colorbar is displayed.", "dflt": false, "role": "info", "valType": "boolean" }, "size": { "arrayOk": true, "description": "Sets the marker size (in px).", "dflt": 8, "min": 0, "role": "style", "valType": "number" }, "sizemin": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the minimum size (in px) of the rendered marker points.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "sizemode": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the rule for which the data in `size` is converted to pixels.", "dflt": "diameter", "role": "info", "valType": "enumerated", "values": [ "diameter", "area" ] }, "sizeref": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the scale factor used to determine the rendered size of marker points. Use with `sizemin` and `sizemode`.", "dflt": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" }, "symbol": { "arrayOk": true, "description": "Sets the marker symbol type.", "dflt": "circle", "role": "style", "valType": "enumerated", "values": [ "circle", "circle-open", "square", "square-open", "diamond", "diamond-open", "cross", "x" ] }, "symbolsrc": { "description": "Sets the source reference on plot.ly for symbol .", "role": "info", "valType": "string" } }, "mode": { "description": "Determines the drawing mode for this scatter trace. If the provided `mode` includes *text* then the `text` elements appear at the coordinates. Otherwise, the `text` elements appear on hover. If there are less than 20 points, then the default is *lines+markers*. Otherwise, *lines*.", "dflt": "lines+markers", "extras": [ "none" ], "flags": [ "lines", "markers", "text" ], "role": "info", "valType": "flaglist" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "projection": { "role": "object", "x": { "opacity": { "description": "Sets the projection color.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "scale": { "description": "Sets the scale factor determining the size of the projection marker points.", "dflt": 0.6666666666666666, "max": 10, "min": 0, "role": "style", "valType": "number" }, "show": { "description": "Sets whether or not projections are shown along the x axis.", "dflt": false, "role": "info", "valType": "boolean" } }, "y": { "opacity": { "description": "Sets the projection color.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "scale": { "description": "Sets the scale factor determining the size of the projection marker points.", "dflt": 0.6666666666666666, "max": 10, "min": 0, "role": "style", "valType": "number" }, "show": { "description": "Sets whether or not projections are shown along the y axis.", "dflt": false, "role": "info", "valType": "boolean" } }, "z": { "opacity": { "description": "Sets the projection color.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "scale": { "description": "Sets the scale factor determining the size of the projection marker points.", "dflt": 0.6666666666666666, "max": 10, "min": 0, "role": "style", "valType": "number" }, "show": { "description": "Sets whether or not projections are shown along the z axis.", "dflt": false, "role": "info", "valType": "boolean" } } }, "scene": { "description": "Sets a reference between this trace's 3D coordinate system and a 3D scene. If *scene* (the default value), the (x,y,z) coordinates refer to `layout.scene`. If *scene2*, the (x,y,z) coordinates refer to `layout.scene2`, and so on.", "dflt": "scene", "role": "info", "valType": "sceneid" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "surfaceaxis": { "description": "If *-1*, the scatter points are not fill with a surface If *0*, *1*, *2*, the scatter points are filled with a Delaunay surface about the x, y, z respectively.", "dflt": -1, "role": "info", "valType": "enumerated", "values": [ -1, 0, 1, 2 ] }, "surfacecolor": { "description": "Sets the surface fill color.", "role": "style", "valType": "color" }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y,z) triplet. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y,z) coordinates.", "dflt": "", "role": "info", "valType": "string" }, "textfont": { "color": { "arrayOk": true, "role": "style", "valType": "color" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "description": "Sets the text font.", "family": { "arrayOk": true, "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "familysrc": { "description": "Sets the source reference on plot.ly for family .", "role": "info", "valType": "string" }, "role": "object", "size": { "arrayOk": true, "min": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" } }, "textposition": { "arrayOk": true, "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", "dflt": "top center", "role": "style", "valType": "enumerated", "values": [ "top left", "top center", "top right", "middle left", "middle center", "middle right", "bottom left", "bottom center", "bottom right" ] }, "textpositionsrc": { "description": "Sets the source reference on plot.ly for textposition .", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "scatter3d", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "z": { "description": "Sets the z coordinates.", "role": "data", "valType": "data_array" }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The data visualized as scatter point or lines in 3D dimension is set in `x`, `y`, `z`. Text (appearing either on the chart or on hover only) is via `text`. Bubble charts are achieved by setting `marker.size` and/or `marker.color` Projections are achieved via `projection`. Surface fills are achieved via `surfaceaxis`.", "hrName": "scatter_3d" }, "scattergeo": { "attributes": { "geo": { "description": "Sets a reference between this trace's geospatial coordinates and a geographic map. If *geo* (the default value), the geospatial coordinates refer to `layout.geo`. If *geo2*, the geospatial coordinates refer to `layout.geo2`, and so on.", "dflt": "geo", "role": "info", "valType": "geoid" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "lon", "lat", "location", "text", "name" ], "role": "info", "valType": "flaglist" }, "lat": { "description": "Sets the latitude coordinates (in degrees North).", "role": "data", "valType": "data_array" }, "latsrc": { "description": "Sets the source reference on plot.ly for lat .", "role": "info", "valType": "string" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the line color.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines. Set to a dash string type or a dash length in px.", "dflt": "solid", "role": "style", "valType": "string", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "locationmode": { "description": "Determines the set of locations used to match entries in `locations` to regions on the map.", "dflt": "ISO-3", "role": "info", "valType": "enumerated", "values": [ "ISO-3", "USA-states", "country names" ] }, "locations": { "description": "Sets the coordinates via location IDs or names. Coordinates correspond to the centroid of each location given. See `locationmode` for more info.", "role": "data", "valType": "data_array" }, "locationssrc": { "description": "Sets the source reference on plot.ly for locations .", "role": "info", "valType": "string" }, "lon": { "description": "Sets the longitude coordinates (in degrees East).", "role": "data", "valType": "data_array" }, "lonsrc": { "description": "Sets the source reference on plot.ly for lon .", "role": "info", "valType": "string" }, "marker": { "autocolorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not the colorscale is picked using values inside `marker.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines the whether or not the color domain is computed automatically.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "line": { "autocolorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines whether or not the colorscale is picked using the sign of values inside `marker.line.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "opacity": { "arrayOk": true, "description": "Sets the marker opacity.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "opacitysrc": { "description": "Sets the source reference on plot.ly for opacity .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "showscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not a colorbar is displayed.", "dflt": false, "role": "info", "valType": "boolean" }, "size": { "arrayOk": true, "description": "Sets the marker size (in px).", "dflt": 6, "min": 0, "role": "style", "valType": "number" }, "sizemin": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the minimum size (in px) of the rendered marker points.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "sizemode": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the rule for which the data in `size` is converted to pixels.", "dflt": "diameter", "role": "info", "valType": "enumerated", "values": [ "diameter", "area" ] }, "sizeref": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the scale factor used to determine the rendered size of marker points. Use with `sizemin` and `sizemode`.", "dflt": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" }, "symbol": { "arrayOk": true, "description": "Sets the marker symbol type. Adding 100 is equivalent to appending *-open* to a symbol name. Adding 200 is equivalent to appending *-dot* to a symbol name. Adding 300 is equivalent to appending *-open-dot* or *dot-open* to a symbol name.", "dflt": "circle", "role": "style", "valType": "enumerated", "values": [ 0, "circle", 100, "circle-open", 200, "circle-dot", 300, "circle-open-dot", 1, "square", 101, "square-open", 201, "square-dot", 301, "square-open-dot", 2, "diamond", 102, "diamond-open", 202, "diamond-dot", 302, "diamond-open-dot", 3, "cross", 103, "cross-open", 203, "cross-dot", 303, "cross-open-dot", 4, "x", 104, "x-open", 204, "x-dot", 304, "x-open-dot", 5, "triangle-up", 105, "triangle-up-open", 205, "triangle-up-dot", 305, "triangle-up-open-dot", 6, "triangle-down", 106, "triangle-down-open", 206, "triangle-down-dot", 306, "triangle-down-open-dot", 7, "triangle-left", 107, "triangle-left-open", 207, "triangle-left-dot", 307, "triangle-left-open-dot", 8, "triangle-right", 108, "triangle-right-open", 208, "triangle-right-dot", 308, "triangle-right-open-dot", 9, "triangle-ne", 109, "triangle-ne-open", 209, "triangle-ne-dot", 309, "triangle-ne-open-dot", 10, "triangle-se", 110, "triangle-se-open", 210, "triangle-se-dot", 310, "triangle-se-open-dot", 11, "triangle-sw", 111, "triangle-sw-open", 211, "triangle-sw-dot", 311, "triangle-sw-open-dot", 12, "triangle-nw", 112, "triangle-nw-open", 212, "triangle-nw-dot", 312, "triangle-nw-open-dot", 13, "pentagon", 113, "pentagon-open", 213, "pentagon-dot", 313, "pentagon-open-dot", 14, "hexagon", 114, "hexagon-open", 214, "hexagon-dot", 314, "hexagon-open-dot", 15, "hexagon2", 115, "hexagon2-open", 215, "hexagon2-dot", 315, "hexagon2-open-dot", 16, "octagon", 116, "octagon-open", 216, "octagon-dot", 316, "octagon-open-dot", 17, "star", 117, "star-open", 217, "star-dot", 317, "star-open-dot", 18, "hexagram", 118, "hexagram-open", 218, "hexagram-dot", 318, "hexagram-open-dot", 19, "star-triangle-up", 119, "star-triangle-up-open", 219, "star-triangle-up-dot", 319, "star-triangle-up-open-dot", 20, "star-triangle-down", 120, "star-triangle-down-open", 220, "star-triangle-down-dot", 320, "star-triangle-down-open-dot", 21, "star-square", 121, "star-square-open", 221, "star-square-dot", 321, "star-square-open-dot", 22, "star-diamond", 122, "star-diamond-open", 222, "star-diamond-dot", 322, "star-diamond-open-dot", 23, "diamond-tall", 123, "diamond-tall-open", 223, "diamond-tall-dot", 323, "diamond-tall-open-dot", 24, "diamond-wide", 124, "diamond-wide-open", 224, "diamond-wide-dot", 324, "diamond-wide-open-dot", 25, "hourglass", 125, "hourglass-open", 26, "bowtie", 126, "bowtie-open", 27, "circle-cross", 127, "circle-cross-open", 28, "circle-x", 128, "circle-x-open", 29, "square-cross", 129, "square-cross-open", 30, "square-x", 130, "square-x-open", 31, "diamond-cross", 131, "diamond-cross-open", 32, "diamond-x", 132, "diamond-x-open", 33, "cross-thin", 133, "cross-thin-open", 34, "x-thin", 134, "x-thin-open", 35, "asterisk", 135, "asterisk-open", 36, "hash", 136, "hash-open", 236, "hash-dot", 336, "hash-open-dot", 37, "y-up", 137, "y-up-open", 38, "y-down", 138, "y-down-open", 39, "y-left", 139, "y-left-open", 40, "y-right", 140, "y-right-open", 41, "line-ew", 141, "line-ew-open", 42, "line-ns", 142, "line-ns-open", 43, "line-ne", 143, "line-ne-open", 44, "line-nw", 144, "line-nw-open" ] }, "symbolsrc": { "description": "Sets the source reference on plot.ly for symbol .", "role": "info", "valType": "string" } }, "mode": { "description": "Determines the drawing mode for this scatter trace. If the provided `mode` includes *text* then the `text` elements appear at the coordinates. Otherwise, the `text` elements appear on hover. If there are less than 20 points, then the default is *lines+markers*. Otherwise, *lines*.", "dflt": "markers", "extras": [ "none" ], "flags": [ "lines", "markers", "text" ], "role": "info", "valType": "flaglist" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (lon,lat) pair. or item in `locations`. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) or `locations` coordinates.", "dflt": "", "role": "info", "valType": "string" }, "textfont": { "color": { "arrayOk": true, "role": "style", "valType": "color" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "description": "Sets the text font.", "family": { "arrayOk": true, "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "familysrc": { "description": "Sets the source reference on plot.ly for family .", "role": "info", "valType": "string" }, "role": "object", "size": { "arrayOk": true, "min": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" } }, "textposition": { "arrayOk": true, "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", "dflt": "middle center", "role": "style", "valType": "enumerated", "values": [ "top left", "top center", "top right", "middle left", "middle center", "middle right", "bottom left", "bottom center", "bottom right" ] }, "textpositionsrc": { "description": "Sets the source reference on plot.ly for textposition .", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "scattergeo", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] } }, "description": "The data visualized as scatter point or lines on a geographic map is provided either by longitude/latitude pairs in `lon` and `lat` respectively or by geographic location IDs or names in `locations`.", "hrName": "scatter_geo" }, "scattergl": { "attributes": { "dx": { "description": "Sets the x coordinate step. See `x0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "dy": { "description": "Sets the y coordinate step. See `y0` for more info.", "dflt": 1, "role": "info", "valType": "number" }, "error_x": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "error_y": { "_deprecated": { "opacity": { "description": "Obsolete. Use the alpha channel in error bar `color` to set the opacity.", "role": "style", "valType": "number" } }, "array": { "description": "Sets the data corresponding the length of each error bar. Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminus": { "description": "Sets the data corresponding the length of each error bar in the bottom (left) direction for vertical (horizontal) bars Values are plotted relative to the underlying data.", "role": "data", "valType": "data_array" }, "arrayminussrc": { "description": "Sets the source reference on plot.ly for arrayminus .", "role": "info", "valType": "string" }, "arraysrc": { "description": "Sets the source reference on plot.ly for array .", "role": "info", "valType": "string" }, "color": { "description": "Sets the stoke color of the error bars.", "role": "style", "valType": "color" }, "copy_ystyle": { "role": "style", "valType": "boolean" }, "copy_zstyle": { "role": "style", "valType": "boolean" }, "role": "object", "symmetric": { "description": "Determines whether or not the error bars have the same length in both direction (top/bottom for vertical bars, left/right for horizontal bars.", "role": "info", "valType": "boolean" }, "thickness": { "description": "Sets the thickness (in px) of the error bars.", "dflt": 2, "min": 0, "role": "style", "valType": "number" }, "traceref": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "tracerefminus": { "dflt": 0, "min": 0, "role": "info", "valType": "integer" }, "type": { "description": "Determines the rule used to generate the error bars. If *constant`, the bar lengths are of a constant value. Set this constant in `value`. If *percent*, the bar lengths correspond to a percentage of underlying data. Set this percentage in `value`. If *sqrt*, the bar lengths correspond to the sqaure of the underlying data. If *array*, the bar lengths are set with data set `array`.", "role": "info", "valType": "enumerated", "values": [ "percent", "constant", "sqrt", "data" ] }, "value": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars.", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "valueminus": { "description": "Sets the value of either the percentage (if `type` is set to *percent*) or the constant (if `type` is set to *constant*) corresponding to the lengths of the error bars in the bottom (left) direction for vertical (horizontal) bars", "dflt": 10, "min": 0, "role": "info", "valType": "number" }, "visible": { "description": "Determines whether or not this set of error bars is visible.", "role": "info", "valType": "boolean" }, "width": { "description": "Sets the width (in px) of the cross-bar at both ends of the error bars.", "min": 0, "role": "style", "valType": "number" } }, "fill": { "description": "Sets the area to fill with a solid color. Use with `fillcolor`.", "dflt": "none", "role": "style", "valType": "enumerated", "values": [ "none", "tozeroy", "tozerox" ] }, "fillcolor": { "description": "Sets the fill color.", "role": "style", "valType": "color" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "line": { "color": { "description": "Sets the line color.", "role": "style", "valType": "color" }, "dash": { "description": "Sets the style of the lines.", "dflt": "solid", "role": "style", "valType": "enumerated", "values": [ "solid", "dot", "dash", "longdash", "dashdot", "longdashdot" ] }, "role": "object", "width": { "description": "Sets the line width (in px).", "dflt": 2, "min": 0, "role": "style", "valType": "number" } }, "marker": { "autocolorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not the colorscale is picked using values inside `marker.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines the whether or not the color domain is computed automatically.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the marker color.", "role": "style", "valType": "color" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "line": { "autocolorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines whether or not the colorscale is picked using the sign of values inside `marker.line.color`.", "dflt": true, "role": "style", "valType": "boolean" }, "cauto": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "style", "valType": "boolean" }, "cmax": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the upper bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "cmin": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the lower bound of the color domain.", "dflt": null, "role": "info", "valType": "number" }, "color": { "arrayOk": true, "description": "Sets the color of the lines bounding the marker points.", "role": "style", "valType": "color" }, "colorscale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Sets the colorscale.", "role": "style", "valType": "colorscale" }, "colorsrc": { "description": "Sets the source reference on plot.ly for color .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.line.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "width": { "arrayOk": true, "description": "Sets the width (in px) of the lines bounding the marker points.", "min": 0, "role": "style", "valType": "number" }, "widthsrc": { "description": "Sets the source reference on plot.ly for width .", "role": "info", "valType": "string" } }, "opacity": { "arrayOk": true, "description": "Sets the marker opacity.", "max": 1, "min": 0, "role": "style", "valType": "number" }, "opacitysrc": { "description": "Sets the source reference on plot.ly for opacity .", "role": "info", "valType": "string" }, "reversescale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "role": "object", "showscale": { "description": "Has only an effect if `marker.color` is set to a numerical array. Determines whether or not a colorbar is displayed.", "dflt": false, "role": "info", "valType": "boolean" }, "size": { "arrayOk": true, "description": "Sets the marker size (in px).", "dflt": 6, "min": 0, "role": "style", "valType": "number" }, "sizemin": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the minimum size (in px) of the rendered marker points.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "sizemode": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the rule for which the data in `size` is converted to pixels.", "dflt": "diameter", "role": "info", "valType": "enumerated", "values": [ "diameter", "area" ] }, "sizeref": { "description": "Has only an effect if `marker.size` is set to a numerical array. Sets the scale factor used to determine the rendered size of marker points. Use with `sizemin` and `sizemode`.", "dflt": 1, "role": "style", "valType": "number" }, "sizesrc": { "description": "Sets the source reference on plot.ly for size .", "role": "info", "valType": "string" }, "symbol": { "arrayOk": true, "description": "Sets the marker symbol type.", "dflt": "circle", "role": "style", "valType": "enumerated", "values": [ "circle", "circle-open", "square", "square-open", "diamond", "diamond-open", "cross", "x" ] }, "symbolsrc": { "description": "Sets the source reference on plot.ly for symbol .", "role": "info", "valType": "string" } }, "mode": { "description": "Determines the drawing mode for this scatter trace.", "extras": [ "none" ], "flags": [ "lines", "markers" ], "role": "info", "valType": "flaglist" }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "description": "Sets the opacity of the trace.", "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y) pair to appear on hover. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates.", "dflt": "", "role": "info", "valType": "string" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "scattergl", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "x0": { "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", "dflt": 0, "role": "info", "valType": "any" }, "xaxis": { "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", "dflt": "x", "role": "info", "valType": "axisid" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "y0": { "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", "dflt": 0, "role": "info", "valType": "any" }, "yaxis": { "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.xaxis2`, and so on.", "dflt": "y", "role": "info", "valType": "axisid" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" } }, "description": "The data visualized as scatter point or lines is set in `x` and `y` using the WebGl plotting engine. Bubble charts are achieved by setting `marker.size` and/or `marker.color` to a numerical arrays." }, "surface": { "attributes": { "autocolorscale": { "description": "Determines whether or not the colorscale is picked using the sign of the input z values.", "dflt": false, "role": "style", "valType": "boolean" }, "colorbar": { "bgcolor": { "description": "Sets the color of padded area.", "dflt": "rgba(0,0,0,0)", "role": "style", "valType": "color" }, "bordercolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "borderwidth": { "description": "Sets the width (in px) or the border enclosing this color bar.", "dflt": 0, "min": 0, "role": "style", "valType": "number" }, "dtick": { "description": "Sets the step in-between ticks on this axis Use with `tick0`. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0.", "dflt": 1, "role": "style", "valType": "any" }, "exponentformat": { "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", "dflt": "B", "role": "style", "valType": "enumerated", "values": [ "none", "e", "E", "power", "SI", "B" ] }, "len": { "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "lenmode": { "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", "dflt": "fraction", "role": "info", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "nticks": { "description": "Sets the number of ticks. Has an effect only if `tickmode` is set to *auto*.", "dflt": 0, "min": 0, "role": "style", "valType": "integer" }, "outlinecolor": { "description": "Sets the axis line color.", "dflt": "#444", "role": "style", "valType": "color" }, "outlinewidth": { "description": "Sets the width (in px) of the axis line.", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "role": "object", "showexponent": { "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticklabels": { "description": "Determines whether or not the tick labels are drawn.", "dflt": true, "role": "style", "valType": "boolean" }, "showtickprefix": { "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "showticksuffix": { "description": "Same as `showtickprefix` but for tick suffixes.", "dflt": "all", "role": "style", "valType": "enumerated", "values": [ "all", "first", "last", "none" ] }, "thickness": { "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", "dflt": 30, "min": 0, "role": "style", "valType": "number" }, "thicknessmode": { "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", "dflt": "pixels", "role": "style", "valType": "enumerated", "values": [ "fraction", "pixels" ] }, "tick0": { "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2). If the axis `type` is *date*, then you must convert the date to unix time in milliseconds (the number of milliseconds since January 1st, 1970). For example, to set the starting tick to November 4th, 2013, set the range to 1380844800000.0.", "dflt": 0, "role": "style", "valType": "number" }, "tickangle": { "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", "dflt": "auto", "role": "style", "valType": "angle" }, "tickcolor": { "description": "Sets the tick color.", "dflt": "#444", "role": "style", "valType": "color" }, "tickfont": { "color": { "role": "style", "valType": "color" }, "description": "Sets the tick font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "tickformat": { "description": "Sets the tick label formatting rule using the python/d3 number formatting language. See https://github.com/mbostock/d3/wiki/Formatting#numbers or https://docs.python.org/release/3.1.3/library/string.html#formatspec for more info.", "dflt": "", "role": "style", "valType": "string" }, "ticklen": { "description": "Sets the tick length (in px).", "dflt": 5, "min": 0, "role": "style", "valType": "number" }, "tickmode": { "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", "role": "info", "valType": "enumerated", "values": [ "auto", "linear", "array" ] }, "tickprefix": { "description": "Sets a tick label prefix.", "dflt": "", "role": "style", "valType": "string" }, "ticks": { "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", "dflt": "", "role": "style", "valType": "enumerated", "values": [ "outside", "inside", "" ] }, "ticksuffix": { "description": "Sets a tick label suffix.", "dflt": "", "role": "style", "valType": "string" }, "ticktext": { "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "ticktextsrc": { "description": "Sets the source reference on plot.ly for ticktext .", "role": "info", "valType": "string" }, "tickvals": { "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", "role": "data", "valType": "data_array" }, "tickvalssrc": { "description": "Sets the source reference on plot.ly for tickvals .", "role": "info", "valType": "string" }, "tickwidth": { "description": "Sets the tick width (in px).", "dflt": 1, "min": 0, "role": "style", "valType": "number" }, "title": { "description": "Sets the title of the color bar.", "dflt": "Click to enter colorscale title", "role": "info", "valType": "string" }, "titlefont": { "color": { "role": "style", "valType": "color" }, "description": "Sets this color bar's title font.", "family": { "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The plotly service (at https://plot.ly or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*,, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", "noBlank": true, "role": "style", "strict": true, "valType": "string" }, "role": "object", "size": { "min": 1, "role": "style", "valType": "number" } }, "titleside": { "description": "Determines the location of the colorbar title with respect to the color bar.", "dflt": "top", "role": "style", "valType": "enumerated", "values": [ "right", "top", "bottom" ] }, "x": { "description": "Sets the x position of the color bar (in plot fraction).", "dflt": 1.02, "max": 3, "min": -2, "role": "style", "valType": "number" }, "xanchor": { "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar.", "dflt": "left", "role": "style", "valType": "enumerated", "values": [ "left", "center", "right" ] }, "xpad": { "description": "Sets the amount of padding (in px) along the x direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" }, "y": { "description": "Sets the y position of the color bar (in plot fraction).", "dflt": 0.5, "max": 3, "min": -2, "role": "style", "valType": "number" }, "yanchor": { "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar.", "dflt": "middle", "role": "style", "valType": "enumerated", "values": [ "top", "middle", "bottom" ] }, "ypad": { "description": "Sets the amount of padding (in px) along the y direction.", "dflt": 10, "min": 0, "role": "style", "valType": "number" } }, "colorscale": { "description": "Sets the colorscale.", "role": "style", "valType": "colorscale" }, "contours": { "role": "object", "x": { "color": { "dflt": "#000", "role": "style", "valType": "color" }, "highlight": { "dflt": false, "role": "info", "valType": "boolean" }, "highlightColor": { "dflt": "#000", "role": "style", "valType": "color" }, "highlightWidth": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" }, "project": { "role": "object", "x": { "description": "Sets whether or not the dynamic contours are projected along the x axis.", "dflt": false, "role": "info", "valType": "boolean" }, "y": { "description": "Sets whether or not the dynamic contours are projected along the y axis.", "dflt": false, "role": "info", "valType": "boolean" }, "z": { "description": "Sets whether or not the dynamic contours are projected along the z axis.", "dflt": false, "role": "info", "valType": "boolean" } }, "role": "object", "show": { "description": "Sets whether or not dynamic contours are shown along the x axis", "dflt": false, "role": "info", "valType": "boolean" }, "usecolormap": { "dflt": false, "role": "info", "valType": "boolean" }, "width": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" } }, "y": { "color": { "dflt": "#000", "role": "style", "valType": "color" }, "highlight": { "dflt": false, "role": "info", "valType": "boolean" }, "highlightColor": { "dflt": "#000", "role": "style", "valType": "color" }, "highlightWidth": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" }, "project": { "role": "object", "x": { "description": "Sets whether or not the dynamic contours are projected along the x axis.", "dflt": false, "role": "info", "valType": "boolean" }, "y": { "description": "Sets whether or not the dynamic contours are projected along the y axis.", "dflt": false, "role": "info", "valType": "boolean" }, "z": { "description": "Sets whether or not the dynamic contours are projected along the z axis.", "dflt": false, "role": "info", "valType": "boolean" } }, "role": "object", "show": { "description": "Sets whether or not dynamic contours are shown along the y axis", "dflt": false, "role": "info", "valType": "boolean" }, "usecolormap": { "dflt": false, "role": "info", "valType": "boolean" }, "width": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" } }, "z": { "color": { "dflt": "#000", "role": "style", "valType": "color" }, "highlight": { "dflt": false, "role": "info", "valType": "boolean" }, "highlightColor": { "dflt": "#000", "role": "style", "valType": "color" }, "highlightWidth": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" }, "project": { "role": "object", "x": { "description": "Sets whether or not the dynamic contours are projected along the x axis.", "dflt": false, "role": "info", "valType": "boolean" }, "y": { "description": "Sets whether or not the dynamic contours are projected along the y axis.", "dflt": false, "role": "info", "valType": "boolean" }, "z": { "description": "Sets whether or not the dynamic contours are projected along the z axis.", "dflt": false, "role": "info", "valType": "boolean" } }, "role": "object", "show": { "description": "Sets whether or not dynamic contours are shown along the z axis", "dflt": false, "role": "info", "valType": "boolean" }, "usecolormap": { "dflt": false, "role": "info", "valType": "boolean" }, "width": { "dflt": 2, "max": 16, "min": 1, "role": "style", "valType": "number" } } }, "hidesurface": { "dflt": false, "role": "info", "valType": "boolean" }, "hoverinfo": { "description": "Determines which trace information appear on hover.", "dflt": "all", "extras": [ "all", "none" ], "flags": [ "x", "y", "z", "text", "name" ], "role": "info", "valType": "flaglist" }, "legendgroup": { "description": "Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items.", "dflt": "", "role": "info", "valType": "string" }, "lighting": { "ambient": { "dflt": 0.8, "max": 1, "min": 0, "role": "style", "valType": "number" }, "diffuse": { "dflt": 0.8, "max": 1, "min": 0, "role": "style", "valType": "number" }, "fresnel": { "dflt": 0.2, "max": 5, "min": 0, "role": "style", "valType": "number" }, "role": "object", "roughness": { "dflt": 0.5, "max": 1, "min": 0, "role": "style", "valType": "number" }, "specular": { "dflt": 0.05, "max": 2, "min": 0, "role": "style", "valType": "number" } }, "name": { "description": "Sets the trace name. The trace name appear as the legend item and on hover.", "role": "info", "valType": "string" }, "opacity": { "dflt": 1, "max": 1, "min": 0, "role": "style", "valType": "number" }, "reversescale": { "description": "Reverses the colorscale.", "dflt": false, "role": "style", "valType": "boolean" }, "scene": { "description": "Sets a reference between this trace's 3D coordinate system and a 3D scene. If *scene* (the default value), the (x,y,z) coordinates refer to `layout.scene`. If *scene2*, the (x,y,z) coordinates refer to `layout.scene2`, and so on.", "dflt": "scene", "role": "info", "valType": "sceneid" }, "showlegend": { "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, "role": "info", "valType": "boolean" }, "showscale": { "description": "Determines whether or not a colorbar is displayed for this trace.", "dflt": true, "role": "info", "valType": "boolean" }, "stream": { "maxpoints": { "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", "min": 0, "role": "info", "valType": "number" }, "role": "object", "token": { "description": "The stream id number links a data trace on a plot with a stream. See https://plot.ly/settings for more details.", "noBlank": true, "role": "info", "strict": true, "valType": "string" } }, "text": { "description": "Sets the text elements associated with each z value.", "role": "data", "valType": "data_array" }, "textsrc": { "description": "Sets the source reference on plot.ly for text .", "role": "info", "valType": "string" }, "type": "surface", "uid": { "dflt": "", "role": "info", "valType": "string" }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, "role": "info", "valType": "enumerated", "values": [ true, false, "legendonly" ] }, "x": { "description": "Sets the x coordinates.", "role": "data", "valType": "data_array" }, "xsrc": { "description": "Sets the source reference on plot.ly for x .", "role": "info", "valType": "string" }, "y": { "description": "Sets the y coordinates.", "role": "data", "valType": "data_array" }, "ysrc": { "description": "Sets the source reference on plot.ly for y .", "role": "info", "valType": "string" }, "z": { "description": "Sets the z coordinates.", "role": "data", "valType": "data_array" }, "zauto": { "description": "Determines the whether or not the color domain is computed with respect to the input data.", "dflt": true, "role": "info", "valType": "boolean" }, "zmax": { "description": "Sets the upper bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zmin": { "description": "Sets the lower bound of color domain.", "dflt": null, "role": "info", "valType": "number" }, "zsrc": { "description": "Sets the source reference on plot.ly for z .", "role": "info", "valType": "string" } }, "description": "The data the describes the coordinates of the surface is set in `z`. Data in `z` should be a {2D array}. Coordinates in `x` and `y` can either be 1D {arrays} or {2D arrays} (e.g. to graph parametric surfaces). If not provided in `x` and `y`, the x and y coordinates are assumed to be linear starting at 0 with a unit step." } } }plotly-1.9.5+dfsg.orig/plotly/widgets/0000755000175000017500000000000012647020776017263 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/widgets/__init__.py0000644000175000017500000000013412645550357021373 0ustar noahfxnoahfxfrom __future__ import absolute_import from plotly.widgets.graph_widget import GraphWidget plotly-1.9.5+dfsg.orig/plotly/widgets/graphWidget.js0000644000175000017500000001532612645550357022076 0ustar noahfxnoahfxwindow.genUID = function() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16); }); }; var IPYTHON_VERSION = '3'; require(["widgets/js/widget", "widgets/js/manager"], function (widget, manager) { if (!('DOMWidgetView' in widget)) { // we're in IPython2, things moved a bit from 2 --> 3. // construct the expected IPython3 widget API IPYTHON_VERSION = '2'; manager = {WidgetManager: widget}; widget = {DOMWidgetView: IPython.DOMWidgetView}; } var GraphView = widget.DOMWidgetView.extend({ render: function(){ var that = this; var graphId = window.genUID(); var loadingId = 'loading-'+graphId; var _graph_url = that.model.get('_graph_url'); // variable plotlyDomain in the case of enterprise var url_parts = _graph_url.split('/'); var plotlyDomain = url_parts[0] + '//' + url_parts[2]; if(!('plotlyDomains' in window)){ window.plotlyDomains = {}; } window.plotlyDomains[graphId] = plotlyDomain; // Place IFrame in output cell div `$el` that.$el.css('width', '100%'); that.$graph = $([''].join(' ')); that.$graph.appendTo(that.$el); that.$loading = $('
Initializing...
') .appendTo(that.$el); // for some reason the 'width' is being changed in IPython 3.0.0 // for the containing `div` element. There's a flicker here, but // I was unable to fix it otherwise. setTimeout(function () { if (IPYTHON_VERSION === '3') { $('#' + graphId)[0].parentElement.style.width = '100%'; } }, 500); // initialize communication with the iframe if(!('pingers' in window)){ window.pingers = {}; } window.pingers[graphId] = setInterval(function() { that.graphContentWindow = $('#'+graphId)[0].contentWindow; that.graphContentWindow.postMessage({task: 'ping'}, plotlyDomain); }, 200); // Assign a message listener to the 'message' events // from iframe's postMessage protocol. // Filter the messages by iframe src so that the right message // gets passed to the right widget if(!('messageListeners' in window)){ window.messageListeners = {}; } window.messageListeners[graphId] = function(e) { if(_graph_url.indexOf(e.origin)>-1) { var frame = document.getElementById(graphId); if(frame === null){ // frame doesn't exist in the dom anymore, clean up it's old event listener window.removeEventListener('message', window.messageListeners[graphId]); clearInterval(window.pingers[graphId]); } else if(frame.contentWindow === e.source) { // TODO: Stop event propagation, so each frame doesn't listen and filter var frameContentWindow = $('#'+graphId)[0].contentWindow; var message = e.data; if('pong' in message && message.pong) { $('#loading-'+graphId).hide(); clearInterval(window.pingers[graphId]); that.send({event: 'pong', graphId: graphId}); } else if (message.type==='hover' || message.type==='zoom' || message.type==='click' || message.type==='unhover') { // click and hover events contain all of the data in the traces, // which can be a very large object and may take a ton of time // to pass to the python backend. Strip out the data, and require // the user to call get_figure if they need trace information if(message.type !== 'zoom') { for(var i in message.points) { delete message.points[i].data; delete message.points[i].fullData; } } that.send({event: message.type, message: message, graphId: graphId}); } else if (message.task === 'getAttributes') { that.send({event: 'getAttributes', response: message.response}); } } } }; window.removeEventListener('message', window.messageListeners[graphId]); window.addEventListener('message', window.messageListeners[graphId]); }, update: function() { // Listen for messages from the graph widget in python var jmessage = this.model.get('_message'); var message = JSON.parse(jmessage); // check for duplicate messages if(!('messageIds' in window)){ window.messageIds = {}; } if(!(message.uid in window.messageIds)){ // message hasn't been received yet, do stuff window.messageIds[message.uid] = true; if (message.fadeTo) { this.fadeTo(message); } else { var plot = $('#' + message.graphId)[0].contentWindow; plot.postMessage(message, window.plotlyDomains[message.graphId]); } } return GraphView.__super__.update.apply(this); }, /** * Wrapper for jquery's `fadeTo` function. * * @param message Contains the id we need to find the element. */ fadeTo: function (message) { var plot = $('#' + message.graphId); plot.fadeTo(message.duration, message.opacity); } }); // Register the GraphView with the widget manager. manager.WidgetManager.register_widget_view('GraphView', GraphView); }); //@ sourceURL=graphWidget.js plotly-1.9.5+dfsg.orig/plotly/widgets/graph_widget.py0000644000175000017500000007235412645550357022315 0ustar noahfxnoahfx""" Module to allow Plotly graphs to interact with IPython widgets. """ import json import uuid from collections import deque from pkg_resources import resource_string # TODO: protected imports? from IPython.html import widgets from IPython.utils.traitlets import Unicode from IPython.display import Javascript, display import plotly.plotly.plotly as py from plotly import utils, tools from plotly.graph_objs import Figure # Load JS widget code # No officially recommended way to do this in any other way # http://mail.scipy.org/pipermail/ipython-dev/2014-April/013835.html js_widget_code = resource_string('plotly', 'widgets/graphWidget.js').decode('utf-8') display(Javascript(js_widget_code)) __all__ = None class GraphWidget(widgets.DOMWidget): """An interactive Plotly graph widget for use in IPython Notebooks. """ _view_name = Unicode('GraphView', sync=True) _message = Unicode(sync=True) _graph_url = Unicode(sync=True) _new_url = Unicode(sync=True) _filename = '' _flags = { 'save_pending': False } # TODO: URL for offline enterprise def __init__(self, graph_url='https://plot.ly/~playground/7', **kwargs): """Initialize a plotly graph widget Args: graph_url: The url of a Plotly graph Example: ``` GraphWidget('https://plot.ly/~chris/3375') ``` """ super(GraphWidget, self).__init__(**kwargs) # TODO: Validate graph_url self._graph_url = graph_url self._listener_set = set() self._event_handlers = { 'click': widgets.CallbackDispatcher(), 'hover': widgets.CallbackDispatcher(), 'zoom': widgets.CallbackDispatcher() } self._graphId = '' self.on_msg(self._handle_msg) # messages to the iframe client need to wait for the # iframe to communicate that it is ready # unfortunately, this two-way blocking communication # isn't possible # (https://github.com/ipython/ipython/wiki/IPEP-21:-Widget-Messages#caveats) # so we'll just cue up messages until they're ready to be sent self._clientMessages = deque() @property def url(self): return self._new_url or '' def _handle_msg(self, message): """Handle a msg from the front-end. Args: content (dict): Content of the msg. """ content = message['content']['data']['content'] if content.get('event', '') == 'pong': self._graphId = content['graphId'] # ready to recieve - pop out all of the items in the deque while self._clientMessages: _message = self._clientMessages.popleft() _message['graphId'] = self._graphId _message = json.dumps(_message) self._message = _message if content.get('event', '') in ['click', 'hover', 'zoom']: # De-nest the message if content['event'] == 'click' or content['event'] == 'hover': message = content['message']['points'] elif content['event'] == 'zoom': message = content['message']['ranges'] self._event_handlers[content['event']](self, message) if content.get('event', '') == 'getAttributes': self._attributes = content.get('response', {}) # there might be a save pending, use the plotly module to save if self._flags['save_pending']: self._flags['save_pending'] = False url = py.plot(self._attributes, auto_open=False, filename=self._filename, validate=False) self._new_url = url self._fade_to('slow', 1) def _handle_registration(self, event_type, callback, remove): self._event_handlers[event_type].register_callback(callback, remove=remove) event_callbacks = self._event_handlers[event_type].callbacks if (len(event_callbacks) and event_type not in self._listener_set): self._listener_set.add(event_type) message = {'task': 'listen', 'events': list(self._listener_set)} self._handle_outgoing_message(message) def _handle_outgoing_message(self, message): if self._graphId == '': self._clientMessages.append(message) else: message['graphId'] = self._graphId message['uid'] = str(uuid.uuid4()) self._message = json.dumps(message, cls=utils.PlotlyJSONEncoder) def on_click(self, callback, remove=False): """ Assign a callback to click events propagated by clicking on point(s) in the Plotly graph. Args: callback (function): Callback function this is called on click events with the signature: callback(widget, hover_obj) -> None Args: widget (GraphWidget): The current instance of the graph widget that this callback is assigned to. click_obj (dict): a nested dict that describes which point(s) were clicked on. click_obj example: [ { 'curveNumber': 1, 'pointNumber': 2, 'x': 4, 'y': 14 } ] remove (bool, optional): If False, attach the callback. If True, remove the callback. Defaults to False. Returns: None Example: ``` from IPython.display import display def message_handler(widget, msg): display(widget._graph_url) display(msg) g = GraphWidget('https://plot.ly/~chris/3375') display(g) g.on_click(message_handler) ``` """ self._handle_registration('click', callback, remove) def on_hover(self, callback, remove=False): """ Assign a callback to hover events propagated by hovering over points in the Plotly graph. Args: callback (function): Callback function this is called on hover events with the signature: callback(widget, hover_obj) -> None Args: widget (GraphWidget): The current instance of the graph widget that this callback is assigned to. hover_obj (dict): a nested dict that describes which point(s) was hovered over. hover_obj example: [ { 'curveNumber': 1, 'pointNumber': 2, 'x': 4, 'y': 14 } ] remove (bool, optional): If False, attach the callback. If True, remove the callback. Defaults to False. Returns: None Example: ``` from IPython.display import display def message_handler(widget, hover_msg): display(widget._graph_url) display(hover_msg) g = GraphWidget('https://plot.ly/~chris/3375') display(g) g.on_hover(message_handler) ``` """ self._handle_registration('hover', callback, remove) def on_zoom(self, callback, remove=False): """ Assign a callback to zoom events propagated by zooming in regions in the Plotly graph. Args: callback (function): Callback function this is called on zoom events with the signature: callback(widget, ranges) -> None Args: widget (GraphWidget): The current instance of the graph widget that this callback is assigned to. ranges (dict): A description of the region that was zoomed into. ranges example: { 'x': [1.8399058038561549, 2.16443359662], 'y': [4.640902872777017, 7.855677154582] } remove (bool, optional): If False, attach the callback. If True, remove the callback. Defaults to False. Returns: None Example: ``` from IPython.display import display def message_handler(widget, ranges): display(widget._graph_url) display(ranges) g = GraphWidget('https://plot.ly/~chris/3375') display(g) g.on_zoom(message_handler) ``` """ self._handle_registration('zoom', callback, remove) def plot(self, figure_or_data, validate=True): """Plot figure_or_data in the Plotly graph widget. Args: figure_or_data (dict, list, or plotly.graph_obj object): The standard Plotly graph object that describes Plotly graphs as used in `plotly.plotly.plot`. See examples of the figure_or_data in https://plot.ly/python/ Returns: None Example 1 - Graph a scatter plot: ``` from plotly.graph_objs import Scatter g = GraphWidget() g.plot([Scatter(x=[1, 2, 3], y=[10, 15, 13])]) ``` Example 2 - Graph a scatter plot with a title: ``` from plotly.graph_objs import Scatter, Figure, Data fig = Figure( data = Data([ Scatter(x=[1, 2, 3], y=[20, 15, 13]) ]), layout = Layout(title='Experimental Data') ) g = GraphWidget() g.plot(fig) ``` Example 3 - Clear a graph widget ``` from plotly.graph_objs import Scatter, Figure g = GraphWidget() g.plot([Scatter(x=[1, 2, 3], y=[10, 15, 13])]) # Now clear it g.plot({}) # alternatively, g.plot(Figure()) ``` """ if figure_or_data == {} or figure_or_data == Figure(): validate = False figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) message = { 'task': 'newPlot', 'data': figure.get('data', []), 'layout': figure.get('layout', {}), 'graphId': self._graphId } self._handle_outgoing_message(message) def restyle(self, update, indices=None): """Update the style of existing traces in the Plotly graph. Args: update (dict): dict where keys are the graph attribute strings and values are the value of the graph attribute. To update graph objects that are nested, like a marker's color, combine the keys with a period, e.g. `marker.color`. To replace an entire nested object, like `marker`, set the value to the object. See Example 2 below. To update an attribute of multiple traces, set the value to an list of values. If the list is shorter than the number of traces, the values will wrap around. Note: this means that for values that are naturally an array, like `x` or `colorscale`, you need to wrap the value in an extra array, i.e. {'colorscale': [[[0, 'red'], [1, 'green']]]} You can also supply values to different traces with the indices argument. See all of the graph attributes in our reference documentation here: https://plot.ly/python/reference or by calling `help` on graph objects in `plotly.graph_objs`. indices (list, optional): Specify which traces to apply the update dict to. Negative indices are supported. If indices are not given, the update will apply to *all* traces. Examples: Initialization - Start each example below with this setup: ``` from plotly.widgets import GraphWidget from IPython.display import display graph = GraphWidget() display(graph) ``` Example 1 - Set `marker.color` to red in every trace in the graph ``` graph.restyle({'marker.color': 'red'}) ``` Example 2 - Replace `marker` with {'color': 'red'} ``` graph.restyle({'marker': {'color': red'}}) ``` Example 3 - Set `marker.color` to red in the first trace of the graph ``` graph.restyle({'marker.color': 'red'}, indices=[0]) ``` Example 4 - Set `marker.color` of all of the traces to alternating sequences of red and green ``` graph.restyle({'marker.color': ['red', 'green']}) ``` Example 5 - Set just `marker.color` of the first two traces to red and green ``` graph.restyle({'marker.color': ['red', 'green']}, indices=[0, 1]) ``` Example 6 - Set multiple attributes of all of the traces ``` graph.restyle({ 'marker.color': 'red', 'line.color': 'green' }) ``` Example 7 - Update the data of the first trace ``` graph.restyle({ 'x': [[1, 2, 3]], 'y': [[10, 20, 30]], }, indices=[0]) ``` Example 8 - Update the data of the first two traces ``` graph.restyle({ 'x': [[1, 2, 3], [1, 2, 4]], 'y': [[10, 20, 30], [5, 8, 14]], }, indices=[0, 1]) ``` """ # TODO: Add flat traces to graph_objs message = { 'task': 'restyle', 'update': update, 'graphId': self._graphId } if indices: message['indices'] = indices self._handle_outgoing_message(message) def relayout(self, layout): """Update the layout of the Plotly graph. Args: layout (dict): dict where keys are the graph attribute strings and values are the value of the graph attribute. To update graph objects that are nested, like the title of an axis, combine the keys with a period e.g. `xaxis.title`. To set a value of an element in an array, like an axis's range, use brackets, e.g. 'xaxis.range[0]'. To replace an entire nested object, just specify the value to the sub-object. See example 4 below. See all of the layout attributes in our reference documentation https://plot.ly/python/reference/#Layout Or by calling `help` on `plotly.graph_objs.Layout` Examples - Start each example below with this setup: Initialization: ``` from plotly.widgets import GraphWidget from IPython.display import display graph = GraphWidget('https://plot.ly/~chris/3979') display(graph) ``` Example 1 - Update the title ``` graph.relayout({'title': 'Experimental results'}) ``` Example 2 - Update the xaxis range ``` graph.relayout({'xaxis.range': [-1, 6]}) ``` Example 3 - Update the first element of the xaxis range ``` graph.relayout({'xaxis.range[0]': -3}) ``` Example 4 - Replace the entire xaxis object ``` graph.relayout({'xaxis': {'title': 'Experimental results'}}) ``` """ # TODO: Add flat layout to graph_objs message = { 'task': 'relayout', 'update': layout, 'graphId': self._graphId } self._handle_outgoing_message(message) def hover(self, *hover_objs): """Show hover labels over the points specified in hover_obj. Hover labels are the labels that normally appear when the mouse hovers over points in the plotly graph. Args: hover_objs (tuple of dicts): Specifies which points to place hover labels over. The location of the hover labels is described by a dict with keys and'xval' and/or 'yval' or 'curveNumber' and 'pointNumber' and optional keys 'hovermode' and 'subplot' 'xval' and 'yval' specify the (x, y) coordinates to place the label. 'xval' and 'yval need to be close to a point drawn in a graph. 'curveNumber' and 'pointNumber' specify the trace number and the index theof the point in that trace respectively. 'subplot' describes which axes to the coordinates refer to. By default, it is equal to 'xy'. For example, to specify the second x-axis and the third y-axis, set 'subplot' to 'x2y3' 'hovermode' is either 'closest', 'x', or 'y'. When set to 'x', all data sharing the same 'x' coordinate will be shown on screen with corresponding trace labels. When set to 'y' all data sharing the same 'y' coordinates will be shown on the screen with corresponding trace labels. When set to 'closest', information about the data point closest to where the viewer is hovering will appear. Note: If 'hovermode' is 'x', only 'xval' needs to be set. If 'hovermode' is 'y', only 'yval' needs to be set. If 'hovermode' is 'closest', 'xval' and 'yval' both need to be set. Note: 'hovermode' can be toggled by the user in the graph toolbar. Note: It is not currently possible to apply multiple hover labels to points on different axes. Note: `hover` can only be called with multiple dicts if 'curveNumber' and 'pointNumber' are the keys of the dicts Examples: Initialization - Start each example below with this setup: ``` from plotly.widgets import GraphWidget from IPython.display import display graph = GraphWidget('https://plot.ly/~chris/3979') display(graph) ``` Example 1 - Apply a label to the (x, y) point (3, 2) ``` graph.hover({'xval': 3, 'yval': 2, 'hovermode': 'closest'}) ``` Example 2 -Apply a labels to all the points with the x coordinate 3 ``` graph.hover({'xval': 3, 'hovermode': 'x'}) ``` Example 3 - Apply a label to the first point of the first trace and the second point of the second trace. ``` graph.hover({'curveNumber': 0, 'pointNumber': 0}, {'curveNumber': 1, 'pointNumber': 1}) ``` """ # TODO: Add to graph objects if len(hover_objs) == 1: hover_objs = hover_objs[0] message = { 'task': 'hover', 'selection': hover_objs, 'graphId': self._graphId } self._handle_outgoing_message(message) def add_traces(self, traces, new_indices=None): """ Add new data traces to a graph. If `new_indices` isn't specified, they are simply appended. Args: traces (dict or list of dicts, or class of plotly.graph_objs):trace new_indices (list[int]|None), optional: The final indices the added traces should occupy in the graph. Examples: Initialization - Start each example below with this setup: ``` from plotly.widgets import GraphWidget from plotly.graph_objs import Scatter from IPython.display import display graph = GraphWidget('https://plot.ly/~chris/3979') display(graph) ``` Example 1 - Add a scatter/line trace to the graph ``` graph.add_traces(Scatter(x = [1, 2, 3], y = [5, 4, 5])) ``` Example 2 - Add a scatter trace and set it to to be the second trace. This will appear as the second item in the legend. ``` graph.add_traces(Scatter(x = [1, 2, 3], y = [5, 6, 5]), new_indices=[1]) ``` Example 3 - Add multiple traces to the graph ``` graph.add_traces([ Scatter(x = [1, 2, 3], y = [5, 6, 5]), Scatter(x = [1, 2.5, 3], y = [5, 8, 5]) ]) ``` """ # TODO: Validate traces with graph_objs message = { 'task': 'addTraces', 'traces': traces, 'graphId': self._graphId } if new_indices is not None: message['newIndices'] = new_indices self._handle_outgoing_message(message) def delete_traces(self, indices): """Delete data traces from a graph. Args: indices (list[int]): The indices of the traces to be removed Example - Delete the 2nd trace: ``` from plotly.widgets import GraphWidget from IPython.display import display graph = GraphWidget('https://plot.ly/~chris/3979') display(graph) graph.delete_traces([1]) ``` """ message = { 'task': 'deleteTraces', 'indices': indices, 'graphId': self._graphId } self._handle_outgoing_message(message) def reorder_traces(self, current_indices, new_indices=None): """Reorder the traces in a graph. The order of the traces determines the order of the legend entries and the layering of the objects drawn in the graph, i.e. the first trace is drawn first and the second trace is drawn on top of the first trace. Args: current_indices (list[int]): The index of the traces to reorder. new_indices (list[int], optional): The index of the traces specified by `current_indices` after ordering. If None, then move the traces to the end. Examples: Example 1 - Move the first trace to the second to last position, the second trace to the last position ``` graph.move_traces([0, 1]) ``` Example 2 - Move the first trace to the second position, the second trace to the first position. ``` graph.move_traces([0], [1]) ``` """ message = { 'task': 'moveTraces', 'currentIndices': current_indices, 'graphId': self._graphId } if new_indices is not None: message['newIndices'] = new_indices self._handle_outgoing_message(message) def save(self, ignore_defaults=False, filename=''): """ Save a copy of the current state of the widget in plotly. :param (bool) ignore_defaults: Auto-fill in unspecified figure keys? :param (str) filename: Name of the file on plotly. """ self._flags['save_pending'] = True self._filename = filename message = {'task': 'getAttributes', 'ignoreDefaults': ignore_defaults} self._handle_outgoing_message(message) self._fade_to('slow', 0.1) def extend_traces(self, update, indices=(0,), max_points=None): """ Append data points to existing traces in the Plotly graph. Args: update (dict): dict where keys are the graph attribute strings and values are arrays of arrays with values to extend. Each array in the array will extend a trace. Valid keys include: 'x', 'y', 'text, 'marker.color', 'marker.size', 'marker.symbol', 'marker.line.color', 'marker.line.width' indices (list, int): Specify which traces to apply the `update` dict to. If indices are not given, the update will apply to the traces in order. max_points (int or dict, optional): If specified, then only show the `max_points` most recent points in the graph. This is useful to prevent traces from becoming too large (and slow) or for creating "windowed" graphs in monitoring applications. To set max_points to different values for each trace or attribute, set max_points to a dict mapping keys to max_points values. See the examples below. Examples: Initialization - Start each example below with this setup: ``` from plotly.widgets import GraphWidget from IPython.display import display graph = GraphWidget() graph.plot([ {'x': [], 'y': []}, {'x': [], 'y': []} ]) display(graph) ``` Example 1 - Extend the first trace with x and y data ``` graph.extend_traces({'x': [[1, 2, 3]], 'y': [[10, 20, 30]]}, indices=[0]) ``` Example 2 - Extend the second trace with x and y data ``` graph.extend_traces({'x': [[1, 2, 3]], 'y': [[10, 20, 30]]}, indices=[1]) ``` Example 3 - Extend the first two traces with x and y data ``` graph.extend_traces({ 'x': [[1, 2, 3], [2, 3, 4]], 'y': [[10, 20, 30], [3, 4, 3]] }, indices=[0, 1]) ``` Example 4 - Extend the first trace with x and y data and limit the length of data in that trace to 50 points. ``` graph.extend_traces({ 'x': [range(100)], 'y': [range(100)] }, indices=[0, 1], max_points=50) ``` Example 5 - Extend the first and second trace with x and y data and limit the length of data in the first trace to 25 points and the second trace to 50 points. ``` new_points = range(100) graph.extend_traces({ 'x': [new_points, new_points], 'y': [new_points, new_points] }, indices=[0, 1], max_points={ 'x': [25, 50], 'y': [25, 50] } ) ``` Example 6 - Update other attributes, like marker colors and sizes and text ``` # Initialize a plot with some empty attributes graph.plot([{ 'x': [], 'y': [], 'text': [], 'marker': { 'size': [], 'color': [] } }]) # Append some data into those attributes graph.extend_traces({ 'x': [[1, 2, 3]], 'y': [[10, 20, 30]], 'text': [['A', 'B', 'C']], 'marker.size': [[10, 15, 20]], 'marker.color': [['blue', 'red', 'orange']] }, indices=[0]) ``` Example 7 - Live-update a graph over a few seconds ``` import time graph.plot([{'x': [], 'y': []}]) for i in range(10): graph.extend_traces({ 'x': [[i]], 'y': [[i]] }, indices=[0]) time.sleep(0.5) ``` """ message = { 'task': 'extendTraces', 'update': update, 'graphId': self._graphId, 'indices': indices } if max_points is not None: message['maxPoints'] = max_points self._handle_outgoing_message(message) def _fade_to(self, duration, opacity): """ Change the opacity to give a visual signal to users. """ message = {'fadeTo': True, 'duration': duration, 'opacity': opacity} self._handle_outgoing_message(message) plotly-1.9.5+dfsg.orig/plotly/__init__.py0000644000175000017500000000144112645550357017727 0ustar noahfxnoahfx""" https://plot.ly/python/ Plotly's Python API allows users to programmatically access Plotly's server resources. This package is organized as follows: Subpackages: - plotly: all functionality that requires access to Plotly's servers - graph_objs: objects for designing figures and visualizing data - matplotlylib: tools to convert matplotlib figures Modules: - tools: some helpful tools that do not require access to Plotly's servers - utils: functions that you probably won't need, but that subpackages use - version: holds the current API version - exceptions: defines our custom exception classes """ from __future__ import absolute_import from plotly import (plotly, graph_objs, grid_objs, tools, utils, session, offline) from plotly.version import __version__ plotly-1.9.5+dfsg.orig/plotly/graph_objs/0000755000175000017500000000000012647020776017733 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/graph_objs/__init__.py0000644000175000017500000000062312645550357022046 0ustar noahfxnoahfx""" graph_objs ========== This package imports definitions for all of Plotly's graph objects. For more information, run help(Obj) on any of the following objects defined here. The reason for the package graph_objs and the module graph_objs is to provide a clearer API for users. """ from __future__ import absolute_import from plotly.graph_objs.graph_objs import * # this is protected with __all__ plotly-1.9.5+dfsg.orig/plotly/graph_objs/graph_objs_tools.py0000644000175000017500000002225212645550357023647 0ustar noahfxnoahfxfrom __future__ import absolute_import import textwrap import six from plotly import exceptions, graph_reference # Define line and tab size for help text! LINE_SIZE = 76 TAB_SIZE = 4 def get_help(object_name, path=(), parent_object_names=(), attribute=None): """ Returns a help string for a graph object. :param (str) object_name: An object name from GRAPH_REFERENCE :param (tuple[str]) path: The path within a `figure` object. :param parent_object_names: An iterable of names of this object's parents. :param (str|None) attribute: An attribute of given . :return: (str) A printable string to show to users. """ if object_name in graph_reference.ARRAYS: help_string = _list_help(object_name, path, parent_object_names) else: if attribute: help_string = _dict_attribute_help(object_name, path, parent_object_names, attribute) else: help_string = _dict_object_help(object_name, path, parent_object_names) return help_string.expandtabs(TAB_SIZE) def _list_help(object_name, path=(), parent_object_names=()): """See get_help().""" items = graph_reference.ARRAYS[object_name]['items'] items_classes = [graph_reference.string_to_class_name(item) for item in items] lines = textwrap.wrap(repr(items_classes), width=LINE_SIZE-TAB_SIZE) help_dict = { 'object_name': object_name, 'path_string': '[' + ']['.join(repr(k) for k in path) + ']', 'parent_object_names': parent_object_names, 'items_string': '\t' + '\n\t'.join(lines) } return ( "Valid items for '{object_name}' at path {path_string} under parents " "{parent_object_names}:\n{items_string}\n".format(**help_dict) ) def _dict_object_help(object_name, path, parent_object_names): """See get_help().""" attributes = graph_reference.get_valid_attributes(object_name, parent_object_names) lines = textwrap.wrap(repr(list(attributes)), width=LINE_SIZE-TAB_SIZE) help_dict = { 'object_name': object_name, 'path_string': '[' + ']['.join(repr(k) for k in path) + ']', 'parent_object_names': parent_object_names, 'attributes_string': '\t' + '\n\t'.join(lines) } return ( "Valid attributes for '{object_name}' at path {path_string} under " "parents {parent_object_names}:\n\n{attributes_string}\n\n" "Run `<{object_name}-object>.help('attribute')` on any of the above.\n" "'<{object_name}-object>' is the object at {path_string}" .format(**help_dict) ) def _dict_attribute_help(object_name, path, parent_object_names, attribute): """ Get general help information or information on a specific attribute. See get_help(). :param (str|unicode) attribute: The attribute we'll get info for. """ help_dict = { 'object_name': object_name, 'path_string': '[' + ']['.join(repr(k) for k in path) + ']', 'parent_object_names': parent_object_names, 'attribute': attribute } valid_attributes = graph_reference.get_valid_attributes( object_name, parent_object_names ) help_string = ( "Current path: {path_string}\n" "Current parent object_names: {parent_object_names}\n\n") if attribute not in valid_attributes: help_string += "'{attribute}' is not allowed here.\n" return help_string.format(**help_dict) attributes_dicts = graph_reference.get_attributes_dicts( object_name, parent_object_names ) attribute_definitions = [] additional_definition = None meta_keys = graph_reference.GRAPH_REFERENCE['defs']['metaKeys'] trace_names = graph_reference.TRACE_NAMES for key, attribute_dict in attributes_dicts.items(): if attribute in attribute_dict: if object_name in trace_names and attribute == 'type': d = {'role': 'info'} else: d = {k: v for k, v in attribute_dict[attribute].items() if k in meta_keys and not k.startswith('_')} elif attribute in attribute_dict.get('_deprecated', {}): deprecate_attribute_dict = attribute_dict['_deprecated'][attribute] d = {k: v for k, v in deprecate_attribute_dict.items() if k in meta_keys and not k.startswith('_')} d['deprecated'] = True else: continue if key == 'additional_attributes': additional_definition = d continue new_definition = True for item in attribute_definitions: if item['definition'] == d: item['paths'].append(key) new_definition = False if new_definition: attribute_definitions.append({'paths': [key], 'definition': d}) if attribute_definitions: help_string += ("With the current parents, '{attribute}' can be " "used as follows:\n\n") help_string = help_string.format(**help_dict) for item in attribute_definitions: valid_parents_objects_names = [ graph_reference.attribute_path_to_object_names(definition_path) for definition_path in item['paths'] ] if len(valid_parents_objects_names) == 1: valid_parent_objects_names = valid_parents_objects_names[0] help_string += 'Under {}:\n\n'.format( str(valid_parent_objects_names) ) else: help_string += 'Under any of:\n\t\t* {}\n\n'.format( '\n\t\t* '.join(str(tup) for tup in valid_parents_objects_names) ) for meta_key, val in sorted(item['definition'].items()): help_string += '\t{}: '.format(meta_key) if meta_key == 'description': # TODO: https://github.com/plotly/streambed/issues/3950 if isinstance(val, list) and attribute == 'showline': val = val[0] lines = textwrap.wrap(val, width=LINE_SIZE) help_string += '\n\t\t'.join(lines) else: help_string += '{}'.format(val) help_string += '\n' help_string += '\n\n' if additional_definition: help_string += 'Additionally:\n\n' for item in sorted(additional_definition.items()): help_string += '\t{}: {}\n'.format(*item) help_string += '\n' return help_string def curtail_val_repr(val, max_chars, add_delim=False): """ Used mostly by the `to_string` function on Graph Objects to pretty print. Limit the number of characters of output, but keep the representation pretty. :param (*) val: The `repr(val)` result is what gets curtailed. :param (int) max_chars: Max number of chars which may be returned. :param (bool) add_delim: Used if a value is *not* the last in an iterable. :return: (str) """ delim = ", " end = ".." if isinstance(val, six.string_types): if max_chars <= len("'" + end + "'"): return ' ' * max_chars elif add_delim and max_chars <= len("'" + end + "'") + len(delim): return "'" + end + "'" + ' ' * (max_chars - len("'" + end + "'")) else: if max_chars <= len(end): return ' ' * max_chars elif add_delim and max_chars <= len(end) + len(delim): return end + ' ' * (max_chars - len(end)) if add_delim: max_chars -= len(delim) r = repr(val) if len(r) > max_chars: if isinstance(val, six.string_types): # TODO: can we assume this ends in "'" r = r[:max_chars - len(end + "'")] + end + "'" elif (isinstance(val, list) and max_chars >= len("[{end}]".format(end=end))): r = r[:max_chars - len(end + ']')] + end + ']' else: r = r[:max_chars - len(end)] + end if add_delim: r += delim return r def assign_id_to_src(src_name, src_value): if isinstance(src_value, six.string_types): src_id = src_value else: try: src_id = src_value.id except: err = ("{0} does not have an `id` property. " "{1} needs to be assigned to either an " "object with an `id` (like a " "plotly.grid_objs.Column) or a string. " "The `id` is a unique identifier " "assigned by the Plotly webserver " "to this grid column.") src_value_str = str(src_value) err = err.format(src_name, src_value_str) raise exceptions.InputError(err) if src_id == '': err = exceptions.COLUMN_NOT_YET_UPLOADED_MESSAGE err.format(column_name=src_value.name, reference=src_name) raise exceptions.InputError(err) return src_id def sort_keys(key): """ Temporary function. See https://github.com/plotly/python-api/issues/290. :param (str|unicode) key: The attribute we're sorting on. :return: (bool, str|unicode) The naturally-sortable tuple. """ is_special = key in 'rtxyz' return not is_special, key plotly-1.9.5+dfsg.orig/plotly/graph_objs/graph_objs.py0000644000175000017500000011063712645550357022434 0ustar noahfxnoahfx""" graph_objs ========== A module that understands plotly language and can manage the json structures. This module defines two base classes: PlotlyList and PlotlyDict. The former inherits from `list` and the latter inherits from `dict`. and is A third structure, PlotlyTrace, is also considered a base class for all subclassing 'trace' objects like Scatter, Box, Bar, etc. It is also not meant to instantiated by users. Goals of this module: --------------------- * A dict/list with the same entries as a PlotlyDict/PlotlyList should look exactly the same once a call is made to plot. * Only mutate object structure when users ASK for it. (some magic now...) * It should always be possible to get a dict/list JSON representation from a graph_objs object and it should always be possible to make a graph_objs object from a dict/list JSON representation. """ from __future__ import absolute_import import copy import re import warnings from collections import OrderedDict import six from plotly import exceptions, graph_reference from plotly.graph_objs import graph_objs_tools class PlotlyBase(object): """ Base object for PlotlyList and PlotlyDict. """ _name = None _parent = None _parent_key = None def _get_path(self): """ Get a tuple of the str keys and int indices for this object's path. :return: (tuple) """ path = [] parents = self._get_parents() parents.reverse() children = [self] + parents[:-1] for parent, child in zip(parents, children): path.append(child._parent_key) path.reverse() return tuple(path) def _get_parents(self): """ Get a list of all the parent objects above this one. :return: (list[PlotlyBase]) """ parents = [] parent = self._parent while parent is not None: parents.append(parent) parent = parent._parent parents.reverse() return parents def _get_parent_object_names(self): """ Get a list of the names of the parent objects above this one. :return: (list[str]) """ parents = self._get_parents() return [parent._name for parent in parents] def _get_class_name(self): """For convenience. See `graph_reference.object_name_to_class_name`.""" return graph_reference.object_name_to_class_name(self._name) def help(self, return_help=False): """ Print a help string for this object. :param (bool) return_help: Return help string instead of prining? :return: (None|str) Optionally can return help string. """ object_name = self._name path = self._get_path() parent_object_names = self._get_parent_object_names() help_string = graph_objs_tools.get_help(object_name, path, parent_object_names) if return_help: return help_string print(help_string) def to_graph_objs(self, **kwargs): """Everything is cast into graph_objs. Here for backwards compat.""" pass def validate(self): """Everything is *always* validated now. keep for backwards compat.""" pass class PlotlyList(list, PlotlyBase): """ Base class for list-like Plotly objects. """ _name = None def __init__(self, *args, **kwargs): _raise = kwargs.get('_raise', True) if self._name is None: self.__dict__['_name'] = kwargs.pop('_name', None) self.__dict__['_parent'] = kwargs.get('_parent') self.__dict__['_parent_key'] = kwargs.get('_parent_key') if self._name is None: raise exceptions.PlotlyError( "PlotlyList is a base class. It's shouldn't be instantiated." ) if args and isinstance(args[0], dict): note = ( "Just like a `list`, `{name}` must be instantiated " "with a *single* collection.\n" "In other words these are OK:\n" ">>> {name}()\n" ">>> {name}([])\n" ">>> {name}([dict()])\n" ">>> {name}([dict(), dict()])\n" "However, these don't make sense:\n" ">>> {name}(dict())\n" ">>> {name}(dict(), dict())" .format(name=self._get_class_name()) ) raise exceptions.PlotlyListEntryError(self, [0], notes=[note]) super(PlotlyList, self).__init__() for index, value in enumerate(list(*args)): value = self._value_to_graph_object(index, value, _raise=_raise) if isinstance(value, PlotlyBase): self.append(value) def __setitem__(self, index, value, _raise=True): """Override to enforce validation.""" if not isinstance(index, int): if _raise: index_type = type(index) raise TypeError('Index must be int, not {}'.format(index_type)) return if index >= len(self): raise IndexError(index) value = self._value_to_graph_object(index, value, _raise=_raise) if isinstance(value, (PlotlyDict, PlotlyList)): super(PlotlyList, self).__setitem__(index, value) def __setattr__(self, key, value): raise exceptions.PlotlyError('Setting attributes on a PlotlyList is ' 'not allowed') def __iadd__(self, other): """Defines the `+=` operator, which we map to extend.""" self.extend(other) return self def __copy__(self): # TODO: https://github.com/plotly/python-api/issues/291 return GraphObjectFactory.create(self._name, _parent=self._parent, _parent_key=self._parent_key, *self) def __deepcopy__(self, memodict={}): # TODO: https://github.com/plotly/python-api/issues/291 return self.__copy__() def _value_to_graph_object(self, index, value, _raise=True): """ Attempt to change the given value into a graph object. If _raise is False, this won't raise. If the entry can't be converted, `None` is returned, meaning the caller should ignore the value or discard it as a failed conversion. :param (dict) value: A dict to be converted into a graph object. :param (bool) _raise: If False, ignore bad values instead of raising. :return: (PlotlyBase|None) The graph object or possibly `None`. """ if not isinstance(value, dict): if _raise: path = self._get_path() + (index, ) raise exceptions.PlotlyListEntryError(self, path) else: return items = graph_reference.ARRAYS[self._name]['items'] for i, item in enumerate(items, 1): try: return GraphObjectFactory.create(item, _raise=_raise, _parent=self, _parent_key=index, **value) except exceptions.PlotlyGraphObjectError: if i == len(items) and _raise: raise def append(self, value): """Override to enforce validation.""" index = len(self) # used for error messages value = self._value_to_graph_object(index, value) super(PlotlyList, self).append(value) def extend(self, iterable): """Override to enforce validation.""" for value in iterable: index = len(self) value = self._value_to_graph_object(index, value) super(PlotlyList, self).append(value) def insert(self, index, value): """Override to enforce validation.""" value = self._value_to_graph_object(index, value) super(PlotlyList, self).insert(index, value) def update(self, changes, make_copies=False): """ Update current list with changed_list, which must be iterable. :param (dict|list[dict]) changes: :param (bool) make_copies: Because mutable objects contain references to their values, updating multiple items in a list will cause the items to all reference the same original set of objects. To change this behavior add `make_copies=True` which makes deep copies of the update items and therefore break references. """ if isinstance(changes, dict): changes = [changes] for index in range(len(self)): try: update = changes[index % len(changes)] except ZeroDivisionError: pass else: if make_copies: self[index].update(copy.deepcopy(update)) else: self[index].update(update) def strip_style(self): """Strip style by calling `stip_style` on children items.""" for plotly_dict in self: plotly_dict.strip_style() def get_data(self, flatten=False): """ Returns the JSON for the plot with non-data elements stripped. :param (bool) flatten: {'a': {'b': ''}} --> {'a.b': ''} :returns: (dict|list) Depending on (flat|unflat) """ l = list() for plotly_dict in self: l += [plotly_dict.get_data(flatten=flatten)] del_indicies = [index for index, item in enumerate(self) if len(item) == 0] del_ct = 0 for index in del_indicies: del self[index - del_ct] del_ct += 1 if flatten: d = {} for i, e in enumerate(l): for k, v in e.items(): key = "{0}.{1}".format(i, k) d[key] = v return d else: return l def get_ordered(self, **kwargs): """All children are already validated. Just use get_ordered on them.""" return [child.get_ordered() for child in self] def to_string(self, level=0, indent=4, eol='\n', pretty=True, max_chars=80): """Get formatted string by calling `to_string` on children items.""" if not len(self): return "{name}()".format(name=self._get_class_name()) string = "{name}([{eol}{indent}".format( name=self._get_class_name(), eol=eol, indent=' ' * indent * (level + 1)) for index, entry in enumerate(self): string += entry.to_string(level=level+1, indent=indent, eol=eol, pretty=pretty, max_chars=max_chars) if index < len(self) - 1: string += ",{eol}{indent}".format( eol=eol, indent=' ' * indent * (level + 1)) string += ( "{eol}{indent}])").format(eol=eol, indent=' ' * indent * level) return string def force_clean(self, **kwargs): """Remove empty/None values by calling `force_clean()` on children.""" for entry in self: entry.force_clean() del_indicies = [index for index, item in enumerate(self) if len(item) == 0] del_ct = 0 for index in del_indicies: del self[index - del_ct] del_ct += 1 class PlotlyDict(dict, PlotlyBase): """ Base class for dict-like Plotly objects. """ _name = None _parent_key = None _valid_attributes = None _deprecated_attributes = None _subplot_attributes = None def __init__(self, *args, **kwargs): _raise = kwargs.pop('_raise', True) if self._name is None: self.__dict__['_name'] = kwargs.pop('_name', None) self.__dict__['_parent'] = kwargs.pop('_parent', None) self.__dict__['_parent_key'] = kwargs.pop('_parent_key', None) if self._name is None: raise exceptions.PlotlyError( "PlotlyDict is a base class. It's shouldn't be instantiated." ) super(PlotlyDict, self).__init__() if self._name in graph_reference.TRACE_NAMES: self['type'] = self._name # force key-value pairs to go through validation d = {key: val for key, val in dict(*args, **kwargs).items()} for key, val in d.items(): self.__setitem__(key, val, _raise=_raise) def __dir__(self): """Dynamically return the existing and possible attributes.""" return sorted(list(self._get_valid_attributes())) def __getitem__(self, key): """Calls __missing__ when key is not found. May mutate object.""" if key not in self: self.__missing__(key) return super(PlotlyDict, self).__getitem__(key) def __setattr__(self, key, value): """Maps __setattr__ onto __setitem__""" self.__setitem__(key, value) def __setitem__(self, key, value, _raise=True): """Validates/Converts values which should be Graph Objects.""" if not isinstance(key, six.string_types): if _raise: raise TypeError('Key must be string, not {}'.format(type(key))) return if key.endswith('src'): if key in self._get_valid_attributes(): value = graph_objs_tools.assign_id_to_src(key, value) return super(PlotlyDict, self).__setitem__(key, value) subplot_key = self._get_subplot_key(key) if subplot_key is not None: value = self._value_to_graph_object(subplot_key, value, _raise=_raise) if isinstance(value, (PlotlyDict, PlotlyList)): return super(PlotlyDict, self).__setitem__(key, value) if key not in self._get_valid_attributes(): if key in self._get_deprecated_attributes(): warnings.warn( "Oops! '{attribute}' has been deprecated in " "'{object_name}'\nThis may still work, but you should " "update your code when possible.\n\n" "Run `.help('{attribute}')` for more information." .format(attribute=key, object_name=self._name) ) # this means deprecated attrs get set *as-is*! return super(PlotlyDict, self).__setitem__(key, value) else: if _raise: path = self._get_path() + (key, ) raise exceptions.PlotlyDictKeyError(self, path) return if self._get_attribute_role(key) == 'object': value = self._value_to_graph_object(key, value, _raise=_raise) if not isinstance(value, (PlotlyDict, PlotlyList)): return super(PlotlyDict, self).__setitem__(key, value) def __getattr__(self, key): """Python only calls this when key is missing!""" try: return self.__getitem__(key) except KeyError: raise AttributeError(key) def __copy__(self): # TODO: https://github.com/plotly/python-api/issues/291 return GraphObjectFactory.create(self._name, _parent=self.parent, _parent_key=self._parent_key, **self) def __deepcopy__(self, memodict={}): # TODO: https://github.com/plotly/python-api/issues/291 return self.__copy__() def __missing__(self, key): """Mimics defaultdict. This is called from __getitem__ when key DNE.""" if key in self._get_valid_attributes(): if self._get_attribute_role(key) == 'object': value = GraphObjectFactory.create(key, _parent=self, _parent_key=key) return super(PlotlyDict, self).__setitem__(key, value) subplot_key = self._get_subplot_key(key) if subplot_key is not None: value = GraphObjectFactory.create(subplot_key, _parent=self, _parent_key=key) super(PlotlyDict, self).__setitem__(key, value) def _get_attribute_role(self, key, value=None): """See `graph_reference.get_role`.""" object_name = self._name parent_object_names = self._get_parent_object_names() return graph_reference.get_role( object_name, key, value=value, parent_object_names=parent_object_names ) def _get_valid_attributes(self): """See `graph_reference.get_valid_attributes`.""" if self._valid_attributes is None: parent_object_names = self._get_parent_object_names() valid_attributes = graph_reference.get_valid_attributes( self._name, parent_object_names ) self.__dict__['_valid_attributes'] = valid_attributes return self._valid_attributes def _get_deprecated_attributes(self): """See `graph_reference.get_deprecated_attributes`.""" if self._deprecated_attributes is None: parent_object_names = self._get_parent_object_names() deprecated_attributes = graph_reference.get_deprecated_attributes( self._name, parent_object_names ) self.__dict__['_deprecated_attributes'] = deprecated_attributes return self._deprecated_attributes def _get_subplot_attributes(self): """See `graph_reference.get_subplot_attributes`.""" if self._subplot_attributes is None: parent_object_names = self._get_parent_object_names() subplot_attributes = graph_reference.get_subplot_attributes( self._name, parent_object_names ) self.__dict__['_subplot_attributes'] = subplot_attributes return self._subplot_attributes def _get_subplot_key(self, key): """Some keys can have appended integers, this handles that.""" match = re.search(r'(?P\d+$)', key) if match: root_key = key[:match.start()] if (root_key in self._get_subplot_attributes() and not match.group('digits').startswith('0')): return root_key def _value_to_graph_object(self, key, value, _raise=True): """ Attempt to convert value to graph object. :param (str|unicode) key: Should be an object_name from GRAPH_REFERENCE :param (dict) value: This will fail if it's not a dict. :param (bool) _raise: Flag to prevent inappropriate erring. :return: (PlotlyList|PlotlyDict|None) `None` if `_raise` and failure. """ if key in graph_reference.ARRAYS: val_types = (list, ) else: val_types = (dict, ) if not isinstance(value, val_types): if _raise: path = self._get_path() + (key, ) raise exceptions.PlotlyDictValueError(self, path) else: return # this can be `None` when `_raise == False` return GraphObjectFactory.create(key, value, _raise=_raise, _parent=self, _parent_key=key) def help(self, attribute=None, return_help=False): """ Print help string for this object or an attribute of this object. :param (str) attribute: A valid attribute string for this object. :param (bool) return_help: Return help_string instead of printing it? :return: (None|str) """ if not attribute: return super(PlotlyDict, self).help(return_help=return_help) object_name = self._name path = self._get_path() parent_object_names = self._get_parent_object_names() help_string = graph_objs_tools.get_help(object_name, path, parent_object_names, attribute) if return_help: return help_string print(help_string) def update(self, dict1=None, **dict2): """ Update current dict with dict1 and then dict2. This recursively updates the structure of the original dictionary-like object with the new entries in the second and third objects. This allows users to update with large, nested structures. Note, because the dict2 packs up all the keyword arguments, you can specify the changes as a list of keyword agruments. Examples: # update with dict obj = Layout(title='my title', xaxis=XAxis(range=[0,1], domain=[0,1])) update_dict = dict(title='new title', xaxis=dict(domain=[0,.8])) obj.update(update_dict) obj {'title': 'new title', 'xaxis': {'range': [0,1], 'domain': [0,.8]}} # update with list of keyword arguments obj = Layout(title='my title', xaxis=XAxis(range=[0,1], domain=[0,1])) obj.update(title='new title', xaxis=dict(domain=[0,.8])) obj {'title': 'new title', 'xaxis': {'range': [0,1], 'domain': [0,.8]}} This 'fully' supports duck-typing in that the call signature is identical, however this differs slightly from the normal update method provided by Python's dictionaries. """ if dict1 is not None: for key, val in list(dict1.items()): if key in self: if isinstance(self[key], (PlotlyDict, PlotlyList)): self[key].update(val) else: self[key] = val else: self[key] = val if len(dict2): for key, val in list(dict2.items()): if key in self: if isinstance(self[key], (PlotlyDict, PlotlyList)): self[key].update(val) else: self[key] = val else: self[key] = val def strip_style(self): """ Recursively strip style from the current representation. All PlotlyDicts and PlotlyLists are guaranteed to survive the stripping process, though they made be left empty. This is allowable. Keys that will be stripped in this process are tagged with `'type': 'style'` in graph_objs_meta.json. Note that a key tagged as style, but with an array as a value may still be considered data. """ keys = list(self.keys()) for key in keys: if isinstance(self[key], (PlotlyDict, PlotlyList)): self[key].strip_style() else: if self._get_attribute_role(key, value=self[key]) == 'style': del self[key] # this is for backwards compat when we updated graph reference. elif self._name == 'layout' and key == 'autosize': del self[key] def get_data(self, flatten=False): """Returns the JSON for the plot with non-data elements stripped.""" d = dict() for key, val in list(self.items()): if isinstance(val, (PlotlyDict, PlotlyList)): sub_data = val.get_data(flatten=flatten) if flatten: for sub_key, sub_val in sub_data.items(): key_string = "{0}.{1}".format(key, sub_key) d[key_string] = sub_val else: d[key] = sub_data else: if self._get_attribute_role(key, value=val) == 'data': d[key] = val # we use the name to help make data frames if self._name in graph_reference.TRACE_NAMES and key == 'name': d[key] = val keys = list(d.keys()) for key in keys: if isinstance(d[key], (dict, list)): if len(d[key]) == 0: del d[key] return d def get_ordered(self, **kwargs): """Return a predictable, OrderedDict version of self.""" keys = sorted(self.keys(), key=graph_objs_tools.sort_keys) ordered = OrderedDict() for key in keys: if isinstance(self[key], PlotlyBase): ordered[key] = self[key].get_ordered() else: ordered[key] = self[key] return ordered def to_string(self, level=0, indent=4, eol='\n', pretty=True, max_chars=80): """ Returns a formatted string showing graph_obj constructors. :param (int) level: The number of indentations to start with. :param (int) indent: The indentation amount. :param (str) eol: The end of line character(s). :param (bool) pretty: Curtail long list output with a '..' ? :param (int) max_chars: The max characters per line. Example: print(obj.to_string()) """ if not len(self): return "{name}()".format(name=self._get_class_name()) string = "{name}(".format(name=self._get_class_name()) if self._name in graph_reference.TRACE_NAMES: keys = [key for key in self.keys() if key != 'type'] else: keys = self.keys() keys = sorted(keys, key=graph_objs_tools.sort_keys) num_keys = len(keys) for index, key in enumerate(keys, 1): string += "{eol}{indent}{key}=".format( eol=eol, indent=' ' * indent * (level+1), key=key) if isinstance(self[key], PlotlyBase): string += self[key].to_string(level=level+1, indent=indent, eol=eol, pretty=pretty, max_chars=max_chars) else: if pretty: # curtail representation if too many chars max_len = (max_chars - indent*(level + 1) - len(key + "=") - len(eol)) if index < num_keys: max_len -= len(',') # remember the comma! if isinstance(self[key], list): s = "[]" for iii, entry in enumerate(self[key], 1): if iii < len(self[key]): s_sub = graph_objs_tools.curtail_val_repr( entry, max_chars=max_len - len(s), add_delim=True ) else: s_sub = graph_objs_tools.curtail_val_repr( entry, max_chars=max_len - len(s), add_delim=False ) s = s[:-1] + s_sub + s[-1] if len(s) == max_len: break string += s else: string += graph_objs_tools.curtail_val_repr( self[key], max_len) else: # they want it all! string += repr(self[key]) if index < num_keys: string += "," string += "{eol}{indent})".format(eol=eol, indent=' ' * indent * level) return string def force_clean(self, **kwargs): """Recursively remove empty/None values.""" keys = list(self.keys()) for key in keys: try: self[key].force_clean() except AttributeError: pass if isinstance(self[key], (dict, list)): if len(self[key]) == 0: del self[key] # clears empty collections! elif self[key] is None: del self[key] class GraphObjectFactory(object): """GraphObject creation in this module should run through this factory.""" @staticmethod def create(object_name, *args, **kwargs): """ Create a graph object from the OBJECTS dict by name, args, and kwargs. :param (str) object_name: A valid object name from OBJECTS. :param args: Arguments to pass to class constructor. :param kwargs: Keyword arguments to pass to class constructor. :return: (PlotlyList|PlotlyDict) The instantiated graph object. """ is_array = object_name in graph_reference.ARRAYS is_object = object_name in graph_reference.OBJECTS if not (is_array or is_object): raise exceptions.PlotlyError( "'{}' is not a valid object name.".format(object_name) ) # We patch Figure and Data, so they actually require the subclass. class_name = graph_reference.OBJECT_NAME_TO_CLASS_NAME.get(object_name) if class_name in ['Figure', 'Data']: return globals()[class_name](*args, **kwargs) else: kwargs['_name'] = object_name if is_array: return PlotlyList(*args, **kwargs) else: return PlotlyDict(*args, **kwargs) def _add_classes_to_globals(globals): """ Create and add all the Graph Objects to this module for export. :param (dict) globals: The globals() dict from this module. """ for class_name, class_dict in graph_reference.CLASSES.items(): object_name = class_dict['object_name'] base_type = class_dict['base_type'] # This is for backwards compat (e.g., Trace) and future changes. if object_name is None: globals[class_name] = base_type continue doc = graph_objs_tools.get_help(object_name) if object_name in graph_reference.ARRAYS: class_bases = (PlotlyList, ) else: class_bases = (PlotlyDict, ) class_dict = {'__doc__': doc, '__name__': class_name, '_name': object_name} cls = type(str(class_name), class_bases, class_dict) globals[class_name] = cls def _patch_figure_class(figure_class): def __init__(self, *args, **kwargs): super(figure_class, self).__init__(*args, **kwargs) if 'data' not in self: self.data = GraphObjectFactory.create('data', _parent=self, _parent_key='data') figure_class.__init__ = __init__ def get_data(self, flatten=False): """ Returns the JSON for the plot with non-data elements stripped. Flattening may increase the utility of the result. :param (bool) flatten: {'a': {'b': ''}} --> {'a.b': ''} :returns: (dict|list) Depending on (flat|unflat) """ return self.data.get_data(flatten=flatten) figure_class.get_data = get_data def to_dataframe(self): """ Create a pandas dataframe with trace names and keys as column names. :return: (DataFrame) """ data = self.get_data(flatten=True) from pandas import DataFrame, Series return DataFrame(dict([(k, Series(v)) for k, v in data.items()])) figure_class.to_dataframe = to_dataframe def print_grid(self): """ Print a visual layout of the figure's axes arrangement. This is only valid for figures that are created with plotly.tools.make_subplots. """ try: grid_str = self.__dict__['_grid_str'] except AttributeError: raise Exception("Use plotly.tools.make_subplots " "to create a subplot grid.") print(grid_str) figure_class.print_grid = print_grid def append_trace(self, trace, row, col): """ Add a data traces to your figure bound to axes at the row, col index. The row, col index is generated from figures created with plotly.tools.make_subplots and can be viewed with Figure.print_grid. :param (dict) trace: The data trace to be bound. :param (int) row: Subplot row index (see Figure.print_grid). :param (int) col: Subplot column index (see Figure.print_grid). Example: # stack two subplots vertically fig = tools.make_subplots(rows=2) This is the format of your plot grid: [ (1,1) x1,y1 ] [ (2,1) x2,y2 ] fig.append_trace(Scatter(x=[1,2,3], y=[2,1,2]), 1, 1) fig.append_trace(Scatter(x=[1,2,3], y=[2,1,2]), 2, 1) """ try: grid_ref = self._grid_ref except AttributeError: raise Exception("In order to use Figure.append_trace, " "you must first use plotly.tools.make_subplots " "to create a subplot grid.") if row <= 0: raise Exception("Row value is out of range. " "Note: the starting cell is (1, 1)") if col <= 0: raise Exception("Col value is out of range. " "Note: the starting cell is (1, 1)") try: ref = grid_ref[row-1][col-1] except IndexError: raise Exception("The (row, col) pair sent is out of range. " "Use Figure.print_grid to view the subplot grid. ") if 'scene' in ref[0]: trace['scene'] = ref[0] if ref[0] not in self['layout']: raise Exception("Something went wrong. " "The scene object for ({r},{c}) subplot cell " "got deleted.".format(r=row, c=col)) else: xaxis_key = "xaxis{ref}".format(ref=ref[0][1:]) yaxis_key = "yaxis{ref}".format(ref=ref[1][1:]) if (xaxis_key not in self['layout'] or yaxis_key not in self['layout']): raise Exception("Something went wrong. " "An axis object for ({r},{c}) subplot cell " "got deleted.".format(r=row, c=col)) trace['xaxis'] = ref[0] trace['yaxis'] = ref[1] self['data'] += [trace] figure_class.append_trace = append_trace def _patch_data_class(data_class): def _value_to_graph_object(self, index, value, _raise=True): if not isinstance(value, dict): if _raise: notes = ['Entry should subclass dict.'] path = self._get_path() + (index, ) raise exceptions.PlotlyListEntryError(self, path, notes=notes) else: return item = value.get('type', 'scatter') if item not in graph_reference.ARRAYS['data']['items']: if _raise: path = self._get_path() + (0, ) raise exceptions.PlotlyDataTypeError(self, path) return GraphObjectFactory.create(item, _raise=_raise, _parent=self, _parent_key=index, **value) data_class._value_to_graph_object = _value_to_graph_object def get_data(self, flatten=False): """ Returns the JSON for the plot with non-data elements stripped. :param (bool) flatten: {'a': {'b': ''}} --> {'a.b': ''} :returns: (dict|list) Depending on (flat|unflat) """ if flatten: data = [v.get_data(flatten=flatten) for v in self] d = {} taken_names = [] for i, trace in enumerate(data): # we want to give the traces helpful names # however, we need to be sure they're unique too... trace_name = trace.pop('name', 'trace_{0}'.format(i)) if trace_name in taken_names: j = 1 new_trace_name = "{0}_{1}".format(trace_name, j) while new_trace_name in taken_names: new_trace_name = "{0}_{1}".format(trace_name, j) j += 1 trace_name = new_trace_name taken_names.append(trace_name) # finish up the dot-concatenation for k, v in trace.items(): key = "{0}.{1}".format(trace_name, k) d[key] = v return d else: return super(data_class, self).get_data(flatten=flatten) data_class.get_data = get_data _add_classes_to_globals(globals()) _patch_figure_class(globals()['Figure']) _patch_data_class(globals()['Data']) # We don't want to expose this module to users, just the classes. # See http://blog.labix.org/2008/06/27/watch-out-for-listdictkeys-in-python-3 __all__ = list(graph_reference.CLASSES.keys()) plotly-1.9.5+dfsg.orig/plotly/graph_reference.py0000644000175000017500000004507012645550357021315 0ustar noahfxnoahfx""" This module handles accessing, storing, and managing the graph reference. """ from __future__ import absolute_import import hashlib import json import os import re from pkg_resources import resource_string import requests import six from plotly import files, utils GRAPH_REFERENCE_PATH = '/v2/plot-schema' GRAPH_REFERENCE_DOWNLOAD_TIMEOUT = 5 # seconds # For backwards compat, we keep this list of previously known objects. # Moving forward, we only add new trace names. # {: {'object_name': , 'base_type': } _BACKWARDS_COMPAT_CLASS_NAMES = { 'AngularAxis': {'object_name': 'angularaxis', 'base_type': dict}, 'Annotation': {'object_name': 'annotation', 'base_type': dict}, 'Annotations': {'object_name': 'annotations', 'base_type': list}, 'Area': {'object_name': 'area', 'base_type': dict}, 'Bar': {'object_name': 'bar', 'base_type': dict}, 'Box': {'object_name': 'box', 'base_type': dict}, 'ColorBar': {'object_name': 'colorbar', 'base_type': dict}, 'Contour': {'object_name': 'contour', 'base_type': dict}, 'Contours': {'object_name': 'contours', 'base_type': dict}, 'Data': {'object_name': 'data', 'base_type': list}, 'ErrorX': {'object_name': 'error_x', 'base_type': dict}, 'ErrorY': {'object_name': 'error_y', 'base_type': dict}, 'ErrorZ': {'object_name': 'error_z', 'base_type': dict}, 'Figure': {'object_name': 'figure', 'base_type': dict}, 'Font': {'object_name': 'font', 'base_type': dict}, 'Heatmap': {'object_name': 'heatmap', 'base_type': dict}, 'Histogram': {'object_name': 'histogram', 'base_type': dict}, 'Histogram2d': {'object_name': 'histogram2d', 'base_type': dict}, 'Histogram2dContour': {'object_name': 'histogram2dcontour', 'base_type': dict}, 'Layout': {'object_name': 'layout', 'base_type': dict}, 'Legend': {'object_name': 'legend', 'base_type': dict}, 'Line': {'object_name': 'line', 'base_type': dict}, 'Margin': {'object_name': 'margin', 'base_type': dict}, 'Marker': {'object_name': 'marker', 'base_type': dict}, 'RadialAxis': {'object_name': 'radialaxis', 'base_type': dict}, 'Scatter': {'object_name': 'scatter', 'base_type': dict}, 'Scatter3d': {'object_name': 'scatter3d', 'base_type': dict}, 'Scene': {'object_name': 'scene', 'base_type': dict}, 'Stream': {'object_name': 'stream', 'base_type': dict}, 'Surface': {'object_name': 'surface', 'base_type': dict}, 'Trace': {'object_name': None, 'base_type': dict}, 'XAxis': {'object_name': 'xaxis', 'base_type': dict}, 'XBins': {'object_name': 'xbins', 'base_type': dict}, 'YAxis': {'object_name': 'yaxis', 'base_type': dict}, 'YBins': {'object_name': 'ybins', 'base_type': dict}, 'ZAxis': {'object_name': 'zaxis', 'base_type': dict} } def get_graph_reference(): """ Attempts to load local copy of graph reference or makes GET request if DNE. :return: (dict) The graph reference. :raises: (PlotlyError) When graph reference DNE and GET request fails. """ default_config = files.FILE_CONTENT[files.CONFIG_FILE] if files.check_file_permissions(): graph_reference = utils.load_json_dict(files.GRAPH_REFERENCE_FILE) config = utils.load_json_dict(files.CONFIG_FILE) # TODO: https://github.com/plotly/python-api/issues/293 plotly_api_domain = config.get('plotly_api_domain', default_config['plotly_api_domain']) else: graph_reference = {} plotly_api_domain = default_config['plotly_api_domain'] sha1 = hashlib.sha1(six.b(str(graph_reference))).hexdigest() graph_reference_url = '{}{}?sha1={}'.format(plotly_api_domain, GRAPH_REFERENCE_PATH, sha1) try: response = requests.get(graph_reference_url, timeout=GRAPH_REFERENCE_DOWNLOAD_TIMEOUT) response.raise_for_status() except requests.exceptions.RequestException: if not graph_reference: path = os.path.join('graph_reference', 'default-schema.json') s = resource_string('plotly', path).decode('utf-8') graph_reference = json.loads(s) else: if six.PY3: content = str(response.content, encoding='utf-8') else: content = response.content data = json.loads(content) if data['modified']: graph_reference = data['schema'] return utils.decode_unicode(graph_reference) def string_to_class_name(string): """ Single function to handle turning object names into class names. GRAPH_REFERENCE has names like `error_y`, which we'll turn into `ErrorY`. :param (str) string: A string that we'll turn into a class name string. :return: (str) """ # capitalize first letter string = re.sub(r'[A-Za-z]', lambda m: m.group().title(), string, count=1) # replace `*_` with `*` E.g., `Error_x` --> `ErrorX` string = re.sub(r'_[A-Za-z0-9]+', lambda m: m.group()[1:].title(), string) return str(string) def object_name_to_class_name(object_name): """Not all objects have classes auto-generated.""" if object_name in TRACE_NAMES: return string_to_class_name(object_name) if object_name in OBJECT_NAME_TO_CLASS_NAME: return OBJECT_NAME_TO_CLASS_NAME[object_name] if object_name in ARRAYS: return 'list' else: return 'dict' def get_attributes_dicts(object_name, parent_object_names=()): """ Returns *all* attribute information given the context of parents. The response has the form: { ('some', 'path'): {}, ('some', 'other', 'path'): {}, ... 'additional_attributes': {} } There may be any number of paths mapping to attribute dicts. There will be one attribute dict under 'additional_attributes' which will usually be empty. :param (str|unicode) object_name: The object name whose attributes we want. :param (list[str|unicode]) parent_object_names: Names of parent objects. :return: (dict) """ object_dict = OBJECTS[object_name] # If we patched this object, we may have added hard-coded attrs. additional_attributes = object_dict['additional_attributes'] # We should also one or more paths where attributes are defined. attribute_paths = list(object_dict['attribute_paths']) # shallow copy # If we have parent_names, some of these attribute paths may be invalid. for parent_object_name in reversed(parent_object_names): if parent_object_name in ARRAYS: continue parent_object_dict = OBJECTS[parent_object_name] parent_attribute_paths = parent_object_dict['attribute_paths'] for path in list(attribute_paths): if not _is_valid_sub_path(path, parent_attribute_paths): attribute_paths.remove(path) # We return a dict mapping paths to attributes. We also add in additional # attributes if defined. attributes_dicts = {path: utils.get_by_path(GRAPH_REFERENCE, path) for path in attribute_paths} attributes_dicts['additional_attributes'] = additional_attributes return attributes_dicts def get_valid_attributes(object_name, parent_object_names=()): attributes = get_attributes_dicts(object_name, parent_object_names) # These are for documentation and quick lookups. They're just strings. valid_attributes = set() for attributes_dict in attributes.values(): for key, val in attributes_dict.items(): if key not in GRAPH_REFERENCE['defs']['metaKeys']: valid_attributes.add(key) deprecated_attributes = attributes_dict.get('_deprecated', {}) for key, val in deprecated_attributes.items(): if key not in GRAPH_REFERENCE['defs']['metaKeys']: valid_attributes.add(key) return valid_attributes def get_deprecated_attributes(object_name, parent_object_names=()): attributes = get_attributes_dicts(object_name, parent_object_names) # These are for documentation and quick lookups. They're just strings. deprecated_attributes = set() for attributes_dict in attributes.values(): deprecated_attributes_dict = attributes_dict.get('_deprecated', {}) for key, val in deprecated_attributes_dict.items(): if key not in GRAPH_REFERENCE['defs']['metaKeys']: deprecated_attributes.add(key) return deprecated_attributes def get_subplot_attributes(object_name, parent_object_names=()): attributes = get_attributes_dicts(object_name, parent_object_names) # These are for documentation and quick lookups. They're just strings. subplot_attributes = set() for attributes_dict in attributes.values(): for key, val in attributes_dict.items(): if key not in GRAPH_REFERENCE['defs']['metaKeys']: if isinstance(val, dict) and val.get('_isSubplotObj'): subplot_attributes.add(key) deprecated_attributes = attributes_dict.get('_deprecated', {}) for key, val in deprecated_attributes.items(): if key not in GRAPH_REFERENCE['defs']['metaKeys']: if isinstance(val, dict) and val.get('_isSubplotObj'): subplot_attributes.add(key) return subplot_attributes def attribute_path_to_object_names(attribute_container_path): """ Return a location within a figure from a path existing in GRAPH_REFERENCE. Users don't need to know about GRAPH_REFERENCE, so yielding information about paths there would only be confusing. Also, the implementation and structure there may change, but figure structure won't. :param (tuple[str]) attribute_container_path: An object should exist here. :return: (tuple[str]) A tuple of object names: Example: In: ('traces', 'pie', 'attributes', 'marker') Out: ('figure', 'data', 'pie', 'marker') """ object_names = ['figure'] # this is always the case if 'layout' in attribute_container_path: for path_part in attribute_container_path: if path_part in OBJECTS: object_names.append(path_part) if path_part in ARRAYS: object_names.append(path_part) object_names.append(path_part[:-1]) elif 'layoutAttributes' in attribute_container_path: object_names.append('layout') start_index = attribute_container_path.index('layoutAttributes') for path_part in attribute_container_path[start_index:]: if path_part in OBJECTS: object_names.append(path_part) if path_part in ARRAYS: object_names.append(path_part) object_names.append(path_part[:-1]) else: # assume it's in 'traces' object_names.append('data') for path_part in attribute_container_path: if path_part in OBJECTS: object_names.append(path_part) if path_part in ARRAYS: object_names.append(path_part) object_names.append(path_part[:-1]) return tuple(object_names) def get_role(object_name, attribute, value=None, parent_object_names=()): """ Values have types associated with them based on graph_reference. 'data' type values are always kept 'style' values are kept if they're sequences (but not strings) :param (str) object_name: The name of the object containing 'attribute'. :param (str) attribute: The attribute we want the `role` of. :param (*) value: If the value is an array, the return can be different. :param parent_object_names: An iterable of obj names from graph reference. :returns: (str) This will be 'data', 'style', or 'info'. """ if object_name in TRACE_NAMES and attribute == 'type': return 'info' attributes_dicts = get_attributes_dicts(object_name, parent_object_names) matches = [] for attributes_dict in attributes_dicts.values(): for key, val in attributes_dict.items(): if key == attribute: matches.append(val) for key, val in attributes_dict.get('_deprecated', {}).items(): if key == attribute: matches.append(val) roles = [] for match in matches: role = match['role'] array_ok = match.get('arrayOk') if value is not None and array_ok: iterable = hasattr(value, '__iter__') stringy = isinstance(value, six.string_types) dicty = isinstance(value, dict) if iterable and not stringy and not dicty: role = 'data' roles.append(role) # TODO: this is ambiguous until the figure is in place... if 'data' in roles: role = 'data' else: role = roles[0] return role def _is_valid_sub_path(path, parent_paths): """ Check if a sub path is valid given an iterable of parent paths. :param (tuple[str]) path: The path that may be a sub path. :param (list[tuple]) parent_paths: The known parent paths. :return: (bool) Examples: * ('a', 'b', 'c') is a valid subpath of ('a', ) * ('a', 'd') is not a valid subpath of ('b', ) * ('a', ) is not a valid subpath of ('a', 'b') * ('anything',) is a valid subpath of () """ if not parent_paths: return True for parent_path in parent_paths: if path[:len(parent_path)] == parent_path: return True return False def _get_objects(): """ Create a reorganization of graph reference which organizes by object name. Each object can have *many* different definitions in the graph reference. These possibilities get narrowed down when we have contextual information about parent objects. For instance, Marker in Scatter has a different definition than Marker in Pie. However, we need Marker, Scatter, and Pie to exist on their own as well. Each value has the form: { 'meta_paths': [], 'attribute_paths': [], 'additional_attributes': {} } * meta_paths describes the top-most path where this object is defined * attribute_paths describes all the locations where attributes exist * additional_attributes can be used to hard-code (patch) the plot schema :return: (dict) """ objects = {} for node, path in utils.node_generator(GRAPH_REFERENCE): if any([key in path for key in GRAPH_REFERENCE['defs']['metaKeys']]): continue # objects don't exist under nested meta keys if node.get('role') != 'object': continue if 'items' in node: continue object_name = path[-1] if object_name not in objects: objects[object_name] = {'meta_paths': [], 'attribute_paths': [], 'additional_attributes': {}} if node.get('attributes'): objects[object_name]['attribute_paths'].append( path + ('attributes', ) ) else: objects[object_name]['attribute_paths'].append(path) objects[object_name]['meta_paths'].append(path) return objects def _patch_objects(): """Things like Layout, Figure, and Data need to be included.""" layout_attribute_paths = [] for node, path in utils.node_generator(GRAPH_REFERENCE): if any([key in path for key in GRAPH_REFERENCE['defs']['metaKeys']]): continue # objects don't exist under nested meta keys if path and path[-1] == 'layoutAttributes': layout_attribute_paths.append(path) for trace_name in TRACE_NAMES: OBJECTS[trace_name] = { 'meta_paths': [('traces', trace_name)], 'attribute_paths': [('traces', trace_name, 'attributes')], 'additional_attributes': {} } OBJECTS['layout'] = {'meta_paths': [('layout', )], 'attribute_paths': layout_attribute_paths, 'additional_attributes': {}} figure_attributes = {'layout': {'role': 'object'}, 'data': {'role': 'object', '_isLinkedToArray': True}} OBJECTS['figure'] = {'meta_paths': [], 'attribute_paths': [], 'additional_attributes': figure_attributes} def _get_arrays(): """Very few arrays, but this dict is the complement of OBJECTS.""" arrays = {} for node, path in utils.node_generator(GRAPH_REFERENCE): if any([key in path for key in GRAPH_REFERENCE['defs']['metaKeys']]): continue # objects don't exist under nested meta keys if node.get('role') != 'object': continue if 'items' not in node: continue object_name = path[-1] if object_name not in arrays: items = node['items'] # If items is a dict, it's anyOf them. if isinstance(items, dict): item_names = list(items.keys()) else: item_names = [object_name[:-1]] arrays[object_name] = {'meta_paths': [path], 'items': item_names} return arrays def _patch_arrays(): """Adds information on our eventual Data array.""" ARRAYS['data'] = {'meta_paths': [('traces', )], 'items': list(TRACE_NAMES)} def _get_classes(): """ We eventually make classes out of the objects in GRAPH_REFERENCE. :return: (dict) A mapping of class names to object names. """ classes = {} # add all the objects we had before, but mark them if they no longer # exist in the graph reference for class_name, class_dict in _BACKWARDS_COMPAT_CLASS_NAMES.items(): object_name = class_dict['object_name'] base_type = class_dict['base_type'] if object_name in OBJECTS or object_name in ARRAYS: classes[class_name] = {'object_name': object_name, 'base_type': base_type} else: classes[class_name] = {'object_name': None, 'base_type': base_type} # always keep the trace dicts up to date for object_name in TRACE_NAMES: class_name = string_to_class_name(object_name) classes[class_name] = {'object_name': object_name, 'base_type': dict} return classes # The ordering here is important. GRAPH_REFERENCE = get_graph_reference() # See http://blog.labix.org/2008/06/27/watch-out-for-listdictkeys-in-python-3 TRACE_NAMES = list(GRAPH_REFERENCE['traces'].keys()) OBJECTS = _get_objects() _patch_objects() ARRAYS = _get_arrays() _patch_arrays() CLASSES = _get_classes() OBJECT_NAME_TO_CLASS_NAME = {class_dict['object_name']: class_name for class_name, class_dict in CLASSES.items() if class_dict['object_name'] is not None} plotly-1.9.5+dfsg.orig/plotly/utils.py0000644000175000017500000003262312645550357017336 0ustar noahfxnoahfx""" utils ===== Low-level functionality NOT intended for users to EVER use. """ from __future__ import absolute_import import json import os.path import re import sys import threading import pytz from . exceptions import PlotlyError try: import numpy _numpy_imported = True except ImportError: _numpy_imported = False try: import pandas _pandas_imported = True except ImportError: _pandas_imported = False try: import sage.all _sage_imported = True except ImportError: _sage_imported = False ### incase people are using threading, we lock file reads lock = threading.Lock() ### general file setup tools ### def load_json_dict(filename, *args): """Checks if file exists. Returns {} if something fails.""" data = {} if os.path.exists(filename): lock.acquire() with open(filename, "r") as f: try: data = json.load(f) if not isinstance(data, dict): data = {} except: data = {} # TODO: issue a warning and bubble it up lock.release() if args: return {key: data[key] for key in args if key in data} return data def save_json_dict(filename, json_dict): """Save json to file. Error if path DNE, not a dict, or invalid json.""" if isinstance(json_dict, dict): # this will raise a TypeError if something goes wrong json_string = json.dumps(json_dict, indent=4) lock.acquire() with open(filename, "w") as f: f.write(json_string) lock.release() else: raise TypeError("json_dict was not a dictionary. not saving.") def ensure_file_exists(filename): """Given a valid filename, make sure it exists (will create if DNE).""" if not os.path.exists(filename): head, tail = os.path.split(filename) ensure_dir_exists(head) with open(filename, 'w') as f: pass # just create the file def ensure_dir_exists(directory): """Given a valid directory path, make sure it exists.""" if dir: if not os.path.isdir(directory): os.makedirs(directory) def iso_to_plotly_time_string(iso_string): """Remove timezone info and replace 'T' delimeter with ' ' (ws).""" # make sure we don't send timezone info to plotly if (iso_string.split('-')[:3] is '00:00') or\ (iso_string.split('+')[0] is '00:00'): raise Exception("Plotly won't accept timestrings with timezone info.\n" "All timestrings are assumed to be in UTC.") iso_string = iso_string.replace('-00:00', '').replace('+00:00', '') if iso_string.endswith('T00:00:00'): return iso_string.replace('T00:00:00', '') else: return iso_string.replace('T', ' ') ### Custom JSON encoders ### class NotEncodable(Exception): pass class PlotlyJSONEncoder(json.JSONEncoder): """ Meant to be passed as the `cls` kwarg to json.dumps(obj, cls=..) See PlotlyJSONEncoder.default for more implementation information. Additionally, this encoder overrides nan functionality so that 'Inf', 'NaN' and '-Inf' encode to 'null'. Which is stricter JSON than the Python version. """ def coerce_to_strict(self, const): """ This is used to ultimately *encode* into strict JSON, see `encode` """ # before python 2.7, 'true', 'false', 'null', were include here. if const in ('Infinity', '-Infinity', 'NaN'): return None else: return const def encode(self, o): """ Load and then dump the result using parse_constant kwarg Note that setting invalid separators will cause a failure at this step. """ # this will raise errors in a normal-expected way encoded_o = super(PlotlyJSONEncoder, self).encode(o) # now: # 1. `loads` to switch Infinity, -Infinity, NaN to None # 2. `dumps` again so you get 'null' instead of extended JSON try: new_o = json.loads(encoded_o, parse_constant=self.coerce_to_strict) except ValueError: # invalid separators will fail here. raise a helpful exception raise ValueError( "Encoding into strict JSON failed. Did you set the separators " "valid JSON separators?" ) else: return json.dumps(new_o, sort_keys=self.sort_keys, indent=self.indent, separators=(self.item_separator, self.key_separator)) def default(self, obj): """ Accept an object (of unknown type) and try to encode with priority: 1. builtin: user-defined objects 2. sage: sage math cloud 3. pandas: dataframes/series 4. numpy: ndarrays 5. datetime: time/datetime objects Each method throws a NotEncoded exception if it fails. The default method will only get hit if the object is not a type that is naturally encoded by json: Normal objects: dict object list, tuple array str, unicode string int, long, float number True true False false None null Extended objects: float('nan') 'NaN' float('infinity') 'Infinity' float('-infinity') '-Infinity' Therefore, we only anticipate either unknown iterables or values here. """ # TODO: The ordering if these methods is *very* important. Is this OK? encoding_methods = ( self.encode_as_plotly, self.encode_as_sage, self.encode_as_numpy, self.encode_as_pandas, self.encode_as_datetime, self.encode_as_date, self.encode_as_list # because some values have `tolist` do last. ) for encoding_method in encoding_methods: try: return encoding_method(obj) except NotEncodable: pass return json.JSONEncoder.default(self, obj) @staticmethod def encode_as_plotly(obj): """Attempt to use a builtin `to_plotly_json` method.""" try: return obj.to_plotly_json() except AttributeError: raise NotEncodable @staticmethod def encode_as_list(obj): """Attempt to use `tolist` method to convert to normal Python list.""" if hasattr(obj, 'tolist'): return obj.tolist() else: raise NotEncodable @staticmethod def encode_as_sage(obj): """Attempt to convert sage.all.RR to floats and sage.all.ZZ to ints""" if not _sage_imported: raise NotEncodable if obj in sage.all.RR: return float(obj) elif obj in sage.all.ZZ: return int(obj) else: raise NotEncodable @staticmethod def encode_as_pandas(obj): """Attempt to convert pandas.NaT""" if not _pandas_imported: raise NotEncodable if obj is pandas.NaT: return None else: raise NotEncodable @staticmethod def encode_as_numpy(obj): """Attempt to convert numpy.ma.core.masked""" if not _numpy_imported: raise NotEncodable if obj is numpy.ma.core.masked: return float('nan') else: raise NotEncodable @staticmethod def encode_as_datetime(obj): """Attempt to convert to utc-iso time string using datetime methods.""" # first we need to get this into utc try: obj = obj.astimezone(pytz.utc) except ValueError: # we'll get a value error if trying to convert with naive datetime pass except TypeError: # pandas throws a typeerror here instead of a value error, it's OK pass except AttributeError: # we'll get an attribute error if astimezone DNE raise NotEncodable # now we need to get a nicely formatted time string try: time_string = obj.isoformat() except AttributeError: raise NotEncodable else: return iso_to_plotly_time_string(time_string) @staticmethod def encode_as_date(obj): """Attempt to convert to utc-iso time string using date methods.""" try: time_string = obj.isoformat() except AttributeError: raise NotEncodable else: return iso_to_plotly_time_string(time_string) ### unicode stuff ### def decode_unicode(coll): if isinstance(coll, list): for no, entry in enumerate(coll): if isinstance(entry, (dict, list)): coll[no] = decode_unicode(entry) else: if isinstance(entry, str): try: coll[no] = str(entry) except UnicodeEncodeError: pass elif isinstance(coll, dict): keys, vals = list(coll.keys()), list(coll.values()) for key, val in zip(keys, vals): if isinstance(val, (dict, list)): coll[key] = decode_unicode(val) elif isinstance(val, str): try: coll[key] = str(val) except UnicodeEncodeError: pass coll[str(key)] = coll.pop(key) return coll ### docstring templating ### def template_doc(**names): def _decorator(func): if sys.version[:3] != '3.2': if func.__doc__ is not None: func.__doc__ = func.__doc__.format(**names) return func return _decorator def get_first_duplicate(items): seen = set() for item in items: if item not in seen: seen.add(item) else: return item return None ### source key def is_source_key(key): src_regex = re.compile(r'.+src$') if src_regex.match(key) is not None: return True else: return False def node_generator(node, path=()): """ General, node-yielding generator. Yields (node, path) tuples when it finds values that are dict instances. A path is a sequence of hashable values that can be used as either keys to a mapping (dict) or indices to a sequence (list). A path is always wrt to some object. Given an object, a path explains how to get from the top level of that object to a nested value in the object. :param (dict) node: Part of a dict to be traversed. :param (tuple[str]) path: Defines the path of the current node. :return: (Generator) Example: >>> for node, path in node_generator({'a': {'b': 5}}): >>> print node, path {'a': {'b': 5}} () {'b': 5} ('a', ) """ if not isinstance(node, dict): return # in case it's called with a non-dict node at top level yield node, path for key, val in node.items(): if isinstance(val, dict): for item in node_generator(val, path + (key, )): yield item def get_by_path(obj, path): """ Iteratively get on obj for each key in path. :param (list|dict) obj: The top-level object. :param (tuple[str]|tuple[int]) path: Keys to access parts of obj. :return: (*) Example: >>> figure = {'data': [{'x': [5]}]} >>> path = ('data', 0, 'x') >>> get_by_path(figure, path) # [5] """ for key in path: obj = obj[key] return obj ### validation def validate_world_readable_and_sharing_settings(option_set): if ('world_readable' in option_set and option_set['world_readable'] is True and 'sharing' in option_set and option_set['sharing'] is not None and option_set['sharing'] != 'public'): raise PlotlyError( "Looks like you are setting your plot privacy to both " "public and private.\n If you set world_readable as True, " "sharing can only be set to 'public'") elif ('world_readable' in option_set and option_set['world_readable'] is False and 'sharing' in option_set and option_set['sharing'] == 'public'): raise PlotlyError( "Looks like you are setting your plot privacy to both " "public and private.\n If you set world_readable as " "False, sharing can only be set to 'private' or 'secret'") elif ('sharing' in option_set and option_set['sharing'] not in ['public', 'private', 'secret', None]): raise PlotlyError( "The 'sharing' argument only accepts one of the following " "strings:\n'public' -- for public plots\n" "'private' -- for private plots\n" "'secret' -- for private plots that can be shared with a " "secret url" ) def set_sharing_and_world_readable(option_set): if 'world_readable' in option_set and 'sharing' not in option_set: option_set['sharing'] = ( 'public' if option_set['world_readable'] else 'private') elif 'sharing' in option_set and 'world_readable' not in option_set: if option_set['sharing'] == 'public': option_set['world_readable'] = True else: option_set['world_readable'] = False plotly-1.9.5+dfsg.orig/plotly/matplotlylib/0000755000175000017500000000000012647020776020331 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/0000755000175000017500000000000012647020776022712 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/exporter.py0000644000175000017500000003001212645550357025131 0ustar noahfxnoahfx""" Matplotlib Exporter =================== This submodule contains tools for crawling a matplotlib figure and exporting relevant pieces to a renderer. """ import warnings import io from . import utils import matplotlib from matplotlib import transforms, collections class Exporter(object): """Matplotlib Exporter Parameters ---------- renderer : Renderer object The renderer object called by the exporter to create a figure visualization. See mplexporter.Renderer for information on the methods which should be defined within the renderer. close_mpl : bool If True (default), close the matplotlib figure as it is rendered. This is useful for when the exporter is used within the notebook, or with an interactive matplotlib backend. """ def __init__(self, renderer, close_mpl=True): self.close_mpl = close_mpl self.renderer = renderer def run(self, fig): """ Run the exporter on the given figure Parmeters --------- fig : matplotlib.Figure instance The figure to export """ # Calling savefig executes the draw() command, putting elements # in the correct place. fig.savefig(io.BytesIO(), format='png', dpi=fig.dpi) if self.close_mpl: import matplotlib.pyplot as plt plt.close(fig) self.crawl_fig(fig) @staticmethod def process_transform(transform, ax=None, data=None, return_trans=False, force_trans=None): """Process the transform and convert data to figure or data coordinates Parameters ---------- transform : matplotlib Transform object The transform applied to the data ax : matplotlib Axes object (optional) The axes the data is associated with data : ndarray (optional) The array of data to be transformed. return_trans : bool (optional) If true, return the final transform of the data force_trans : matplotlib.transform instance (optional) If supplied, first force the data to this transform Returns ------- code : string Code is either "data", "axes", "figure", or "display", indicating the type of coordinates output. transform : matplotlib transform the transform used to map input data to output data. Returned only if return_trans is True new_data : ndarray Data transformed to match the given coordinate code. Returned only if data is specified """ if isinstance(transform, transforms.BlendedGenericTransform): warnings.warn("Blended transforms not yet supported. " "Zoom behavior may not work as expected.") if force_trans is not None: if data is not None: data = (transform - force_trans).transform(data) transform = force_trans code = "display" if ax is not None: for (c, trans) in [("data", ax.transData), ("axes", ax.transAxes), ("figure", ax.figure.transFigure), ("display", transforms.IdentityTransform())]: if transform.contains_branch(trans): code, transform = (c, transform - trans) break if data is not None: if return_trans: return code, transform.transform(data), transform else: return code, transform.transform(data) else: if return_trans: return code, transform else: return code def crawl_fig(self, fig): """Crawl the figure and process all axes""" with self.renderer.draw_figure(fig=fig, props=utils.get_figure_properties(fig)): for ax in fig.axes: self.crawl_ax(ax) def crawl_ax(self, ax): """Crawl the axes and process all elements within""" with self.renderer.draw_axes(ax=ax, props=utils.get_axes_properties(ax)): for line in ax.lines: self.draw_line(ax, line) for text in ax.texts: self.draw_text(ax, text) for (text, ttp) in zip([ax.xaxis.label, ax.yaxis.label, ax.title], ["xlabel", "ylabel", "title"]): if(hasattr(text, 'get_text') and text.get_text()): self.draw_text(ax, text, force_trans=ax.transAxes, text_type=ttp) for artist in ax.artists: # TODO: process other artists if isinstance(artist, matplotlib.text.Text): self.draw_text(ax, artist) for patch in ax.patches: self.draw_patch(ax, patch) for collection in ax.collections: self.draw_collection(ax, collection) for image in ax.images: self.draw_image(ax, image) legend = ax.get_legend() if legend is not None: props = utils.get_legend_properties(ax, legend) with self.renderer.draw_legend(legend=legend, props=props): if props['visible']: self.crawl_legend(ax, legend) def crawl_legend(self, ax, legend): """ Recursively look through objects in legend children """ legendElements = list(utils.iter_all_children(legend._legend_box, skipContainers=True)) legendElements.append(legend.legendPatch) for child in legendElements: # force a large zorder so it appears on top child.set_zorder(1E6 + child.get_zorder()) try: # What kind of object... if isinstance(child, matplotlib.patches.Patch): self.draw_patch(ax, child, force_trans=ax.transAxes) elif isinstance(child, matplotlib.text.Text): if not (child is legend.get_children()[-1] and child.get_text() == 'None'): self.draw_text(ax, child, force_trans=ax.transAxes) elif isinstance(child, matplotlib.lines.Line2D): self.draw_line(ax, child, force_trans=ax.transAxes) elif isinstance(child, matplotlib.collections.Collection): self.draw_collection(ax, child, force_pathtrans=ax.transAxes) else: warnings.warn("Legend element %s not impemented" % child) except NotImplementedError: warnings.warn("Legend element %s not impemented" % child) def draw_line(self, ax, line, force_trans=None): """Process a matplotlib line and call renderer.draw_line""" coordinates, data = self.process_transform(line.get_transform(), ax, line.get_xydata(), force_trans=force_trans) linestyle = utils.get_line_style(line) if linestyle['dasharray'] in ['None', 'none', None]: linestyle = None markerstyle = utils.get_marker_style(line) if (markerstyle['marker'] in ['None', 'none', None] or markerstyle['markerpath'][0].size == 0): markerstyle = None label = line.get_label() if markerstyle or linestyle: self.renderer.draw_marked_line(data=data, coordinates=coordinates, linestyle=linestyle, markerstyle=markerstyle, label=label, mplobj=line) def draw_text(self, ax, text, force_trans=None, text_type=None): """Process a matplotlib text object and call renderer.draw_text""" content = text.get_text() if content: transform = text.get_transform() position = text.get_position() coords, position = self.process_transform(transform, ax, position, force_trans=force_trans) style = utils.get_text_style(text) self.renderer.draw_text(text=content, position=position, coordinates=coords, text_type=text_type, style=style, mplobj=text) def draw_patch(self, ax, patch, force_trans=None): """Process a matplotlib patch object and call renderer.draw_path""" vertices, pathcodes = utils.SVG_path(patch.get_path()) transform = patch.get_transform() coordinates, vertices = self.process_transform(transform, ax, vertices, force_trans=force_trans) linestyle = utils.get_path_style(patch, fill=patch.get_fill()) self.renderer.draw_path(data=vertices, coordinates=coordinates, pathcodes=pathcodes, style=linestyle, mplobj=patch) def draw_collection(self, ax, collection, force_pathtrans=None, force_offsettrans=None): """Process a matplotlib collection and call renderer.draw_collection""" (transform, transOffset, offsets, paths) = collection._prepare_points() offset_coords, offsets = self.process_transform( transOffset, ax, offsets, force_trans=force_offsettrans) path_coords = self.process_transform( transform, ax, force_trans=force_pathtrans) processed_paths = [utils.SVG_path(path) for path in paths] processed_paths = [(self.process_transform( transform, ax, path[0], force_trans=force_pathtrans)[1], path[1]) for path in processed_paths] path_transforms = collection.get_transforms() try: # matplotlib 1.3: path_transforms are transform objects. # Convert them to numpy arrays. path_transforms = [t.get_matrix() for t in path_transforms] except AttributeError: # matplotlib 1.4: path transforms are already numpy arrays. pass styles = {'linewidth': collection.get_linewidths(), 'facecolor': collection.get_facecolors(), 'edgecolor': collection.get_edgecolors(), 'alpha': collection._alpha, 'zorder': collection.get_zorder()} offset_dict = {"data": "before", "screen": "after"} offset_order = offset_dict[collection.get_offset_position()] self.renderer.draw_path_collection(paths=processed_paths, path_coordinates=path_coords, path_transforms=path_transforms, offsets=offsets, offset_coordinates=offset_coords, offset_order=offset_order, styles=styles, mplobj=collection) def draw_image(self, ax, image): """Process a matplotlib image object and call renderer.draw_image""" self.renderer.draw_image(imdata=utils.image_to_base64(image), extent=image.get_extent(), coordinates="data", style={"alpha": image.get_alpha(), "zorder": image.get_zorder()}, mplobj=image) plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/__init__.py0000644000175000017500000000007712645550357025030 0ustar noahfxnoahfxfrom .renderers import Renderer from .exporter import Exporter plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/utils.py0000644000175000017500000002617012645550357024433 0ustar noahfxnoahfx""" Utility Routines for Working with Matplotlib Objects ==================================================== """ import itertools import io import base64 import numpy as np import warnings import matplotlib from matplotlib.colors import colorConverter from matplotlib.path import Path from matplotlib.markers import MarkerStyle from matplotlib.transforms import Affine2D from matplotlib import ticker def color_to_hex(color): """Convert matplotlib color code to hex color code""" if color is None or colorConverter.to_rgba(color)[3] == 0: return 'none' else: rgb = colorConverter.to_rgb(color) return '#{0:02X}{1:02X}{2:02X}'.format(*(int(255 * c) for c in rgb)) def many_to_one(input_dict): """Convert a many-to-one mapping to a one-to-one mapping""" return dict((key, val) for keys, val in input_dict.items() for key in keys) LINESTYLES = many_to_one({('solid', '-', (None, None)): "10,0", ('dashed', '--'): "6,6", ('dotted', ':'): "2,2", ('dashdot', '-.'): "4,4,2,4", ('', ' ', 'None', 'none'): "none"}) def get_dasharray(obj, i=None): """Get an SVG dash array for the given matplotlib linestyle Parameters ---------- obj : matplotlib object The matplotlib line or path object, which must have a get_linestyle() method which returns a valid matplotlib line code i : integer (optional) Returns ------- dasharray : string The HTML/SVG dasharray code associated with the object. """ if obj.__dict__.get('_dashSeq', None) is not None: return ','.join(map(str, obj._dashSeq)) else: ls = obj.get_linestyle() if i is not None: ls = ls[i] dasharray = LINESTYLES.get(ls, None) if dasharray is None: warnings.warn("dash style '{0}' not understood: " "defaulting to solid.".format(ls)) dasharray = LINESTYLES['-'] return dasharray PATH_DICT = {Path.LINETO: 'L', Path.MOVETO: 'M', Path.CURVE3: 'S', Path.CURVE4: 'C', Path.CLOSEPOLY: 'Z'} def SVG_path(path, transform=None, simplify=False): """Construct the vertices and SVG codes for the path Parameters ---------- path : matplotlib.Path object transform : matplotlib transform (optional) if specified, the path will be transformed before computing the output. Returns ------- vertices : array The shape (M, 2) array of vertices of the Path. Note that some Path codes require multiple vertices, so the length of these vertices may be longer than the list of path codes. path_codes : list A length N list of single-character path codes, N <= M. Each code is a single character, in ['L','M','S','C','Z']. See the standard SVG path specification for a description of these. """ if transform is not None: path = path.transformed(transform) vc_tuples = [(vertices if path_code != Path.CLOSEPOLY else [], PATH_DICT[path_code]) for (vertices, path_code) in path.iter_segments(simplify=simplify)] if not vc_tuples: # empty path is a special case return np.zeros((0, 2)), [] else: vertices, codes = zip(*vc_tuples) vertices = np.array(list(itertools.chain(*vertices))).reshape(-1, 2) return vertices, list(codes) def get_path_style(path, fill=True): """Get the style dictionary for matplotlib path objects""" style = {} style['alpha'] = path.get_alpha() if style['alpha'] is None: style['alpha'] = 1 style['edgecolor'] = color_to_hex(path.get_edgecolor()) if fill: style['facecolor'] = color_to_hex(path.get_facecolor()) else: style['facecolor'] = 'none' style['edgewidth'] = path.get_linewidth() style['dasharray'] = get_dasharray(path) style['zorder'] = path.get_zorder() return style def get_line_style(line): """Get the style dictionary for matplotlib line objects""" style = {} style['alpha'] = line.get_alpha() if style['alpha'] is None: style['alpha'] = 1 style['color'] = color_to_hex(line.get_color()) style['linewidth'] = line.get_linewidth() style['dasharray'] = get_dasharray(line) style['zorder'] = line.get_zorder() return style def get_marker_style(line): """Get the style dictionary for matplotlib marker objects""" style = {} style['alpha'] = line.get_alpha() if style['alpha'] is None: style['alpha'] = 1 style['facecolor'] = color_to_hex(line.get_markerfacecolor()) style['edgecolor'] = color_to_hex(line.get_markeredgecolor()) style['edgewidth'] = line.get_markeredgewidth() style['marker'] = line.get_marker() markerstyle = MarkerStyle(line.get_marker()) markersize = line.get_markersize() markertransform = (markerstyle.get_transform() + Affine2D().scale(markersize, -markersize)) style['markerpath'] = SVG_path(markerstyle.get_path(), markertransform) style['markersize'] = markersize style['zorder'] = line.get_zorder() return style def get_text_style(text): """Return the text style dict for a text instance""" style = {} style['alpha'] = text.get_alpha() if style['alpha'] is None: style['alpha'] = 1 style['fontsize'] = text.get_size() style['color'] = color_to_hex(text.get_color()) style['halign'] = text.get_horizontalalignment() # left, center, right style['valign'] = text.get_verticalalignment() # baseline, center, top style['rotation'] = text.get_rotation() style['zorder'] = text.get_zorder() return style def get_axis_properties(axis): """Return the property dictionary for a matplotlib.Axis instance""" props = {} label1On = axis._major_tick_kw.get('label1On', True) if isinstance(axis, matplotlib.axis.XAxis): if label1On: props['position'] = "bottom" else: props['position'] = "top" elif isinstance(axis, matplotlib.axis.YAxis): if label1On: props['position'] = "left" else: props['position'] = "right" else: raise ValueError("{0} should be an Axis instance".format(axis)) # Use tick values if appropriate locator = axis.get_major_locator() props['nticks'] = len(locator()) if isinstance(locator, ticker.FixedLocator): props['tickvalues'] = list(locator()) else: props['tickvalues'] = None # Find tick formats formatter = axis.get_major_formatter() if isinstance(formatter, ticker.NullFormatter): props['tickformat'] = "" elif not any(label.get_visible() for label in axis.get_ticklabels()): props['tickformat'] = "" else: props['tickformat'] = None # Get axis scale props['scale'] = axis.get_scale() # Get major tick label size (assumes that's all we really care about!) labels = axis.get_ticklabels() if labels: props['fontsize'] = labels[0].get_fontsize() else: props['fontsize'] = None # Get associated grid props['grid'] = get_grid_style(axis) return props def get_grid_style(axis): gridlines = axis.get_gridlines() if axis._gridOnMajor and len(gridlines) > 0: color = color_to_hex(gridlines[0].get_color()) alpha = gridlines[0].get_alpha() dasharray = get_dasharray(gridlines[0]) return dict(gridOn=True, color=color, dasharray=dasharray, alpha=alpha) else: return {"gridOn":False} def get_figure_properties(fig): return {'figwidth': fig.get_figwidth(), 'figheight': fig.get_figheight(), 'dpi': fig.dpi} def get_axes_properties(ax): props = {'axesbg': color_to_hex(ax.patch.get_facecolor()), 'axesbgalpha': ax.patch.get_alpha(), 'bounds': ax.get_position().bounds, 'dynamic': ax.get_navigate(), 'axison': ax.axison, 'frame_on': ax.get_frame_on(), 'axes': [get_axis_properties(ax.xaxis), get_axis_properties(ax.yaxis)]} for axname in ['x', 'y']: axis = getattr(ax, axname + 'axis') domain = getattr(ax, 'get_{0}lim'.format(axname))() lim = domain if isinstance(axis.converter, matplotlib.dates.DateConverter): scale = 'date' try: import pandas as pd from pandas.tseries.converter import PeriodConverter except ImportError: pd = None if (pd is not None and isinstance(axis.converter, PeriodConverter)): _dates = [pd.Period(ordinal=int(d), freq=axis.freq) for d in domain] domain = [(d.year, d.month - 1, d.day, d.hour, d.minute, d.second, 0) for d in _dates] else: domain = [(d.year, d.month - 1, d.day, d.hour, d.minute, d.second, d.microsecond * 1E-3) for d in matplotlib.dates.num2date(domain)] else: scale = axis.get_scale() if scale not in ['date', 'linear', 'log']: raise ValueError("Unknown axis scale: " "{0}".format(axis[axname].get_scale())) props[axname + 'scale'] = scale props[axname + 'lim'] = lim props[axname + 'domain'] = domain return props def iter_all_children(obj, skipContainers=False): """ Returns an iterator over all childen and nested children using obj's get_children() method if skipContainers is true, only childless objects are returned. """ if hasattr(obj, 'get_children') and len(obj.get_children()) > 0: for child in obj.get_children(): if not skipContainers: yield child # could use `yield from` in python 3... for grandchild in iter_all_children(child, skipContainers): yield grandchild else: yield obj def get_legend_properties(ax, legend): handles, labels = ax.get_legend_handles_labels() visible = legend.get_visible() return {'handles': handles, 'labels': labels, 'visible': visible} def image_to_base64(image): """ Convert a matplotlib image to a base64 png representation Parameters ---------- image : matplotlib image object The image to be converted. Returns ------- image_base64 : string The UTF8-encoded base64 string representation of the png image. """ ax = image.axes binary_buffer = io.BytesIO() # image is saved in axes coordinates: we need to temporarily # set the correct limits to get the correct image lim = ax.axis() ax.axis(image.get_extent()) image.write_png(binary_buffer) ax.axis(lim) binary_buffer.seek(0) return base64.b64encode(binary_buffer.read()).decode('utf-8') plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/_py3k_compat.py0000644000175000017500000000067012645550357025660 0ustar noahfxnoahfx""" Simple fixes for Python 2/3 compatibility """ import sys PY3K = sys.version_info[0] >= 3 if PY3K: import builtins import functools reduce = functools.reduce zip = builtins.zip xrange = builtins.range map = builtins.map else: import __builtin__ import itertools builtins = __builtin__ reduce = __builtin__.reduce zip = itertools.izip xrange = __builtin__.xrange map = itertools.imap plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/renderers/0000755000175000017500000000000012647020776024703 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/renderers/__init__.py0000644000175000017500000000065112645550357027017 0ustar noahfxnoahfx""" Matplotlib Renderers ==================== This submodule contains renderer objects which define renderer behavior used within the Exporter class. The base renderer class is :class:`Renderer`, an abstract base class """ from .base import Renderer from .vega_renderer import VegaRenderer, fig_to_vega from .vincent_renderer import VincentRenderer, fig_to_vincent from .fake_renderer import FakeRenderer, FullFakeRenderer plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/renderers/fake_renderer.py0000644000175000017500000000500112645550357030046 0ustar noahfxnoahfxfrom .base import Renderer class FakeRenderer(Renderer): """ Fake Renderer This is a fake renderer which simply outputs a text tree representing the elements found in the plot(s). This is used in the unit tests for the package. Below are the methods your renderer must implement. You are free to do anything you wish within the renderer (i.e. build an XML or JSON representation, call an external API, etc.) Here the renderer just builds a simple string representation for testing purposes. """ def __init__(self): self.output = "" def open_figure(self, fig, props): self.output += "opening figure\n" def close_figure(self, fig): self.output += "closing figure\n" def open_axes(self, ax, props): self.output += " opening axes\n" def close_axes(self, ax): self.output += " closing axes\n" def open_legend(self, legend, props): self.output += " opening legend\n" def close_legend(self, legend): self.output += " closing legend\n" def draw_text(self, text, position, coordinates, style, text_type=None, mplobj=None): self.output += " draw text '{0}' {1}\n".format(text, text_type) def draw_path(self, data, coordinates, pathcodes, style, offset=None, offset_coordinates="data", mplobj=None): self.output += " draw path with {0} vertices\n".format(data.shape[0]) def draw_image(self, imdata, extent, coordinates, style, mplobj=None): self.output += " draw image of size {0}\n".format(len(imdata)) class FullFakeRenderer(FakeRenderer): """ Renderer with the full complement of methods. When the following are left undefined, they will be implemented via other methods in the class. They can be defined explicitly for more efficient or specialized use within the renderer implementation. """ def draw_line(self, data, coordinates, style, label, mplobj=None): self.output += " draw line with {0} points\n".format(data.shape[0]) def draw_markers(self, data, coordinates, style, label, mplobj=None): self.output += " draw {0} markers\n".format(data.shape[0]) def draw_path_collection(self, paths, path_coordinates, path_transforms, offsets, offset_coordinates, offset_order, styles, mplobj=None): self.output += (" draw path collection " "with {0} offsets\n".format(offsets.shape[0])) plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/renderers/base.py0000644000175000017500000003402312645550357026172 0ustar noahfxnoahfximport warnings import itertools from contextlib import contextmanager import numpy as np from matplotlib import transforms from .. import utils from .. import _py3k_compat as py3k class Renderer(object): @staticmethod def ax_zoomable(ax): return bool(ax and ax.get_navigate()) @staticmethod def ax_has_xgrid(ax): return bool(ax and ax.xaxis._gridOnMajor and ax.yaxis.get_gridlines()) @staticmethod def ax_has_ygrid(ax): return bool(ax and ax.yaxis._gridOnMajor and ax.yaxis.get_gridlines()) @property def current_ax_zoomable(self): return self.ax_zoomable(self._current_ax) @property def current_ax_has_xgrid(self): return self.ax_has_xgrid(self._current_ax) @property def current_ax_has_ygrid(self): return self.ax_has_ygrid(self._current_ax) @contextmanager def draw_figure(self, fig, props): if hasattr(self, "_current_fig") and self._current_fig is not None: warnings.warn("figure embedded in figure: something is wrong") self._current_fig = fig self._fig_props = props self.open_figure(fig=fig, props=props) yield self.close_figure(fig=fig) self._current_fig = None self._fig_props = {} @contextmanager def draw_axes(self, ax, props): if hasattr(self, "_current_ax") and self._current_ax is not None: warnings.warn("axes embedded in axes: something is wrong") self._current_ax = ax self._ax_props = props self.open_axes(ax=ax, props=props) yield self.close_axes(ax=ax) self._current_ax = None self._ax_props = {} @contextmanager def draw_legend(self, legend, props): self._current_legend = legend self._legend_props = props self.open_legend(legend=legend, props=props) yield self.close_legend(legend=legend) self._current_legend = None self._legend_props = {} # Following are the functions which should be overloaded in subclasses def open_figure(self, fig, props): """ Begin commands for a particular figure. Parameters ---------- fig : matplotlib.Figure The Figure which will contain the ensuing axes and elements props : dictionary The dictionary of figure properties """ pass def close_figure(self, fig): """ Finish commands for a particular figure. Parameters ---------- fig : matplotlib.Figure The figure which is finished being drawn. """ pass def open_axes(self, ax, props): """ Begin commands for a particular axes. Parameters ---------- ax : matplotlib.Axes The Axes which will contain the ensuing axes and elements props : dictionary The dictionary of axes properties """ pass def close_axes(self, ax): """ Finish commands for a particular axes. Parameters ---------- ax : matplotlib.Axes The Axes which is finished being drawn. """ pass def open_legend(self, legend, props): """ Beging commands for a particular legend. Parameters ---------- legend : matplotlib.legend.Legend The Legend that will contain the ensuing elements props : dictionary The dictionary of legend properties """ pass def close_legend(self, legend): """ Finish commands for a particular legend. Parameters ---------- legend : matplotlib.legend.Legend The Legend which is finished being drawn """ pass def draw_marked_line(self, data, coordinates, linestyle, markerstyle, label, mplobj=None): """Draw a line that also has markers. If this isn't reimplemented by a renderer object, by default, it will make a call to BOTH draw_line and draw_markers when both markerstyle and linestyle are not None in the same Line2D object. """ if linestyle is not None: self.draw_line(data, coordinates, linestyle, label, mplobj) if markerstyle is not None: self.draw_markers(data, coordinates, markerstyle, label, mplobj) def draw_line(self, data, coordinates, style, label, mplobj=None): """ Draw a line. By default, draw the line via the draw_path() command. Some renderers might wish to override this and provide more fine-grained behavior. In matplotlib, lines are generally created via the plt.plot() command, though this command also can create marker collections. Parameters ---------- data : array_like A shape (N, 2) array of datapoints. coordinates : string A string code, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. style : dictionary a dictionary specifying the appearance of the line. mplobj : matplotlib object the matplotlib plot element which generated this line """ pathcodes = ['M'] + (data.shape[0] - 1) * ['L'] pathstyle = dict(facecolor='none', **style) pathstyle['edgecolor'] = pathstyle.pop('color') pathstyle['edgewidth'] = pathstyle.pop('linewidth') self.draw_path(data=data, coordinates=coordinates, pathcodes=pathcodes, style=pathstyle, mplobj=mplobj) @staticmethod def _iter_path_collection(paths, path_transforms, offsets, styles): """Build an iterator over the elements of the path collection""" N = max(len(paths), len(offsets)) if not path_transforms: path_transforms = [np.eye(3)] edgecolor = styles['edgecolor'] if np.size(edgecolor) == 0: edgecolor = ['none'] facecolor = styles['facecolor'] if np.size(facecolor) == 0: facecolor = ['none'] elements = [paths, path_transforms, offsets, edgecolor, styles['linewidth'], facecolor] it = itertools return it.islice(py3k.zip(*py3k.map(it.cycle, elements)), N) def draw_path_collection(self, paths, path_coordinates, path_transforms, offsets, offset_coordinates, offset_order, styles, mplobj=None): """ Draw a collection of paths. The paths, offsets, and styles are all iterables, and the number of paths is max(len(paths), len(offsets)). By default, this is implemented via multiple calls to the draw_path() function. For efficiency, Renderers may choose to customize this implementation. Examples of path collections created by matplotlib are scatter plots, histograms, contour plots, and many others. Parameters ---------- paths : list list of tuples, where each tuple has two elements: (data, pathcodes). See draw_path() for a description of these. path_coordinates: string the coordinates code for the paths, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. path_transforms: array_like an array of shape (*, 3, 3), giving a series of 2D Affine transforms for the paths. These encode translations, rotations, and scalings in the standard way. offsets: array_like An array of offsets of shape (N, 2) offset_coordinates : string the coordinates code for the offsets, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. offset_order : string either "before" or "after". This specifies whether the offset is applied before the path transform, or after. The matplotlib backend equivalent is "before"->"data", "after"->"screen". styles: dictionary A dictionary in which each value is a list of length N, containing the style(s) for the paths. mplobj : matplotlib object the matplotlib plot element which generated this collection """ if offset_order == "before": raise NotImplementedError("offset before transform") for tup in self._iter_path_collection(paths, path_transforms, offsets, styles): (path, path_transform, offset, ec, lw, fc) = tup vertices, pathcodes = path path_transform = transforms.Affine2D(path_transform) vertices = path_transform.transform(vertices) # This is a hack: if path_coordinates == "figure": path_coordinates = "points" style = {"edgecolor": utils.color_to_hex(ec), "facecolor": utils.color_to_hex(fc), "edgewidth": lw, "dasharray": "10,0", "alpha": styles['alpha'], "zorder": styles['zorder']} self.draw_path(data=vertices, coordinates=path_coordinates, pathcodes=pathcodes, style=style, offset=offset, offset_coordinates=offset_coordinates, mplobj=mplobj) def draw_markers(self, data, coordinates, style, label, mplobj=None): """ Draw a set of markers. By default, this is done by repeatedly calling draw_path(), but renderers should generally overload this method to provide a more efficient implementation. In matplotlib, markers are created using the plt.plot() command. Parameters ---------- data : array_like A shape (N, 2) array of datapoints. coordinates : string A string code, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. style : dictionary a dictionary specifying the appearance of the markers. mplobj : matplotlib object the matplotlib plot element which generated this marker collection """ vertices, pathcodes = style['markerpath'] pathstyle = dict((key, style[key]) for key in ['alpha', 'edgecolor', 'facecolor', 'zorder', 'edgewidth']) pathstyle['dasharray'] = "10,0" for vertex in data: self.draw_path(data=vertices, coordinates="points", pathcodes=pathcodes, style=pathstyle, offset=vertex, offset_coordinates=coordinates, mplobj=mplobj) def draw_text(self, text, position, coordinates, style, text_type=None, mplobj=None): """ Draw text on the image. Parameters ---------- text : string The text to draw position : tuple The (x, y) position of the text coordinates : string A string code, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. style : dictionary a dictionary specifying the appearance of the text. text_type : string or None if specified, a type of text such as "xlabel", "ylabel", "title" mplobj : matplotlib object the matplotlib plot element which generated this text """ raise NotImplementedError() def draw_path(self, data, coordinates, pathcodes, style, offset=None, offset_coordinates="data", mplobj=None): """ Draw a path. In matplotlib, paths are created by filled regions, histograms, contour plots, patches, etc. Parameters ---------- data : array_like A shape (N, 2) array of datapoints. coordinates : string A string code, which should be either 'data' for data coordinates, 'figure' for figure (pixel) coordinates, or "points" for raw point coordinates (useful in conjunction with offsets, below). pathcodes : list A list of single-character SVG pathcodes associated with the data. Path codes are one of ['M', 'm', 'L', 'l', 'Q', 'q', 'T', 't', 'S', 's', 'C', 'c', 'Z', 'z'] See the SVG specification for details. Note that some path codes consume more than one datapoint (while 'Z' consumes none), so in general, the length of the pathcodes list will not be the same as that of the data array. style : dictionary a dictionary specifying the appearance of the line. offset : list (optional) the (x, y) offset of the path. If not given, no offset will be used. offset_coordinates : string (optional) A string code, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. mplobj : matplotlib object the matplotlib plot element which generated this path """ raise NotImplementedError() def draw_image(self, imdata, extent, coordinates, style, mplobj=None): """ Draw an image. Parameters ---------- imdata : string base64 encoded png representation of the image extent : list the axes extent of the image: [xmin, xmax, ymin, ymax] coordinates: string A string code, which should be either 'data' for data coordinates, or 'figure' for figure (pixel) coordinates. style : dictionary a dictionary specifying the appearance of the image mplobj : matplotlib object the matplotlib plot object which generated this image """ raise NotImplementedError() plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/renderers/vincent_renderer.py0000644000175000017500000000360212645550357030613 0ustar noahfxnoahfximport warnings from .base import Renderer from ..exporter import Exporter class VincentRenderer(Renderer): def open_figure(self, fig, props): self.chart = None self.figwidth = int(props['figwidth'] * props['dpi']) self.figheight = int(props['figheight'] * props['dpi']) def draw_line(self, data, coordinates, style, label, mplobj=None): import vincent # only import if VincentRenderer is used if coordinates != 'data': warnings.warn("Only data coordinates supported. Skipping this") linedata = {'x': data[:, 0], 'y': data[:, 1]} line = vincent.Line(linedata, iter_idx='x', width=self.figwidth, height=self.figheight) # TODO: respect the other style settings line.scales['color'].range = [style['color']] if self.chart is None: self.chart = line else: warnings.warn("Multiple plot elements not yet supported") def draw_markers(self, data, coordinates, style, label, mplobj=None): import vincent # only import if VincentRenderer is used if coordinates != 'data': warnings.warn("Only data coordinates supported. Skipping this") markerdata = {'x': data[:, 0], 'y': data[:, 1]} markers = vincent.Scatter(markerdata, iter_idx='x', width=self.figwidth, height=self.figheight) # TODO: respect the other style settings markers.scales['color'].range = [style['facecolor']] if self.chart is None: self.chart = markers else: warnings.warn("Multiple plot elements not yet supported") def fig_to_vincent(fig): """Convert a matplotlib figure to a vincent object""" renderer = VincentRenderer() exporter = Exporter(renderer) exporter.run(fig) return renderer.chart plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/renderers/vega_renderer.py0000644000175000017500000001224412645550357030071 0ustar noahfxnoahfximport warnings import json import random from .base import Renderer from ..exporter import Exporter class VegaRenderer(Renderer): def open_figure(self, fig, props): self.props = props self.figwidth = int(props['figwidth'] * props['dpi']) self.figheight = int(props['figheight'] * props['dpi']) self.data = [] self.scales = [] self.axes = [] self.marks = [] def open_axes(self, ax, props): if len(self.axes) > 0: warnings.warn("multiple axes not yet supported") self.axes = [dict(type="x", scale="x", ticks=10), dict(type="y", scale="y", ticks=10)] self.scales = [dict(name="x", domain=props['xlim'], type="linear", range="width", ), dict(name="y", domain=props['ylim'], type="linear", range="height", ),] def draw_line(self, data, coordinates, style, label, mplobj=None): if coordinates != 'data': warnings.warn("Only data coordinates supported. Skipping this") dataname = "table{0:03d}".format(len(self.data) + 1) # TODO: respect the other style settings self.data.append({'name': dataname, 'values': [dict(x=d[0], y=d[1]) for d in data]}) self.marks.append({'type': 'line', 'from': {'data': dataname}, 'properties': { "enter": { "interpolate": {"value": "monotone"}, "x": {"scale": "x", "field": "data.x"}, "y": {"scale": "y", "field": "data.y"}, "stroke": {"value": style['color']}, "strokeOpacity": {"value": style['alpha']}, "strokeWidth": {"value": style['linewidth']}, } } }) def draw_markers(self, data, coordinates, style, label, mplobj=None): if coordinates != 'data': warnings.warn("Only data coordinates supported. Skipping this") dataname = "table{0:03d}".format(len(self.data) + 1) # TODO: respect the other style settings self.data.append({'name': dataname, 'values': [dict(x=d[0], y=d[1]) for d in data]}) self.marks.append({'type': 'symbol', 'from': {'data': dataname}, 'properties': { "enter": { "interpolate": {"value": "monotone"}, "x": {"scale": "x", "field": "data.x"}, "y": {"scale": "y", "field": "data.y"}, "fill": {"value": style['facecolor']}, "fillOpacity": {"value": style['alpha']}, "stroke": {"value": style['edgecolor']}, "strokeOpacity": {"value": style['alpha']}, "strokeWidth": {"value": style['edgewidth']}, } } }) def draw_text(self, text, position, coordinates, style, text_type=None, mplobj=None): if text_type == 'xlabel': self.axes[0]['title'] = text elif text_type == 'ylabel': self.axes[1]['title'] = text class VegaHTML(object): def __init__(self, renderer): self.specification = dict(width=renderer.figwidth, height=renderer.figheight, data=renderer.data, scales=renderer.scales, axes=renderer.axes, marks=renderer.marks) def html(self): """Build the HTML representation for IPython.""" id = random.randint(0, 2 ** 16) html = '
' % id html += '\n' return html def _repr_html_(self): return self.html() def fig_to_vega(fig, notebook=False): """Convert a matplotlib figure to vega dictionary if notebook=True, then return an object which will display in a notebook otherwise, return an HTML string. """ renderer = VegaRenderer() Exporter(renderer).run(fig) vega_html = VegaHTML(renderer) if notebook: return vega_html else: return vega_html.html() VEGA_TEMPLATE = """ ( function() { var _do_plot = function() { if ( (typeof vg == 'undefined') && (typeof IPython != 'undefined')) { $([IPython.events]).on("vega_loaded.vincent", _do_plot); return; } vg.parse.spec(%s, function(chart) { chart({el: "#vis%d"}).update(); }); }; _do_plot(); })(); """ plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mplexporter/tools.py0000644000175000017500000000330412645550357024425 0ustar noahfxnoahfx""" Tools for matplotlib plot exporting """ def ipynb_vega_init(): """Initialize the IPython notebook display elements This function borrows heavily from the excellent vincent package: http://github.com/wrobstory/vincent """ try: from IPython.core.display import display, HTML except ImportError: print('IPython Notebook could not be loaded.') require_js = ''' if (window['d3'] === undefined) {{ require.config({{ paths: {{d3: "http://d3js.org/d3.v3.min"}} }}); require(["d3"], function(d3) {{ window.d3 = d3; {0} }}); }}; if (window['topojson'] === undefined) {{ require.config( {{ paths: {{topojson: "http://d3js.org/topojson.v1.min"}} }} ); require(["topojson"], function(topojson) {{ window.topojson = topojson; }}); }}; ''' d3_geo_projection_js_url = "http://d3js.org/d3.geo.projection.v0.min.js" d3_layout_cloud_js_url = ("http://wrobstory.github.io/d3-cloud/" "d3.layout.cloud.js") topojson_js_url = "http://d3js.org/topojson.v1.min.js" vega_js_url = 'http://trifacta.github.com/vega/vega.js' dep_libs = '''$.getScript("%s", function() { $.getScript("%s", function() { $.getScript("%s", function() { $.getScript("%s", function() { $([IPython.events]).trigger("vega_loaded.vincent"); }) }) }) });''' % (d3_geo_projection_js_url, d3_layout_cloud_js_url, topojson_js_url, vega_js_url) load_js = require_js.format(dep_libs) html = '' display(HTML(html)) plotly-1.9.5+dfsg.orig/plotly/matplotlylib/renderer.py0000644000175000017500000007451112645550357022522 0ustar noahfxnoahfx""" Renderer Module This module defines the PlotlyRenderer class and a single function, fig_to_plotly, which is intended to be the main way that user's will interact with the matplotlylib package. """ from __future__ import absolute_import import warnings import plotly.graph_objs as go from plotly.matplotlylib.mplexporter import Renderer from plotly.matplotlylib import mpltools # Warning format def warning_on_one_line(msg, category, filename, lineno, file=None, line=None): return '%s:%s: %s:\n\n%s\n\n' % (filename, lineno, category.__name__, msg) warnings.formatwarning = warning_on_one_line class PlotlyRenderer(Renderer): """A renderer class inheriting from base for rendering mpl plots in plotly. A renderer class to be used with an exporter for rendering matplotlib plots in Plotly. This module defines the PlotlyRenderer class which handles the creation of the JSON structures that get sent to plotly. All class attributes available are defined in __init__(). Basic Usage: # (mpl code) # fig = gcf() renderer = PlotlyRenderer(fig) exporter = Exporter(renderer) exporter.run(fig) # ... et voila """ def __init__(self): """Initialize PlotlyRenderer obj. PlotlyRenderer obj is called on by an Exporter object to draw matplotlib objects like figures, axes, text, etc. All class attributes are listed here in the __init__ method. """ self.plotly_fig = go.Figure() self.mpl_fig = None self.current_mpl_ax = None self.bar_containers = None self.current_bars = [] self.axis_ct = 0 self.x_is_mpl_date = False self.mpl_x_bounds = (0, 1) self.mpl_y_bounds = (0, 1) self.msg = "Initialized PlotlyRenderer\n" def open_figure(self, fig, props): """Creates a new figure by beginning to fill out layout dict. The 'autosize' key is set to false so that the figure will mirror sizes set by mpl. The 'hovermode' key controls what shows up when you mouse around a figure in plotly, it's set to show the 'closest' point. Positional agurments: fig -- a matplotlib.figure.Figure object. props.keys(): [ 'figwidth', 'figheight', 'dpi' ] """ self.msg += "Opening figure\n" self.mpl_fig = fig self.plotly_fig['layout'] = go.Layout( width=int(props['figwidth'] * props['dpi']), height=int(props['figheight'] * props['dpi']), autosize=False, hovermode='closest') self.mpl_x_bounds, self.mpl_y_bounds = mpltools.get_axes_bounds(fig) margin = go.Margin( l=int(self.mpl_x_bounds[0] * self.plotly_fig['layout']['width']), r=int( (1-self.mpl_x_bounds[1]) * self.plotly_fig['layout']['width']), t=int((1-self.mpl_y_bounds[1]) * self.plotly_fig['layout'][ 'height']), b=int(self.mpl_y_bounds[0] * self.plotly_fig['layout']['height']), pad=0) self.plotly_fig['layout']['margin'] = margin def close_figure(self, fig): """Closes figure by cleaning up data and layout dictionaries. The PlotlyRenderer's job is to create an appropriate set of data and layout dictionaries. When the figure is closed, some cleanup and repair is necessary. This method removes inappropriate dictionary entries, freeing up Plotly to use defaults and best judgements to complete the entries. This method is called by an Exporter object. Positional arguments: fig -- a matplotlib.figure.Figure object. """ self.plotly_fig.force_clean() self.plotly_fig['layout']['showlegend'] = False self.msg += "Closing figure\n" def open_axes(self, ax, props): """Setup a new axes object (subplot in plotly). Plotly stores information about subplots in different 'xaxis' and 'yaxis' objects which are numbered. These are just dictionaries included in the layout dictionary. This function takes information from the Exporter, fills in appropriate dictionary entries, and updates the layout dictionary. PlotlyRenderer keeps track of the number of plots by incrementing the axis_ct attribute. Setting the proper plot domain in plotly is a bit tricky. Refer to the documentation for mpltools.convert_x_domain and mpltools.convert_y_domain. Positional arguments: ax -- an mpl axes object. This will become a subplot in plotly. props.keys() -- [ 'axesbg', (background color for axes obj) 'axesbgalpha', (alpha, or opacity for background) 'bounds', ((x0, y0, width, height) for axes) 'dynamic', (zoom/pan-able?) 'axes', (list: [xaxis, yaxis]) 'xscale', (log, linear, or date) 'yscale', 'xlim', (range limits for x) 'ylim', 'xdomain' (xdomain=xlim, unless it's a date) 'ydomain' ] """ self.msg += " Opening axes\n" self.current_mpl_ax = ax self.bar_containers = [c for c in ax.containers # empty is OK if c.__class__.__name__ == 'BarContainer'] self.current_bars = [] self.axis_ct += 1 # set defaults in axes xaxis = go.XAxis( anchor='y{0}'.format(self.axis_ct), zeroline=False, ticks='inside') yaxis = go.YAxis( anchor='x{0}'.format(self.axis_ct), zeroline=False, ticks='inside') # update defaults with things set in mpl mpl_xaxis, mpl_yaxis = mpltools.prep_xy_axis( ax=ax, props=props, x_bounds=self.mpl_x_bounds, y_bounds=self.mpl_y_bounds) xaxis.update(mpl_xaxis) yaxis.update(mpl_yaxis) bottom_spine = mpltools.get_spine_visible(ax, 'bottom') top_spine = mpltools.get_spine_visible(ax, 'top') left_spine = mpltools.get_spine_visible(ax, 'left') right_spine = mpltools.get_spine_visible(ax, 'right') xaxis['mirror'] = mpltools.get_axis_mirror(bottom_spine, top_spine) yaxis['mirror'] = mpltools.get_axis_mirror(left_spine, right_spine) xaxis['showline'] = bottom_spine yaxis['showline'] = top_spine # put axes in our figure self.plotly_fig['layout']['xaxis{0}'.format(self.axis_ct)] = xaxis self.plotly_fig['layout']['yaxis{0}'.format(self.axis_ct)] = yaxis # let all subsequent dates be handled properly if required if xaxis.get('type') == 'date': self.x_is_mpl_date = True def close_axes(self, ax): """Close the axes object and clean up. Bars from bar charts are given to PlotlyRenderer one-by-one, thus they need to be taken care of at the close of each axes object. The self.current_bars variable should be empty unless a bar chart has been created. Positional arguments: ax -- an mpl axes object, not required at this time. """ self.draw_bars(self.current_bars) self.msg += " Closing axes\n" self.x_is_mpl_date = False def draw_bars(self, bars): # sort bars according to bar containers mpl_traces = [] for container in self.bar_containers: mpl_traces.append([bar_props for bar_props in self.current_bars if bar_props['mplobj'] in container]) for trace in mpl_traces: self.draw_bar(trace) def draw_bar(self, coll): """Draw a collection of similar patches as a bar chart. After bars are sorted, an appropriate data dictionary must be created to tell plotly about this data. Just like draw_line or draw_markers, draw_bar translates patch/path information into something plotly understands. Positional arguments: patch_coll -- a collection of patches to be drawn as a bar chart. """ tol = 1e-10 trace = [mpltools.make_bar(**bar_props) for bar_props in coll] widths = [bar_props['x1'] - bar_props['x0'] for bar_props in trace] heights = [bar_props['y1'] - bar_props['y0'] for bar_props in trace] vertical = abs( sum(widths[0] - widths[iii] for iii in range(len(widths))) ) < tol horizontal = abs( sum(heights[0] - heights[iii] for iii in range(len(heights))) ) < tol if vertical and horizontal: # Check for monotonic x. Can't both be true! x_zeros = [bar_props['x0'] for bar_props in trace] if all((x_zeros[iii + 1] > x_zeros[iii] for iii in range(len(x_zeros[:-1])))): orientation = 'v' else: orientation = 'h' elif vertical: orientation = 'v' else: orientation = 'h' if orientation == 'v': self.msg += " Attempting to draw a vertical bar chart\n" old_heights = [bar_props['y1'] for bar_props in trace] for bar in trace: bar['y0'], bar['y1'] = 0, bar['y1'] - bar['y0'] new_heights = [bar_props['y1'] for bar_props in trace] # check if we're stacked or not... for old, new in zip(old_heights, new_heights): if abs(old - new) > tol: self.plotly_fig['layout']['barmode'] = 'stack' self.plotly_fig['layout']['hovermode'] = 'x' x = [bar['x0'] + (bar['x1'] - bar['x0']) / 2 for bar in trace] y = [bar['y1'] for bar in trace] bar_gap = mpltools.get_bar_gap([bar['x0'] for bar in trace], [bar['x1'] for bar in trace]) if self.x_is_mpl_date: x = [bar['x0'] for bar in trace] formatter = (self.current_mpl_ax.get_xaxis() .get_major_formatter().__class__.__name__) x = mpltools.mpl_dates_to_datestrings(x, formatter) else: self.msg += " Attempting to draw a horizontal bar chart\n" old_rights = [bar_props['x1'] for bar_props in trace] for bar in trace: bar['x0'], bar['x1'] = 0, bar['x1'] - bar['x0'] new_rights = [bar_props['x1'] for bar_props in trace] # check if we're stacked or not... for old, new in zip(old_rights, new_rights): if abs(old - new) > tol: self.plotly_fig['layout']['barmode'] = 'stack' self.plotly_fig['layout']['hovermode'] = 'y' x = [bar['x1'] for bar in trace] y = [bar['y0'] + (bar['y1'] - bar['y0']) / 2 for bar in trace] bar_gap = mpltools.get_bar_gap([bar['y0'] for bar in trace], [bar['y1'] for bar in trace]) bar = go.Bar( orientation=orientation, x=x, y=y, xaxis='x{0}'.format(self.axis_ct), yaxis='y{0}'.format(self.axis_ct), opacity=trace[0]['alpha'], # TODO: get all alphas if array? marker=go.Marker( color=trace[0]['facecolor'], # TODO: get all line=go.Line(width=trace[0]['edgewidth']))) # TODO ditto if len(bar['x']) > 1: self.msg += " Heck yeah, I drew that bar chart\n" self.plotly_fig['data'] += bar, if bar_gap is not None: self.plotly_fig['layout']['bargap'] = bar_gap else: self.msg += " Bar chart not drawn\n" warnings.warn('found box chart data with length <= 1, ' 'assuming data redundancy, not plotting.') def draw_marked_line(self, **props): """Create a data dict for a line obj. This will draw 'lines', 'markers', or 'lines+markers'. props.keys() -- [ 'coordinates', ('data', 'axes', 'figure', or 'display') 'data', (a list of xy pairs) 'mplobj', (the matplotlib.lines.Line2D obj being rendered) 'label', (the name of the Line2D obj being rendered) 'linestyle', (linestyle dict, can be None, see below) 'markerstyle', (markerstyle dict, can be None, see below) ] props['linestyle'].keys() -- [ 'alpha', (opacity of Line2D obj) 'color', (color of the line if it exists, not the marker) 'linewidth', 'dasharray', (code for linestyle, see DASH_MAP in mpltools.py) 'zorder', (viewing precedence when stacked with other objects) ] props['markerstyle'].keys() -- [ 'alpha', (opacity of Line2D obj) 'marker', (the mpl marker symbol, see SYMBOL_MAP in mpltools.py) 'facecolor', (color of the marker face) 'edgecolor', (color of the marker edge) 'edgewidth', (width of marker edge) 'markerpath', (an SVG path for drawing the specified marker) 'zorder', (viewing precedence when stacked with other objects) ] """ self.msg += " Attempting to draw a line " line, marker = {}, {} if props['linestyle'] and props['markerstyle']: self.msg += "... with both lines+markers\n" mode = "lines+markers" elif props['linestyle']: self.msg += "... with just lines\n" mode = "lines" elif props['markerstyle']: self.msg += "... with just markers\n" mode = "markers" if props['linestyle']: color = \ mpltools.merge_color_and_opacity(props['linestyle']['color'], props['linestyle']['alpha']) line = go.Line( color=color, width=props['linestyle']['linewidth'], dash=mpltools.convert_dash(props['linestyle']['dasharray']) ) if props['markerstyle']: marker = go.Marker( opacity=props['markerstyle']['alpha'], color=props['markerstyle']['facecolor'], symbol=mpltools.convert_symbol(props['markerstyle']['marker']), size=props['markerstyle']['markersize'], line=go.Line( color=props['markerstyle']['edgecolor'], width=props['markerstyle']['edgewidth'] ) ) if props['coordinates'] == 'data': marked_line = go.Scatter( mode=mode, name=props['label'], x=[xy_pair[0] for xy_pair in props['data']], y=[xy_pair[1] for xy_pair in props['data']], xaxis='x{0}'.format(self.axis_ct), yaxis='y{0}'.format(self.axis_ct), line=line, marker=marker) if self.x_is_mpl_date: formatter = (self.current_mpl_ax.get_xaxis() .get_major_formatter().__class__.__name__) marked_line['x'] = mpltools.mpl_dates_to_datestrings( marked_line['x'], formatter ) self.plotly_fig['data'] += marked_line, self.msg += " Heck yeah, I drew that line\n" else: self.msg += " Line didn't have 'data' coordinates, " \ "not drawing\n" warnings.warn("Bummer! Plotly can currently only draw Line2D " "objects from matplotlib that are in 'data' " "coordinates!") def draw_image(self, **props): """Draw image. Not implemented yet! """ self.msg += " Attempting to draw image\n" self.msg += " Not drawing image\n" warnings.warn("Aw. Snap! You're gonna have to hold off on " "the selfies for now. Plotly can't import " "images from matplotlib yet!") def draw_path_collection(self, **props): """Add a path collection to data list as a scatter plot. Current implementation defaults such collections as scatter plots. Matplotlib supports collections that have many of the same parameters in common like color, size, path, etc. However, they needn't all be the same. Plotly does not currently support such functionality and therefore, the style for the first object is taken and used to define the remaining paths in the collection. props.keys() -- [ 'paths', (structure: [vertices, path_code]) 'path_coordinates', ('data', 'axes', 'figure', or 'display') 'path_transforms', (mpl transform, including Affine2D matrix) 'offsets', (offset from axes, helpful if in 'data') 'offset_coordinates', ('data', 'axes', 'figure', or 'display') 'offset_order', 'styles', (style dict, see below) 'mplobj' (the collection obj being drawn) ] props['styles'].keys() -- [ 'linewidth', (one or more linewidths) 'facecolor', (one or more facecolors for path) 'edgecolor', (one or more edgecolors for path) 'alpha', (one or more opacites for path) 'zorder', (precedence when stacked) ] """ self.msg += " Attempting to draw a path collection\n" if props['offset_coordinates'] is 'data': markerstyle = mpltools.get_markerstyle_from_collection(props) scatter_props = { 'coordinates': 'data', 'data': props['offsets'], 'label': None, 'markerstyle': markerstyle, 'linestyle': None } self.msg += " Drawing path collection as markers\n" self.draw_marked_line(**scatter_props) else: self.msg += " Path collection not linked to 'data', " \ "not drawing\n" warnings.warn("Dang! That path collection is out of this " "world. I totally don't know what to do with " "it yet! Plotly can only import path " "collections linked to 'data' coordinates") def draw_path(self, **props): """Draw path, currently only attempts to draw bar charts. This function attempts to sort a given path into a collection of horizontal or vertical bar charts. Most of the actual code takes place in functions from mpltools.py. props.keys() -- [ 'data', (a list of verticies for the path) 'coordinates', ('data', 'axes', 'figure', or 'display') 'pathcodes', (code for the path, structure: ['M', 'L', 'Z', etc.]) 'style', (style dict, see below) 'mplobj' (the mpl path object) ] props['style'].keys() -- [ 'alpha', (opacity of path obj) 'edgecolor', 'facecolor', 'edgewidth', 'dasharray', (style for path's enclosing line) 'zorder' (precedence of obj when stacked) ] """ self.msg += " Attempting to draw a path\n" is_bar = mpltools.is_bar(self.current_mpl_ax.containers, **props) if is_bar: self.current_bars += [props] else: self.msg += " This path isn't a bar, not drawing\n" warnings.warn("I found a path object that I don't think is part " "of a bar chart. Ignoring.") def draw_text(self, **props): """Create an annotation dict for a text obj. Currently, plotly uses either 'page' or 'data' to reference annotation locations. These refer to 'display' and 'data', respectively for the 'coordinates' key used in the Exporter. Appropriate measures are taken to transform text locations to reference one of these two options. props.keys() -- [ 'text', (actual content string, not the text obj) 'position', (an x, y pair, not an mpl Bbox) 'coordinates', ('data', 'axes', 'figure', 'display') 'text_type', ('title', 'xlabel', or 'ylabel') 'style', (style dict, see below) 'mplobj' (actual mpl text object) ] props['style'].keys() -- [ 'alpha', (opacity of text) 'fontsize', (size in points of text) 'color', (hex color) 'halign', (horizontal alignment, 'left', 'center', or 'right') 'valign', (vertical alignment, 'baseline', 'center', or 'top') 'rotation', 'zorder', (precedence of text when stacked with other objs) ] """ self.msg += " Attempting to draw an mpl text object\n" if not mpltools.check_corners(props['mplobj'], self.mpl_fig): warnings.warn( "Looks like the annotation(s) you are trying \n" "to draw lies/lay outside the given figure size.\n\n" "Therefore, the resulting Plotly figure may not be \n" "large enough to view the full text. To adjust \n" "the size of the figure, use the 'width' and \n" "'height' keys in the Layout object. Alternatively,\n" "use the Margin object to adjust the figure's margins.") align = props['mplobj']._multialignment if not align: align = props['style']['halign'] # mpl default if 'annotations' not in self.plotly_fig['layout']: self.plotly_fig['layout']['annotations'] = go.Annotations() if props['text_type'] == 'xlabel': self.msg += " Text object is an xlabel\n" self.draw_xlabel(**props) elif props['text_type'] == 'ylabel': self.msg += " Text object is a ylabel\n" self.draw_ylabel(**props) elif props['text_type'] == 'title': self.msg += " Text object is a title\n" self.draw_title(**props) else: # just a regular text annotation... self.msg += " Text object is a normal annotation\n" if props['coordinates'] is not 'data': self.msg += " Text object isn't linked to 'data' " \ "coordinates\n" x_px, y_px = props['mplobj'].get_transform().transform( props['position']) x, y = mpltools.display_to_paper( x_px, y_px, self.plotly_fig['layout'] ) xref = 'paper' yref = 'paper' xanchor = props['style']['halign'] # no difference here! yanchor = mpltools.convert_va(props['style']['valign']) else: self.msg += " Text object is linked to 'data' " \ "coordinates\n" x, y = props['position'] axis_ct = self.axis_ct xaxis = self.plotly_fig['layout']['xaxis{0}'.format(axis_ct)] yaxis = self.plotly_fig['layout']['yaxis{0}'.format(axis_ct)] if (xaxis['range'][0] < x < xaxis['range'][1] and yaxis['range'][0] < y < yaxis['range'][1]): xref = 'x{0}'.format(self.axis_ct) yref = 'y{0}'.format(self.axis_ct) else: self.msg += " Text object is outside " \ "plotting area, making 'paper' reference.\n" x_px, y_px = props['mplobj'].get_transform().transform( props['position']) x, y = mpltools.display_to_paper(x_px, y_px, self.plotly_fig['layout']) xref = 'paper' yref = 'paper' xanchor = props['style']['halign'] # no difference here! yanchor = mpltools.convert_va(props['style']['valign']) annotation = go.Annotation( text=props['text'], opacity=props['style']['alpha'], x=x, y=y, xref=xref, yref=yref, align=align, xanchor=xanchor, yanchor=yanchor, showarrow=False, # change this later? font=go.Font( color=props['style']['color'], size=props['style']['fontsize'] ) ) self.plotly_fig['layout']['annotations'] += annotation, self.msg += " Heck, yeah I drew that annotation\n" def draw_title(self, **props): """Add a title to the current subplot in layout dictionary. If there exists more than a single plot in the figure, titles revert to 'page'-referenced annotations. props.keys() -- [ 'text', (actual content string, not the text obj) 'position', (an x, y pair, not an mpl Bbox) 'coordinates', ('data', 'axes', 'figure', 'display') 'text_type', ('title', 'xlabel', or 'ylabel') 'style', (style dict, see below) 'mplobj' (actual mpl text object) ] props['style'].keys() -- [ 'alpha', (opacity of text) 'fontsize', (size in points of text) 'color', (hex color) 'halign', (horizontal alignment, 'left', 'center', or 'right') 'valign', (vertical alignment, 'baseline', 'center', or 'top') 'rotation', 'zorder', (precedence of text when stacked with other objs) ] """ self.msg += " Attempting to draw a title\n" if len(self.mpl_fig.axes) > 1: self.msg += " More than one subplot, adding title as " \ "annotation\n" x_px, y_px = props['mplobj'].get_transform().transform(props[ 'position']) x, y = mpltools.display_to_paper(x_px, y_px, self.plotly_fig['layout']) annotation = go.Annotation( text=props['text'], font=go.Font( color=props['style']['color'], size=props['style']['fontsize'] ), xref='paper', yref='paper', x=x, y=y, xanchor='center', yanchor='bottom', showarrow=False # no arrow for a title! ) self.plotly_fig['layout']['annotations'] += annotation, else: self.msg += " Only one subplot found, adding as a " \ "plotly title\n" self.plotly_fig['layout']['title'] = props['text'] titlefont = go.Font( size=props['style']['fontsize'], color=props['style']['color'] ) self.plotly_fig['layout']['titlefont'] = titlefont def draw_xlabel(self, **props): """Add an xaxis label to the current subplot in layout dictionary. props.keys() -- [ 'text', (actual content string, not the text obj) 'position', (an x, y pair, not an mpl Bbox) 'coordinates', ('data', 'axes', 'figure', 'display') 'text_type', ('title', 'xlabel', or 'ylabel') 'style', (style dict, see below) 'mplobj' (actual mpl text object) ] props['style'].keys() -- [ 'alpha', (opacity of text) 'fontsize', (size in points of text) 'color', (hex color) 'halign', (horizontal alignment, 'left', 'center', or 'right') 'valign', (vertical alignment, 'baseline', 'center', or 'top') 'rotation', 'zorder', (precedence of text when stacked with other objs) ] """ self.msg += " Adding xlabel\n" axis_key = 'xaxis{0}'.format(self.axis_ct) self.plotly_fig['layout'][axis_key]['title'] = props['text'] titlefont = go.Font( size=props['style']['fontsize'], color=props['style']['color']) self.plotly_fig['layout'][axis_key]['titlefont'] = titlefont def draw_ylabel(self, **props): """Add a yaxis label to the current subplot in layout dictionary. props.keys() -- [ 'text', (actual content string, not the text obj) 'position', (an x, y pair, not an mpl Bbox) 'coordinates', ('data', 'axes', 'figure', 'display') 'text_type', ('title', 'xlabel', or 'ylabel') 'style', (style dict, see below) 'mplobj' (actual mpl text object) ] props['style'].keys() -- [ 'alpha', (opacity of text) 'fontsize', (size in points of text) 'color', (hex color) 'halign', (horizontal alignment, 'left', 'center', or 'right') 'valign', (vertical alignment, 'baseline', 'center', or 'top') 'rotation', 'zorder', (precedence of text when stacked with other objs) ] """ self.msg += " Adding ylabel\n" axis_key = 'yaxis{0}'.format(self.axis_ct) self.plotly_fig['layout'][axis_key]['title'] = props['text'] titlefont = go.Font( size=props['style']['fontsize'], color=props['style']['color']) self.plotly_fig['layout'][axis_key]['titlefont'] = titlefont def resize(self): """Revert figure layout to allow plotly to resize. By default, PlotlyRenderer tries its hardest to precisely mimic an mpl figure. However, plotly is pretty good with aesthetics. By running PlotlyRenderer.resize(), layout parameters are deleted. This lets plotly choose them instead of mpl. """ self.msg += "Resizing figure, deleting keys from layout\n" for key in ['width', 'height', 'autosize', 'margin']: try: del self.plotly_fig['layout'][key] except KeyError: pass def strip_style(self): self.msg += "Stripping mpl style, deleting keys from data and layout\n" self.plotly_fig.strip_style() plotly-1.9.5+dfsg.orig/plotly/matplotlylib/__init__.py0000644000175000017500000000064012645550357022443 0ustar noahfxnoahfx""" matplotlylib ============ This module converts matplotlib figure objects into JSON structures which can be understood and visualized by Plotly. Most of the functionality should be accessed through the parent directory's 'tools' module or 'plotly' package. """ from __future__ import absolute_import from plotly.matplotlylib.renderer import PlotlyRenderer from plotly.matplotlylib.mplexporter import Exporter plotly-1.9.5+dfsg.orig/plotly/matplotlylib/mpltools.py0000644000175000017500000004616012645550357022564 0ustar noahfxnoahfx""" Tools A module for converting from mpl language to plotly language. """ import math import warnings import matplotlib.dates import pytz def check_bar_match(old_bar, new_bar): """Check if two bars belong in the same collection (bar chart). Positional arguments: old_bar -- a previously sorted bar dictionary. new_bar -- a new bar dictionary that needs to be sorted. """ tests = [] tests += new_bar['orientation'] == old_bar['orientation'], tests += new_bar['facecolor'] == old_bar['facecolor'], if new_bar['orientation'] == 'v': new_width = new_bar['x1'] - new_bar['x0'] old_width = old_bar['x1'] - old_bar['x0'] tests += new_width - old_width < 0.000001, tests += new_bar['y0'] == old_bar['y0'], elif new_bar['orientation'] == 'h': new_height = new_bar['y1'] - new_bar['y0'] old_height = old_bar['y1'] - old_bar['y0'] tests += new_height - old_height < 0.000001, tests += new_bar['x0'] == old_bar['x0'], if all(tests): return True else: return False def check_corners(inner_obj, outer_obj): inner_corners = inner_obj.get_window_extent().corners() outer_corners = outer_obj.get_window_extent().corners() if inner_corners[0][0] < outer_corners[0][0]: return False elif inner_corners[0][1] < outer_corners[0][1]: return False elif inner_corners[3][0] > outer_corners[3][0]: return False elif inner_corners[3][1] > outer_corners[3][1]: return False else: return True def convert_dash(mpl_dash): """Convert mpl line symbol to plotly line symbol and return symbol.""" if mpl_dash in DASH_MAP: return DASH_MAP[mpl_dash] else: return 'solid' # default def convert_path(path): verts = path[0] # may use this later code = tuple(path[1]) if code in PATH_MAP: return PATH_MAP[code] else: return None def convert_symbol(mpl_symbol): """Convert mpl marker symbol to plotly symbol and return symbol.""" if isinstance(mpl_symbol, list): symbol = list() for s in mpl_symbol: symbol += [convert_symbol(s)] return symbol elif mpl_symbol in SYMBOL_MAP: return SYMBOL_MAP[mpl_symbol] else: return 'dot' # default def hex_to_rgb(value): """ Change a hex color to an rgb tuple :param (str|unicode) value: The hex string we want to convert. :return: (int, int, int) The red, green, blue int-tuple. Example: '#FFFFFF' --> (255, 255, 255) """ value = value.lstrip('#') lv = len(value) return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3)) def merge_color_and_opacity(color, opacity): """ Merge hex color with an alpha (opacity) to get an rgba tuple. :param (str|unicode) color: A hex color string. :param (float|int) opacity: A value [0, 1] for the 'a' in 'rgba'. :return: (int, int, int, float) The rgba color and alpha tuple. """ if color is None: # None can be used as a placeholder, just bail. return None rgb_tup = hex_to_rgb(color) if opacity is None: return 'rgb {}'.format(rgb_tup) rgba_tup = rgb_tup + (opacity,) return 'rgba {}'.format(rgba_tup) def convert_va(mpl_va): """Convert mpl vertical alignment word to equivalent HTML word. Text alignment specifiers from mpl differ very slightly from those used in HTML. See the VA_MAP for more details. Positional arguments: mpl_va -- vertical mpl text alignment spec. """ if mpl_va in VA_MAP: return VA_MAP[mpl_va] else: return None # let plotly figure it out! def convert_x_domain(mpl_plot_bounds, mpl_max_x_bounds): """Map x dimension of current plot to plotly's domain space. The bbox used to locate an axes object in mpl differs from the method used to locate axes in plotly. The mpl version locates each axes in the figure so that axes in a single-plot figure might have the bounds, [0.125, 0.125, 0.775, 0.775] (x0, y0, width, height), in mpl's figure coordinates. However, the axes all share one space in plotly such that the domain will always be [0, 0, 1, 1] (x0, y0, x1, y1). To convert between the two, the mpl figure bounds need to be mapped to a [0, 1] domain for x and y. The margins set upon opening a new figure will appropriately match the mpl margins. Optionally, setting margins=0 and simply copying the domains from mpl to plotly would place axes appropriately. However, this would throw off axis and title labeling. Positional arguments: mpl_plot_bounds -- the (x0, y0, width, height) params for current ax ** mpl_max_x_bounds -- overall (x0, x1) bounds for all axes ** ** these are all specified in mpl figure coordinates """ mpl_x_dom = [mpl_plot_bounds[0], mpl_plot_bounds[0]+mpl_plot_bounds[2]] plotting_width = (mpl_max_x_bounds[1]-mpl_max_x_bounds[0]) x0 = (mpl_x_dom[0]-mpl_max_x_bounds[0])/plotting_width x1 = (mpl_x_dom[1]-mpl_max_x_bounds[0])/plotting_width return [x0, x1] def convert_y_domain(mpl_plot_bounds, mpl_max_y_bounds): """Map y dimension of current plot to plotly's domain space. The bbox used to locate an axes object in mpl differs from the method used to locate axes in plotly. The mpl version locates each axes in the figure so that axes in a single-plot figure might have the bounds, [0.125, 0.125, 0.775, 0.775] (x0, y0, width, height), in mpl's figure coordinates. However, the axes all share one space in plotly such that the domain will always be [0, 0, 1, 1] (x0, y0, x1, y1). To convert between the two, the mpl figure bounds need to be mapped to a [0, 1] domain for x and y. The margins set upon opening a new figure will appropriately match the mpl margins. Optionally, setting margins=0 and simply copying the domains from mpl to plotly would place axes appropriately. However, this would throw off axis and title labeling. Positional arguments: mpl_plot_bounds -- the (x0, y0, width, height) params for current ax ** mpl_max_y_bounds -- overall (y0, y1) bounds for all axes ** ** these are all specified in mpl figure coordinates """ mpl_y_dom = [mpl_plot_bounds[1], mpl_plot_bounds[1]+mpl_plot_bounds[3]] plotting_height = (mpl_max_y_bounds[1]-mpl_max_y_bounds[0]) y0 = (mpl_y_dom[0]-mpl_max_y_bounds[0])/plotting_height y1 = (mpl_y_dom[1]-mpl_max_y_bounds[0])/plotting_height return [y0, y1] def display_to_paper(x, y, layout): """Convert mpl display coordinates to plotly paper coordinates. Plotly references object positions with an (x, y) coordinate pair in either 'data' or 'paper' coordinates which reference actual data in a plot or the entire plotly axes space where the bottom-left of the bottom-left plot has the location (x, y) = (0, 0) and the top-right of the top-right plot has the location (x, y) = (1, 1). Display coordinates in mpl reference objects with an (x, y) pair in pixel coordinates, where the bottom-left corner is at the location (x, y) = (0, 0) and the top-right corner is at the location (x, y) = (figwidth*dpi, figheight*dpi). Here, figwidth and figheight are in inches and dpi are the dots per inch resolution. """ num_x = x - layout['margin']['l'] den_x = layout['width'] - (layout['margin']['l'] + layout['margin']['r']) num_y = y - layout['margin']['b'] den_y = layout['height'] - (layout['margin']['b'] + layout['margin']['t']) return num_x/den_x, num_y/den_y def get_axes_bounds(fig): """Return the entire axes space for figure. An axes object in mpl is specified by its relation to the figure where (0,0) corresponds to the bottom-left part of the figure and (1,1) corresponds to the top-right. Margins exist in matplotlib because axes objects normally don't go to the edges of the figure. In plotly, the axes area (where all subplots go) is always specified with the domain [0,1] for both x and y. This function finds the smallest box, specified by two points, that all of the mpl axes objects fit into. This box is then used to map mpl axes domains to plotly axes domains. """ x_min, x_max, y_min, y_max = [], [], [], [] for axes_obj in fig.get_axes(): bounds = axes_obj.get_position().bounds x_min.append(bounds[0]) x_max.append(bounds[0]+bounds[2]) y_min.append(bounds[1]) y_max.append(bounds[1]+bounds[3]) x_min, y_min, x_max, y_max = min(x_min), min(y_min), max(x_max), max(y_max) return (x_min, x_max), (y_min, y_max) def get_axis_mirror(main_spine, mirror_spine): if main_spine and mirror_spine: return 'ticks' elif main_spine and not mirror_spine: return False elif not main_spine and mirror_spine: return False # can't handle this case yet! else: return False # nuttin'! def get_bar_gap(bar_starts, bar_ends, tol=1e-10): if len(bar_starts) == len(bar_ends) and len(bar_starts) > 1: sides1 = bar_starts[1:] sides2 = bar_ends[:-1] gaps = [s2-s1 for s2, s1 in zip(sides1, sides2)] gap0 = gaps[0] uniform = all([abs(gap0-gap) < tol for gap in gaps]) if uniform: return gap0 def convert_rgba_array(color_list): clean_color_list = list() for c in color_list: clean_color_list += [(dict(r=int(c[0]*255), g=int(c[1]*255), b=int(c[2]*255), a=c[3] ))] plotly_colors = list() for rgba in clean_color_list: plotly_colors += ["rgba({r},{g},{b},{a})".format(**rgba)] if len(plotly_colors) == 1: return plotly_colors[0] else: return plotly_colors def convert_path_array(path_array): symbols = list() for path in path_array: symbols += [convert_path(path)] if len(symbols) == 1: return symbols[0] else: return symbols def convert_linewidth_array(width_array): if len(width_array) == 1: return width_array[0] else: return width_array def convert_size_array(size_array): size = [math.sqrt(s) for s in size_array] if len(size) == 1: return size[0] else: return size def get_markerstyle_from_collection(props): markerstyle=dict( alpha=None, facecolor=convert_rgba_array(props['styles']['facecolor']), marker=convert_path_array(props['paths']), edgewidth=convert_linewidth_array(props['styles']['linewidth']), # markersize=convert_size_array(props['styles']['size']), # TODO! markersize=convert_size_array(props['mplobj'].get_sizes()), edgecolor=convert_rgba_array(props['styles']['edgecolor']) ) return markerstyle def get_rect_xmin(data): """Find minimum x value from four (x,y) vertices.""" return min(data[0][0], data[1][0], data[2][0], data[3][0]) def get_rect_xmax(data): """Find maximum x value from four (x,y) vertices.""" return max(data[0][0], data[1][0], data[2][0], data[3][0]) def get_rect_ymin(data): """Find minimum y value from four (x,y) vertices.""" return min(data[0][1], data[1][1], data[2][1], data[3][1]) def get_rect_ymax(data): """Find maximum y value from four (x,y) vertices.""" return max(data[0][1], data[1][1], data[2][1], data[3][1]) def get_spine_visible(ax, spine_key): """Return some spine parameters for the spine, `spine_key`.""" spine = ax.spines[spine_key] ax_frame_on = ax.get_frame_on() spine_frame_like = spine.is_frame_like() if not spine.get_visible(): return False elif not spine._edgecolor[-1]: # user's may have set edgecolor alpha==0 return False elif not ax_frame_on and spine_frame_like: return False elif ax_frame_on and spine_frame_like: return True elif not ax_frame_on and not spine_frame_like: return True # we've already checked for that it's visible. else: return False # oh man, and i thought we exhausted the options... def is_bar(bar_containers, **props): """A test to decide whether a path is a bar from a vertical bar chart.""" # is this patch in a bar container? for container in bar_containers: if props['mplobj'] in container: return True return False def make_bar(**props): """Make an intermediate bar dictionary. This creates a bar dictionary which aids in the comparison of new bars to old bars from other bar chart (patch) collections. This is not the dictionary that needs to get passed to plotly as a data dictionary. That happens in PlotlyRenderer in that class's draw_bar method. In other words, this dictionary describes a SINGLE bar, whereas, plotly will require a set of bars to be passed in a data dictionary. """ return { 'bar': props['mplobj'], 'x0': get_rect_xmin(props['data']), 'y0': get_rect_ymin(props['data']), 'x1': get_rect_xmax(props['data']), 'y1': get_rect_ymax(props['data']), 'alpha': props['style']['alpha'], 'edgecolor': props['style']['edgecolor'], 'facecolor': props['style']['facecolor'], 'edgewidth': props['style']['edgewidth'], 'dasharray': props['style']['dasharray'], 'zorder': props['style']['zorder'] } def prep_ticks(ax, index, ax_type, props): """Prepare axis obj belonging to axes obj. positional arguments: ax - the mpl axes instance index - the index of the axis in `props` ax_type - 'x' or 'y' (for now) props - an mplexporter poperties dictionary """ axis_dict = dict() if ax_type == 'x': axis = ax.get_xaxis() elif ax_type == 'y': axis = ax.get_yaxis() else: return dict() # whoops! scale = props['axes'][index]['scale'] if scale == 'linear': # get tick location information try: tickvalues = props['axes'][index]['tickvalues'] tick0 = tickvalues[0] dticks = [round(tickvalues[i]-tickvalues[i-1], 12) for i in range(1, len(tickvalues) - 1)] if all([dticks[i] == dticks[i-1] for i in range(1, len(dticks) - 1)]): dtick = tickvalues[1] - tickvalues[0] else: warnings.warn("'linear' {0}-axis tick spacing not even, " "ignoring mpl tick formatting.".format(ax_type)) raise TypeError except (IndexError, TypeError): axis_dict['nticks'] = props['axes'][index]['nticks'] else: axis_dict['tick0'] = tick0 axis_dict['dtick'] = dtick axis_dict['tickmode'] = False elif scale == 'log': try: axis_dict['tick0'] = props['axes'][index]['tickvalues'][0] axis_dict['dtick'] = props['axes'][index]['tickvalues'][1] - \ props['axes'][index]['tickvalues'][0] axis_dict['tickmode'] = False except (IndexError, TypeError): axis_dict = dict(nticks=props['axes'][index]['nticks']) base = axis.get_transform().base if base == 10: if ax_type == 'x': axis_dict['range'] = [math.log10(props['xlim'][0]), math.log10(props['xlim'][1])] elif ax_type == 'y': axis_dict['range'] = [math.log10(props['ylim'][0]), math.log10(props['ylim'][1])] else: axis_dict = dict(range=None, type='linear') warnings.warn("Converted non-base10 {0}-axis log scale to 'linear'" "".format(ax_type)) else: return dict() # get tick label formatting information formatter = axis.get_major_formatter().__class__.__name__ if ax_type == 'x' and 'DateFormatter' in formatter: axis_dict['type'] = 'date' try: axis_dict['tick0'] = mpl_dates_to_datestrings( axis_dict['tick0'], formatter ) except KeyError: pass finally: axis_dict.pop('dtick', None) axis_dict.pop('tickmode', None) axis_dict['range'] = mpl_dates_to_datestrings( props['xlim'], formatter ) if formatter == 'LogFormatterMathtext': axis_dict['exponentformat'] = 'e' return axis_dict def prep_xy_axis(ax, props, x_bounds, y_bounds): xaxis = dict( type=props['axes'][0]['scale'], range=list(props['xlim']), showgrid=props['axes'][0]['grid']['gridOn'], domain=convert_x_domain(props['bounds'], x_bounds), side=props['axes'][0]['position'], tickfont=dict(size=props['axes'][0]['fontsize']) ) xaxis.update(prep_ticks(ax, 0, 'x', props)) yaxis = dict( type=props['axes'][1]['scale'], range=list(props['ylim']), showgrid=props['axes'][1]['grid']['gridOn'], domain=convert_y_domain(props['bounds'], y_bounds), side=props['axes'][1]['position'], tickfont=dict(size=props['axes'][1]['fontsize']) ) yaxis.update(prep_ticks(ax, 1, 'y', props)) return xaxis, yaxis def mpl_dates_to_datestrings(dates, mpl_formatter): """Convert matplotlib dates to iso-formatted-like time strings. Plotly's accepted format: "YYYY-MM-DD HH:MM:SS" (e.g., 2001-01-01 00:00:00) Info on mpl dates: http://matplotlib.org/api/dates_api.html """ _dates = dates # this is a pandas datetime formatter, times show up in floating point days # since the epoch (1970-01-01T00:00:00+00:00) if mpl_formatter == "TimeSeries_DateFormatter": try: dates = matplotlib.dates.epoch2num( [date*24*60*60 for date in dates] ) dates = matplotlib.dates.num2date(dates, tz=pytz.utc) except: return _dates # the rest of mpl dates are in floating point days since # (0001-01-01T00:00:00+00:00) + 1. I.e., (0001-01-01T00:00:00+00:00) == 1.0 # according to mpl --> try num2date(1) else: try: dates = matplotlib.dates.num2date(dates, tz=pytz.utc) except: return _dates time_stings = [' '.join(date.isoformat().split('+')[0].split('T')) for date in dates] return time_stings DASH_MAP = { '10,0': 'solid', '6,6': 'dash', '2,2': 'dot', '4,4,2,4': 'dashdot', 'none': 'solid' } PATH_MAP = { ('M', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'Z'): 'o', ('M', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'Z'): '*', ('M', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'Z'): '8', ('M', 'L', 'L', 'L', 'L', 'L', 'Z'): 'h', ('M', 'L', 'L', 'L', 'L', 'Z'): 'p', ('M', 'L', 'M', 'L', 'M', 'L'): '1', ('M', 'L', 'L', 'L', 'Z'): 's', ('M', 'L', 'M', 'L'): '+', ('M', 'L', 'L', 'Z'): '^', ('M', 'L'): '|' } SYMBOL_MAP = { 'o': 'dot', 'v': 'triangle-down', '^': 'triangle-up', '<': 'triangle-left', '>': 'triangle-right', 's': 'square', '+': 'cross', 'x': 'x', '*': 'x', # no star yet in plotly!! 'D': 'diamond', 'd': 'diamond', } VA_MAP = { 'center': 'middle', 'baseline': 'bottom', 'top': 'top' } plotly-1.9.5+dfsg.orig/plotly/version.py0000644000175000017500000000002612647020762017645 0ustar noahfxnoahfx__version__ = '1.9.5' plotly-1.9.5+dfsg.orig/plotly/tools.py0000644000175000017500000045063612645550357017346 0ustar noahfxnoahfx# -*- coding: utf-8 -*- """ tools ===== Functions that USERS will possibly want access to. """ from __future__ import absolute_import from collections import OrderedDict import warnings import six import math from plotly import utils from plotly import exceptions from plotly import graph_reference from plotly import session from plotly.files import (CONFIG_FILE, CREDENTIALS_FILE, FILE_CONTENT, GRAPH_REFERENCE_FILE, check_file_permissions) # Warning format def warning_on_one_line(message, category, filename, lineno, file=None, line=None): return '%s:%s: %s:\n\n%s\n\n' % (filename, lineno, category.__name__, message) warnings.formatwarning = warning_on_one_line try: from . import matplotlylib _matplotlylib_imported = True except ImportError: _matplotlylib_imported = False try: import IPython import IPython.core.display _ipython_imported = True except ImportError: _ipython_imported = False try: import numpy as np _numpy_imported = True except ImportError: _numpy_imported = False try: import pandas as pd _pandas_imported = True except ImportError: _pandas_imported = False try: import scipy as scp _scipy_imported = True except ImportError: _scipy_imported = False try: import scipy.spatial as scs _scipy__spatial_imported = True except ImportError: _scipy__spatial_imported = False try: import scipy.cluster.hierarchy as sch _scipy__cluster__hierarchy_imported = True except ImportError: _scipy__cluster__hierarchy_imported = False try: import scipy import scipy.stats _scipy_imported = True except ImportError: _scipy_imported = False def get_config_defaults(): """ Convenience function to check current settings against defaults. Example: if plotly_domain != get_config_defaults()['plotly_domain']: # do something """ return dict(FILE_CONTENT[CONFIG_FILE]) # performs a shallow copy def ensure_local_plotly_files(): """Ensure that filesystem is setup/filled out in a valid way. If the config or credential files aren't filled out, then write them to the disk. """ if check_file_permissions(): for fn in [CREDENTIALS_FILE, CONFIG_FILE]: utils.ensure_file_exists(fn) contents = utils.load_json_dict(fn) for key, val in list(FILE_CONTENT[fn].items()): # TODO: removed type checking below, may want to revisit if key not in contents: contents[key] = val contents_keys = list(contents.keys()) for key in contents_keys: if key not in FILE_CONTENT[fn]: del contents[key] utils.save_json_dict(fn, contents) # make a request to get graph reference if DNE. utils.ensure_file_exists(GRAPH_REFERENCE_FILE) utils.save_json_dict(GRAPH_REFERENCE_FILE, graph_reference.GRAPH_REFERENCE) else: warnings.warn("Looks like you don't have 'read-write' permission to " "your 'home' ('~') directory or to our '~/.plotly' " "directory. That means plotly's python api can't setup " "local configuration files. No problem though! You'll " "just have to sign-in using 'plotly.plotly.sign_in()'. " "For help with that: 'help(plotly.plotly.sign_in)'." "\nQuestions? support@plot.ly") ### credentials tools ### def set_credentials_file(username=None, api_key=None, stream_ids=None, proxy_username=None, proxy_password=None): """Set the keyword-value pairs in `~/.plotly_credentials`. :param (str) username: The username you'd use to sign in to Plotly :param (str) api_key: The api key associated with above username :param (list) stream_ids: Stream tokens for above credentials :param (str) proxy_username: The un associated with with your Proxy :param (str) proxy_password: The pw associated with your Proxy un """ if not check_file_permissions(): raise exceptions.PlotlyError("You don't have proper file permissions " "to run this function.") ensure_local_plotly_files() # make sure what's there is OK credentials = get_credentials_file() if isinstance(username, six.string_types): credentials['username'] = username if isinstance(api_key, six.string_types): credentials['api_key'] = api_key if isinstance(proxy_username, six.string_types): credentials['proxy_username'] = proxy_username if isinstance(proxy_password, six.string_types): credentials['proxy_password'] = proxy_password if isinstance(stream_ids, (list, tuple)): credentials['stream_ids'] = stream_ids utils.save_json_dict(CREDENTIALS_FILE, credentials) ensure_local_plotly_files() # make sure what we just put there is OK def get_credentials_file(*args): """Return specified args from `~/.plotly_credentials`. as dict. Returns all if no arguments are specified. Example: get_credentials_file('username') """ if check_file_permissions(): ensure_local_plotly_files() # make sure what's there is OK return utils.load_json_dict(CREDENTIALS_FILE, *args) else: return FILE_CONTENT[CREDENTIALS_FILE] def reset_credentials_file(): ensure_local_plotly_files() # make sure what's there is OK utils.save_json_dict(CREDENTIALS_FILE, {}) ensure_local_plotly_files() # put the defaults back ### config tools ### def set_config_file(plotly_domain=None, plotly_streaming_domain=None, plotly_api_domain=None, plotly_ssl_verification=None, plotly_proxy_authorization=None, world_readable=None, sharing=None, auto_open=None): """Set the keyword-value pairs in `~/.plotly/.config`. :param (str) plotly_domain: ex - https://plot.ly :param (str) plotly_streaming_domain: ex - stream.plot.ly :param (str) plotly_api_domain: ex - https://api.plot.ly :param (bool) plotly_ssl_verification: True = verify, False = don't verify :param (bool) plotly_proxy_authorization: True = use plotly proxy auth creds :param (bool) world_readable: True = public, False = private """ if not check_file_permissions(): raise exceptions.PlotlyError("You don't have proper file permissions " "to run this function.") ensure_local_plotly_files() # make sure what's there is OK utils.validate_world_readable_and_sharing_settings({ 'sharing': sharing, 'world_readable': world_readable}) settings = get_config_file() if isinstance(plotly_domain, six.string_types): settings['plotly_domain'] = plotly_domain elif plotly_domain is not None: raise TypeError('plotly_domain should be a string') if isinstance(plotly_streaming_domain, six.string_types): settings['plotly_streaming_domain'] = plotly_streaming_domain elif plotly_streaming_domain is not None: raise TypeError('plotly_streaming_domain should be a string') if isinstance(plotly_api_domain, six.string_types): settings['plotly_api_domain'] = plotly_api_domain elif plotly_api_domain is not None: raise TypeError('plotly_api_domain should be a string') if isinstance(plotly_ssl_verification, (six.string_types, bool)): settings['plotly_ssl_verification'] = plotly_ssl_verification elif plotly_ssl_verification is not None: raise TypeError('plotly_ssl_verification should be a boolean') if isinstance(plotly_proxy_authorization, (six.string_types, bool)): settings['plotly_proxy_authorization'] = plotly_proxy_authorization elif plotly_proxy_authorization is not None: raise TypeError('plotly_proxy_authorization should be a boolean') if isinstance(auto_open, bool): settings['auto_open'] = auto_open elif auto_open is not None: raise TypeError('auto_open should be a boolean') if isinstance(world_readable, bool): settings['world_readable'] = world_readable settings.pop('sharing') elif world_readable is not None: raise TypeError('Input should be a boolean') if isinstance(sharing, six.string_types): settings['sharing'] = sharing elif sharing is not None: raise TypeError('sharing should be a string') utils.set_sharing_and_world_readable(settings) utils.save_json_dict(CONFIG_FILE, settings) ensure_local_plotly_files() # make sure what we just put there is OK def get_config_file(*args): """Return specified args from `~/.plotly/.config`. as tuple. Returns all if no arguments are specified. Example: get_config_file('plotly_domain') """ if check_file_permissions(): ensure_local_plotly_files() # make sure what's there is OK return utils.load_json_dict(CONFIG_FILE, *args) else: return FILE_CONTENT[CONFIG_FILE] def reset_config_file(): ensure_local_plotly_files() # make sure what's there is OK f = open(CONFIG_FILE, 'w') f.close() ensure_local_plotly_files() # put the defaults back ### embed tools ### def get_embed(file_owner_or_url, file_id=None, width="100%", height=525): """Returns HTML code to embed figure on a webpage as an ").format( plotly_rest_url=plotly_rest_url, file_owner=file_owner, file_id=file_id, iframe_height=height, iframe_width=width) else: s = ("").format( plotly_rest_url=plotly_rest_url, file_owner=file_owner, file_id=file_id, share_key=share_key, iframe_height=height, iframe_width=width) return s def embed(file_owner_or_url, file_id=None, width="100%", height=525): """Embeds existing Plotly figure in IPython Notebook Plotly uniquely identifies figures with a 'file_owner'/'file_id' pair. Since each file is given a corresponding unique url, you may also simply pass a valid plotly url as the first argument. Note, if you're using a file_owner string as the first argument, you MUST specify a `file_id` keyword argument. Else, if you're using a url string as the first argument, you MUST NOT specify a `file_id` keyword argument, or file_id must be set to Python's None value. Positional arguments: file_owner_or_url (string) -- a valid plotly username OR a valid plotly url Keyword arguments: file_id (default=None) -- an int or string that can be converted to int if you're using a url, don't fill this in! width (default="100%") -- an int or string corresp. to width of the figure height (default="525") -- same as width but corresp. to the height of the figure """ try: s = get_embed(file_owner_or_url, file_id=file_id, width=width, height=height) # see if we are in the SageMath Cloud from sage_salvus import html return html(s, hide=False) except: pass if _ipython_imported: if file_id: plotly_domain = ( session.get_session_config().get('plotly_domain') or get_config_file()['plotly_domain'] ) url = "{plotly_domain}/~{un}/{fid}".format( plotly_domain=plotly_domain, un=file_owner_or_url, fid=file_id) else: url = file_owner_or_url return PlotlyDisplay(url, width, height) else: if (get_config_defaults()['plotly_domain'] != session.get_session_config()['plotly_domain']): feedback_email = 'feedback@plot.ly' else: # different domain likely means enterprise feedback_email = 'support@plot.ly' warnings.warn( "Looks like you're not using IPython or Sage to embed this " "plot. If you just want the *embed code*,\ntry using " "`get_embed()` instead." '\nQuestions? {}'.format(feedback_email)) ### mpl-related tools ### @utils.template_doc(**get_config_file()) def mpl_to_plotly(fig, resize=False, strip_style=False, verbose=False): """Convert a matplotlib figure to plotly dictionary and send. All available information about matplotlib visualizations are stored within a matplotlib.figure.Figure object. You can create a plot in python using matplotlib, store the figure object, and then pass this object to the fig_to_plotly function. In the background, mplexporter is used to crawl through the mpl figure object for appropriate information. This information is then systematically sent to the PlotlyRenderer which creates the JSON structure used to make plotly visualizations. Finally, these dictionaries are sent to plotly and your browser should open up a new tab for viewing! Optionally, if you're working in IPython, you can set notebook=True and the PlotlyRenderer will call plotly.iplot instead of plotly.plot to have the graph appear directly in the IPython notebook. Note, this function gives the user access to a simple, one-line way to render an mpl figure in plotly. If you need to trouble shoot, you can do this step manually by NOT running this fuction and entereing the following: =========================================================================== from mplexporter import Exporter from mplexporter.renderers import PlotlyRenderer # create an mpl figure and store it under a varialble 'fig' renderer = PlotlyRenderer() exporter = Exporter(renderer) exporter.run(fig) =========================================================================== You can then inspect the JSON structures by accessing these: renderer.layout -- a plotly layout dictionary renderer.data -- a list of plotly data dictionaries Positional arguments: fig -- a matplotlib figure object username -- a valid plotly username ** api_key -- a valid api_key for the above username ** notebook -- an option for use with an IPython notebook ** Don't have a username/api_key? Try looking here: {plotly_domain}/plot ** Forgot your api_key? Try signing in and looking here: {plotly_domain}/python/getting-started """ if _matplotlylib_imported: renderer = matplotlylib.PlotlyRenderer() matplotlylib.Exporter(renderer).run(fig) if resize: renderer.resize() if strip_style: renderer.strip_style() if verbose: print(renderer.msg) return renderer.plotly_fig else: warnings.warn( "To use Plotly's matplotlylib functionality, you'll need to have " "matplotlib successfully installed with all of its dependencies. " "You're getting this error because matplotlib or one of its " "dependencies doesn't seem to be installed correctly.") ### graph_objs related tools ### def get_subplots(rows=1, columns=1, print_grid=False, **kwargs): """Return a dictionary instance with the subplots set in 'layout'. Example 1: # stack two subplots vertically fig = tools.get_subplots(rows=2) fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x1', yaxis='y1')] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x2', yaxis='y2')] Example 2: # print out string showing the subplot grid you've put in the layout fig = tools.get_subplots(rows=3, columns=2, print_grid=True) Keywords arguments with constant defaults: rows (kwarg, int greater than 0, default=1): Number of rows, evenly spaced vertically on the figure. columns (kwarg, int greater than 0, default=1): Number of columns, evenly spaced horizontally on the figure. horizontal_spacing (kwarg, float in [0,1], default=0.1): Space between subplot columns. Applied to all columns. vertical_spacing (kwarg, float in [0,1], default=0.05): Space between subplot rows. Applied to all rows. print_grid (kwarg, True | False, default=False): If True, prints a tab-delimited string representation of your plot grid. Keyword arguments with variable defaults: horizontal_spacing (kwarg, float in [0,1], default=0.2 / columns): Space between subplot columns. vertical_spacing (kwarg, float in [0,1], default=0.3 / rows): Space between subplot rows. """ # TODO: protected until #282 from plotly.graph_objs import graph_objs warnings.warn( "tools.get_subplots is depreciated. " "Please use tools.make_subplots instead." ) # Throw exception for non-integer rows and columns if not isinstance(rows, int) or rows <= 0: raise Exception("Keyword argument 'rows' " "must be an int greater than 0") if not isinstance(columns, int) or columns <= 0: raise Exception("Keyword argument 'columns' " "must be an int greater than 0") # Throw exception if non-valid kwarg is sent VALID_KWARGS = ['horizontal_spacing', 'vertical_spacing'] for key in kwargs.keys(): if key not in VALID_KWARGS: raise Exception("Invalid keyword argument: '{0}'".format(key)) # Set 'horizontal_spacing' / 'vertical_spacing' w.r.t. rows / columns try: horizontal_spacing = float(kwargs['horizontal_spacing']) except KeyError: horizontal_spacing = 0.2 / columns try: vertical_spacing = float(kwargs['vertical_spacing']) except KeyError: vertical_spacing = 0.3 / rows fig = dict(layout=graph_objs.Layout()) # will return this at the end plot_width = (1 - horizontal_spacing * (columns - 1)) / columns plot_height = (1 - vertical_spacing * (rows - 1)) / rows plot_num = 0 for rrr in range(rows): for ccc in range(columns): xaxis_name = 'xaxis{0}'.format(plot_num + 1) x_anchor = 'y{0}'.format(plot_num + 1) x_start = (plot_width + horizontal_spacing) * ccc x_end = x_start + plot_width yaxis_name = 'yaxis{0}'.format(plot_num + 1) y_anchor = 'x{0}'.format(plot_num + 1) y_start = (plot_height + vertical_spacing) * rrr y_end = y_start + plot_height xaxis = graph_objs.XAxis(domain=[x_start, x_end], anchor=x_anchor) fig['layout'][xaxis_name] = xaxis yaxis = graph_objs.YAxis(domain=[y_start, y_end], anchor=y_anchor) fig['layout'][yaxis_name] = yaxis plot_num += 1 if print_grid: print("This is the format of your plot grid!") grid_string = "" plot = 1 for rrr in range(rows): grid_line = "" for ccc in range(columns): grid_line += "[{0}]\t".format(plot) plot += 1 grid_string = grid_line + '\n' + grid_string print(grid_string) return graph_objs.Figure(fig) # forces us to validate what we just did... def make_subplots(rows=1, cols=1, shared_xaxes=False, shared_yaxes=False, start_cell='top-left', print_grid=True, **kwargs): """Return an instance of plotly.graph_objs.Figure with the subplots domain set in 'layout'. Example 1: # stack two subplots vertically fig = tools.make_subplots(rows=2) This is the format of your plot grid: [ (1,1) x1,y1 ] [ (2,1) x2,y2 ] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2])] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x2', yaxis='y2')] # or see Figure.append_trace Example 2: # subplots with shared x axes fig = tools.make_subplots(rows=2, shared_xaxes=True) This is the format of your plot grid: [ (1,1) x1,y1 ] [ (2,1) x1,y2 ] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2])] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], yaxis='y2')] Example 3: # irregular subplot layout (more examples below under 'specs') fig = tools.make_subplots(rows=2, cols=2, specs=[[{}, {}], [{'colspan': 2}, None]]) This is the format of your plot grid! [ (1,1) x1,y1 ] [ (1,2) x2,y2 ] [ (2,1) x3,y3 - ] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2])] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x2', yaxis='y2')] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x3', yaxis='y3')] Example 4: # insets fig = tools.make_subplots(insets=[{'cell': (1,1), 'l': 0.7, 'b': 0.3}]) This is the format of your plot grid! [ (1,1) x1,y1 ] With insets: [ x2,y2 ] over [ (1,1) x1,y1 ] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2])] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x2', yaxis='y2')] Example 5: # include subplot titles fig = tools.make_subplots(rows=2, subplot_titles=('Plot 1','Plot 2')) This is the format of your plot grid: [ (1,1) x1,y1 ] [ (2,1) x2,y2 ] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2])] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x2', yaxis='y2')] Example 6: # Include subplot title on one plot (but not all) fig = tools.make_subplots(insets=[{'cell': (1,1), 'l': 0.7, 'b': 0.3}], subplot_titles=('','Inset')) This is the format of your plot grid! [ (1,1) x1,y1 ] With insets: [ x2,y2 ] over [ (1,1) x1,y1 ] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2])] fig['data'] += [Scatter(x=[1,2,3], y=[2,1,2], xaxis='x2', yaxis='y2')] Keywords arguments with constant defaults: rows (kwarg, int greater than 0, default=1): Number of rows in the subplot grid. cols (kwarg, int greater than 0, default=1): Number of columns in the subplot grid. shared_xaxes (kwarg, boolean or list, default=False) Assign shared x axes. If True, subplots in the same grid column have one common shared x-axis at the bottom of the gird. To assign shared x axes per subplot grid cell (see 'specs'), send list (or list of lists, one list per shared x axis) of cell index tuples. shared_yaxes (kwarg, boolean or list, default=False) Assign shared y axes. If True, subplots in the same grid row have one common shared y-axis on the left-hand side of the gird. To assign shared y axes per subplot grid cell (see 'specs'), send list (or list of lists, one list per shared y axis) of cell index tuples. start_cell (kwarg, 'bottom-left' or 'top-left', default='top-left') Choose the starting cell in the subplot grid used to set the domains of the subplots. print_grid (kwarg, boolean, default=True): If True, prints a tab-delimited string representation of your plot grid. Keyword arguments with variable defaults: horizontal_spacing (kwarg, float in [0,1], default=0.2 / cols): Space between subplot columns. Applies to all columns (use 'specs' subplot-dependents spacing) vertical_spacing (kwarg, float in [0,1], default=0.3 / rows): Space between subplot rows. Applies to all rows (use 'specs' subplot-dependents spacing) subplot_titles (kwarg, list of strings, default=empty list): Title of each subplot. "" can be included in the list if no subplot title is desired in that space so that the titles are properly indexed. specs (kwarg, list of lists of dictionaries): Subplot specifications. ex1: specs=[[{}, {}], [{'colspan': 2}, None]] ex2: specs=[[{'rowspan': 2}, {}], [None, {}]] - Indices of the outer list correspond to subplot grid rows starting from the bottom. The number of rows in 'specs' must be equal to 'rows'. - Indices of the inner lists correspond to subplot grid columns starting from the left. The number of columns in 'specs' must be equal to 'cols'. - Each item in the 'specs' list corresponds to one subplot in a subplot grid. (N.B. The subplot grid has exactly 'rows' times 'cols' cells.) - Use None for blank a subplot cell (or to move pass a col/row span). - Note that specs[0][0] has the specs of the 'start_cell' subplot. - Each item in 'specs' is a dictionary. The available keys are: * is_3d (boolean, default=False): flag for 3d scenes * colspan (int, default=1): number of subplot columns for this subplot to span. * rowspan (int, default=1): number of subplot rows for this subplot to span. * l (float, default=0.0): padding left of cell * r (float, default=0.0): padding right of cell * t (float, default=0.0): padding right of cell * b (float, default=0.0): padding bottom of cell - Use 'horizontal_spacing' and 'vertical_spacing' to adjust the spacing in between the subplots. insets (kwarg, list of dictionaries): Inset specifications. - Each item in 'insets' is a dictionary. The available keys are: * cell (tuple, default=(1,1)): (row, col) index of the subplot cell to overlay inset axes onto. * is_3d (boolean, default=False): flag for 3d scenes * l (float, default=0.0): padding left of inset in fraction of cell width * w (float or 'to_end', default='to_end') inset width in fraction of cell width ('to_end': to cell right edge) * b (float, default=0.0): padding bottom of inset in fraction of cell height * h (float or 'to_end', default='to_end') inset height in fraction of cell height ('to_end': to cell top edge) """ # TODO: protected until #282 from plotly.graph_objs import graph_objs # Throw exception for non-integer rows and cols if not isinstance(rows, int) or rows <= 0: raise Exception("Keyword argument 'rows' " "must be an int greater than 0") if not isinstance(cols, int) or cols <= 0: raise Exception("Keyword argument 'cols' " "must be an int greater than 0") # Dictionary of things start_cell START_CELL_all = { 'bottom-left': { # 'natural' setup where x & y domains increase monotonically 'col_dir': 1, 'row_dir': 1 }, 'top-left': { # 'default' setup visually matching the 'specs' list of lists 'col_dir': 1, 'row_dir': -1 } # TODO maybe add 'bottom-right' and 'top-right' } # Throw exception for invalid 'start_cell' values try: START_CELL = START_CELL_all[start_cell] except KeyError: raise Exception("Invalid 'start_cell' value") # Throw exception if non-valid kwarg is sent VALID_KWARGS = ['horizontal_spacing', 'vertical_spacing', 'specs', 'insets', 'subplot_titles'] for key in kwargs.keys(): if key not in VALID_KWARGS: raise Exception("Invalid keyword argument: '{0}'".format(key)) # Set 'subplot_titles' subplot_titles = kwargs.get('subplot_titles', [""] * rows * cols) # Set 'horizontal_spacing' / 'vertical_spacing' w.r.t. rows / cols try: horizontal_spacing = float(kwargs['horizontal_spacing']) except KeyError: horizontal_spacing = 0.2 / cols try: vertical_spacing = float(kwargs['vertical_spacing']) except KeyError: if 'subplot_titles' in kwargs: vertical_spacing = 0.5 / rows else: vertical_spacing = 0.3 / rows # Sanitize 'specs' (must be a list of lists) exception_msg = "Keyword argument 'specs' must be a list of lists" try: specs = kwargs['specs'] if not isinstance(specs, list): raise Exception(exception_msg) else: for spec_row in specs: if not isinstance(spec_row, list): raise Exception(exception_msg) except KeyError: specs = [[{} for c in range(cols)] for r in range(rows)] # default 'specs' # Throw exception if specs is over or under specified if len(specs) != rows: raise Exception("The number of rows in 'specs' " "must be equal to 'rows'") for r, spec_row in enumerate(specs): if len(spec_row) != cols: raise Exception("The number of columns in 'specs' " "must be equal to 'cols'") # Sanitize 'insets' try: insets = kwargs['insets'] if not isinstance(insets, list): raise Exception("Keyword argument 'insets' must be a list") except KeyError: insets = False # Throw exception if non-valid key / fill in defaults def _check_keys_and_fill(name, arg, defaults): def _checks(item, defaults): if item is None: return if not isinstance(item, dict): raise Exception("Items in keyword argument '{name}' must be " "dictionaries or None".format(name=name)) for k in item.keys(): if k not in defaults.keys(): raise Exception("Invalid key '{k}' in keyword " "argument '{name}'".format(k=k, name=name)) for k in defaults.keys(): if k not in item.keys(): item[k] = defaults[k] for arg_i in arg: if isinstance(arg_i, list): for arg_ii in arg_i: _checks(arg_ii, defaults) elif isinstance(arg_i, dict): _checks(arg_i, defaults) # Default spec key-values SPEC_defaults = dict( is_3d=False, colspan=1, rowspan=1, l=0.0, r=0.0, b=0.0, t=0.0 # TODO add support for 'w' and 'h' ) _check_keys_and_fill('specs', specs, SPEC_defaults) # Default inset key-values if insets: INSET_defaults = dict( cell=(1, 1), is_3d=False, l=0.0, w='to_end', b=0.0, h='to_end' ) _check_keys_and_fill('insets', insets, INSET_defaults) # Set width & height of each subplot cell (excluding padding) width = (1. - horizontal_spacing * (cols - 1)) / cols height = (1. - vertical_spacing * (rows - 1)) / rows # Built row/col sequence using 'row_dir' and 'col_dir' COL_DIR = START_CELL['col_dir'] ROW_DIR = START_CELL['row_dir'] col_seq = range(cols)[::COL_DIR] row_seq = range(rows)[::ROW_DIR] # [grid] Build subplot grid (coord tuple of cell) grid = [[((width + horizontal_spacing) * c, (height + vertical_spacing) * r) for c in col_seq] for r in row_seq] # [grid_ref] Initialize the grid and insets' axis-reference lists grid_ref = [[None for c in range(cols)] for r in range(rows)] insets_ref = [None for inset in range(len(insets))] if insets else None layout = graph_objs.Layout() # init layout object # Function handling logic around 2d axis labels # Returns 'x{}' | 'y{}' def _get_label(x_or_y, r, c, cnt, shared_axes): # Default label (given strictly by cnt) label = "{x_or_y}{cnt}".format(x_or_y=x_or_y, cnt=cnt) if isinstance(shared_axes, bool): if shared_axes: if x_or_y == 'x': label = "{x_or_y}{c}".format(x_or_y=x_or_y, c=c + 1) if x_or_y == 'y': label = "{x_or_y}{r}".format(x_or_y=x_or_y, r=r + 1) if isinstance(shared_axes, list): if isinstance(shared_axes[0], tuple): shared_axes = [shared_axes] # TODO put this elsewhere for shared_axis in shared_axes: if (r + 1, c + 1) in shared_axis: label = { 'x': "x{0}".format(shared_axis[0][1]), 'y': "y{0}".format(shared_axis[0][0]) }[x_or_y] return label # Row in grid of anchor row if shared_xaxes=True ANCHOR_ROW = 0 if ROW_DIR > 0 else rows - 1 # Function handling logic around 2d axis anchors # Return 'x{}' | 'y{}' | 'free' | False def _get_anchors(r, c, x_cnt, y_cnt, shared_xaxes, shared_yaxes): # Default anchors (give strictly by cnt) x_anchor = "y{y_cnt}".format(y_cnt=y_cnt) y_anchor = "x{x_cnt}".format(x_cnt=x_cnt) if isinstance(shared_xaxes, bool): if shared_xaxes: if r != ANCHOR_ROW: x_anchor = False y_anchor = 'free' if shared_yaxes and c != 0: # TODO covers all cases? y_anchor = False return x_anchor, y_anchor elif isinstance(shared_xaxes, list): if isinstance(shared_xaxes[0], tuple): shared_xaxes = [shared_xaxes] # TODO put this elsewhere for shared_xaxis in shared_xaxes: if (r + 1, c + 1) in shared_xaxis[1:]: x_anchor = False y_anchor = 'free' # TODO covers all cases? if isinstance(shared_yaxes, bool): if shared_yaxes: if c != 0: y_anchor = False x_anchor = 'free' if shared_xaxes and r != ANCHOR_ROW: # TODO all cases? x_anchor = False return x_anchor, y_anchor elif isinstance(shared_yaxes, list): if isinstance(shared_yaxes[0], tuple): shared_yaxes = [shared_yaxes] # TODO put this elsewhere for shared_yaxis in shared_yaxes: if (r + 1, c + 1) in shared_yaxis[1:]: y_anchor = False x_anchor = 'free' # TODO covers all cases? return x_anchor, y_anchor list_of_domains = [] # added for subplot titles # Function pasting x/y domains in layout object (2d case) def _add_domain(layout, x_or_y, label, domain, anchor, position): name = label[0] + 'axis' + label[1:] graph_obj = '{X_or_Y}Axis'.format(X_or_Y=x_or_y.upper()) axis = getattr(graph_objs, graph_obj)(domain=domain) if anchor: axis['anchor'] = anchor if isinstance(position, float): axis['position'] = position layout[name] = axis list_of_domains.append(domain) # added for subplot titles # Function pasting x/y domains in layout object (3d case) def _add_domain_is_3d(layout, s_label, x_domain, y_domain): scene = graph_objs.Scene(domain={'x': x_domain, 'y': y_domain}) layout[s_label] = scene x_cnt = y_cnt = s_cnt = 1 # subplot axis/scene counters # Loop through specs -- (r, c) <-> (row, col) for r, spec_row in enumerate(specs): for c, spec in enumerate(spec_row): if spec is None: # skip over None cells continue c_spanned = c + spec['colspan'] - 1 # get spanned c r_spanned = r + spec['rowspan'] - 1 # get spanned r # Throw exception if 'colspan' | 'rowspan' is too large for grid if c_spanned >= cols: raise Exception("Some 'colspan' value is too large for " "this subplot grid.") if r_spanned >= rows: raise Exception("Some 'rowspan' value is too large for " "this subplot grid.") # Get x domain using grid and colspan x_s = grid[r][c][0] + spec['l'] x_e = grid[r][c_spanned][0] + width - spec['r'] x_domain = [x_s, x_e] # Get y domain (dep. on row_dir) using grid & r_spanned if ROW_DIR > 0: y_s = grid[r][c][1] + spec['b'] y_e = grid[r_spanned][c][1] + height - spec['t'] else: y_s = grid[r_spanned][c][1] + spec['b'] y_e = grid[r][c][1] + height - spec['t'] y_domain = [y_s, y_e] if spec['is_3d']: # Add scene to layout s_label = 'scene{0}'.format(s_cnt) _add_domain_is_3d(layout, s_label, x_domain, y_domain) grid_ref[r][c] = (s_label, ) s_cnt += 1 else: # Get axis label and anchor x_label = _get_label('x', r, c, x_cnt, shared_xaxes) y_label = _get_label('y', r, c, y_cnt, shared_yaxes) x_anchor, y_anchor = _get_anchors(r, c, x_cnt, y_cnt, shared_xaxes, shared_yaxes) # Add a xaxis to layout (N.B anchor == False -> no axis) if x_anchor: if x_anchor == 'free': x_position = y_domain[0] else: x_position = False _add_domain(layout, 'x', x_label, x_domain, x_anchor, x_position) x_cnt += 1 # Add a yaxis to layout (N.B anchor == False -> no axis) if y_anchor: if y_anchor == 'free': y_position = x_domain[0] else: y_position = False _add_domain(layout, 'y', y_label, y_domain, y_anchor, y_position) y_cnt += 1 grid_ref[r][c] = (x_label, y_label) # fill in ref # Loop through insets if insets: for i_inset, inset in enumerate(insets): r = inset['cell'][0] - 1 c = inset['cell'][1] - 1 # Throw exception if r | c is out of range if not (0 <= r < rows): raise Exception("Some 'cell' row value is out of range. " "Note: the starting cell is (1, 1)") if not (0 <= c < cols): raise Exception("Some 'cell' col value is out of range. " "Note: the starting cell is (1, 1)") # Get inset x domain using grid x_s = grid[r][c][0] + inset['l'] * width if inset['w'] == 'to_end': x_e = grid[r][c][0] + width else: x_e = x_s + inset['w'] * width x_domain = [x_s, x_e] # Get inset y domain using grid y_s = grid[r][c][1] + inset['b'] * height if inset['h'] == 'to_end': y_e = grid[r][c][1] + height else: y_e = y_s + inset['h'] * height y_domain = [y_s, y_e] if inset['is_3d']: # Add scene to layout s_label = 'scene{0}'.format(s_cnt) _add_domain_is_3d(layout, s_label, x_domain, y_domain) insets_ref[i_inset] = (s_label, ) s_cnt += 1 else: # Get axis label and anchor x_label = _get_label('x', False, False, x_cnt, False) y_label = _get_label('y', False, False, y_cnt, False) x_anchor, y_anchor = _get_anchors(r, c, x_cnt, y_cnt, False, False) # Add a xaxis to layout (N.B insets always have anchors) _add_domain(layout, 'x', x_label, x_domain, x_anchor, False) x_cnt += 1 # Add a yayis to layout (N.B insets always have anchors) _add_domain(layout, 'y', y_label, y_domain, y_anchor, False) y_cnt += 1 insets_ref[i_inset] = (x_label, y_label) # fill in ref # [grid_str] Set the grid's string representation sp = " " # space between cell s_str = "[ " # cell start string e_str = " ]" # cell end string colspan_str = ' -' # colspan string rowspan_str = ' |' # rowspan string empty_str = ' (empty) ' # empty cell string # Init grid_str with intro message grid_str = "This is the format of your plot grid:\n" # Init tmp list of lists of strings (sorta like 'grid_ref' but w/ strings) _tmp = [['' for c in range(cols)] for r in range(rows)] # Define cell string as function of (r, c) and grid_ref def _get_cell_str(r, c, ref): return '({r},{c}) {ref}'.format(r=r + 1, c=c + 1, ref=','.join(ref)) # Find max len of _cell_str, add define a padding function cell_len = max([len(_get_cell_str(r, c, ref)) for r, row_ref in enumerate(grid_ref) for c, ref in enumerate(row_ref) if ref]) + len(s_str) + len(e_str) def _pad(s, cell_len=cell_len): return ' ' * (cell_len - len(s)) # Loop through specs, fill in _tmp for r, spec_row in enumerate(specs): for c, spec in enumerate(spec_row): ref = grid_ref[r][c] if ref is None: if _tmp[r][c] == '': _tmp[r][c] = empty_str + _pad(empty_str) continue cell_str = s_str + _get_cell_str(r, c, ref) if spec['colspan'] > 1: for cc in range(1, spec['colspan'] - 1): _tmp[r][c + cc] = colspan_str + _pad(colspan_str) _tmp[r][c + spec['colspan'] - 1] = ( colspan_str + _pad(colspan_str + e_str)) + e_str else: cell_str += e_str if spec['rowspan'] > 1: for rr in range(1, spec['rowspan'] - 1): _tmp[r + rr][c] = rowspan_str + _pad(rowspan_str) for cc in range(spec['colspan']): _tmp[r + spec['rowspan'] - 1][c + cc] = ( rowspan_str + _pad(rowspan_str)) _tmp[r][c] = cell_str + _pad(cell_str) # Append grid_str using data from _tmp in the correct order for r in row_seq[::-1]: grid_str += sp.join(_tmp[r]) + '\n' # Append grid_str to include insets info if insets: grid_str += "\nWith insets:\n" for i_inset, inset in enumerate(insets): r = inset['cell'][0] - 1 c = inset['cell'][1] - 1 ref = grid_ref[r][c] grid_str += ( s_str + ','.join(insets_ref[i_inset]) + e_str + ' over ' + s_str + _get_cell_str(r, c, ref) + e_str + '\n' ) # Add subplot titles # If shared_axes is False (default) use list_of_domains # This is used for insets and irregular layouts if not shared_xaxes and not shared_yaxes: x_dom = list_of_domains[::2] y_dom = list_of_domains[1::2] subtitle_pos_x = [] subtitle_pos_y = [] for x_domains in x_dom: subtitle_pos_x.append(sum(x_domains) / 2) for y_domains in y_dom: subtitle_pos_y.append(y_domains[1]) # If shared_axes is True the domin of each subplot is not returned so the # title position must be calculated for each subplot else: subtitle_pos_x = [None] * cols subtitle_pos_y = [None] * rows delt_x = (x_e - x_s) for index in range(cols): subtitle_pos_x[index] = ((delt_x / 2) + ((delt_x + horizontal_spacing) * index)) subtitle_pos_x *= rows for index in range(rows): subtitle_pos_y[index] = (1 - ((y_e + vertical_spacing) * index)) subtitle_pos_y *= cols subtitle_pos_y = sorted(subtitle_pos_y, reverse=True) plot_titles = [] for index in range(len(subplot_titles)): if not subplot_titles[index]: pass else: plot_titles.append({'y': subtitle_pos_y[index], 'xref': 'paper', 'x': subtitle_pos_x[index], 'yref': 'paper', 'text': subplot_titles[index], 'showarrow': False, 'font': graph_objs.Font(size=16), 'xanchor': 'center', 'yanchor': 'bottom' }) layout['annotations'] = plot_titles if print_grid: print(grid_str) fig = graph_objs.Figure(layout=layout) fig.__dict__['_grid_ref'] = grid_ref fig.__dict__['_grid_str'] = grid_str return fig def get_valid_graph_obj(obj, obj_type=None): """Returns a new graph object that won't raise. CAREFUL: this will *silently* strip out invalid pieces of the object. """ # TODO: Deprecate or move. #283 from plotly.graph_objs import graph_objs try: cls = getattr(graph_objs, obj_type) except (AttributeError, KeyError): raise exceptions.PlotlyError( "'{}' is not a recognized graph_obj.".format(obj_type) ) return cls(obj, _raise=False) def validate(obj, obj_type): """Validate a dictionary, list, or graph object as 'obj_type'. This will not alter the 'obj' referenced in the call signature. It will raise an error if the 'obj' reference could not be instantiated as a valid 'obj_type' graph object. """ # TODO: Deprecate or move. #283 from plotly.graph_objs import graph_objs if obj_type not in graph_reference.CLASSES: obj_type = graph_reference.string_to_class_name(obj_type) try: cls = getattr(graph_objs, obj_type) except AttributeError: raise exceptions.PlotlyError( "'{0}' is not a recognizable graph_obj.". format(obj_type)) cls(obj) # this will raise on invalid keys/items def _replace_newline(obj): """Replaces '\n' with '
' for all strings in a collection.""" if isinstance(obj, dict): d = dict() for key, val in list(obj.items()): d[key] = _replace_newline(val) return d elif isinstance(obj, list): l = list() for index, entry in enumerate(obj): l += [_replace_newline(entry)] return l elif isinstance(obj, six.string_types): s = obj.replace('\n', '
') if s != obj: warnings.warn("Looks like you used a newline character: '\\n'.\n\n" "Plotly uses a subset of HTML escape characters\n" "to do things like newline (
), bold (),\n" "italics (), etc. Your newline characters \n" "have been converted to '
' so they will show \n" "up right on your Plotly figure!") return s else: return obj # we return the actual reference... but DON'T mutate. if _ipython_imported: class PlotlyDisplay(IPython.core.display.HTML): """An IPython display object for use with plotly urls PlotlyDisplay objects should be instantiated with a url for a plot. IPython will *choose* the proper display representation from any Python object, and using provided methods if they exist. By defining the following, if an HTML display is unusable, the PlotlyDisplay object can provide alternate representations. """ def __init__(self, url, width, height): self.resource = url self.embed_code = get_embed(url, width=width, height=height) super(PlotlyDisplay, self).__init__(data=self.embed_code) def _repr_html_(self): return self.embed_code def return_figure_from_figure_or_data(figure_or_data, validate_figure): from plotly.graph_objs import graph_objs if isinstance(figure_or_data, dict): figure = figure_or_data elif isinstance(figure_or_data, list): figure = {'data': figure_or_data} else: raise exceptions.PlotlyError("The `figure_or_data` positional " "argument must be either " "`dict`-like or `list`-like.") if validate_figure: try: graph_objs.Figure(figure) except exceptions.PlotlyError as err: raise exceptions.PlotlyError("Invalid 'figure_or_data' argument. " "Plotly will not be able to properly " "parse the resulting JSON. If you " "want to send this 'figure_or_data' " "to Plotly anyway (not recommended), " "you can set 'validate=False' as a " "plot option.\nHere's why you're " "seeing this error:\n\n{0}" "".format(err)) if not figure['data']: raise exceptions.PlotlyEmptyDataError( "Empty data list found. Make sure that you populated the " "list of data objects you're sending and try again.\n" "Questions? support@plot.ly" ) return figure # Default colours for finance charts _DEFAULT_INCREASING_COLOR = '#3D9970' # http://clrs.cc _DEFAULT_DECREASING_COLOR = '#FF4136' class FigureFactory(object): """ BETA functions to create specific chart types. This is beta as in: subject to change in a backwards incompatible way without notice. Supported chart types include candlestick, open high low close, quiver, streamline, distplot, dendrogram, annotated heatmap, and tables. See FigureFactory.create_candlestick, FigureFactory.create_ohlc, FigureFactory.create_quiver, FigureFactory.create_streamline, FigureFactory.create_distplot, FigureFactory.create_dendrogram, FigureFactory.create_annotated_heatmap, or FigureFactory.create_table for more information and examples of a specific chart type. """ @staticmethod def _validate_equal_length(*args): """ Validates that data lists or ndarrays are the same length. :raises: (PlotlyError) If any data lists are not the same length. """ length = len(args[0]) if any(len(lst) != length for lst in args): raise exceptions.PlotlyError("Oops! Your data lists or ndarrays " "should be the same length.") @staticmethod def _validate_ohlc(open, high, low, close, direction, **kwargs): """ ohlc and candlestick specific validations Specifically, this checks that the high value is the greatest value and the low value is the lowest value in each unit. See FigureFactory.create_ohlc() or FigureFactory.create_candlestick() for params :raises: (PlotlyError) If the high value is not the greatest value in each unit. :raises: (PlotlyError) If the low value is not the lowest value in each unit. :raises: (PlotlyError) If direction is not 'increasing' or 'decreasing' """ for lst in [open, low, close]: for index in range(len(high)): if high[index] < lst[index]: raise exceptions.PlotlyError("Oops! Looks like some of " "your high values are less " "the corresponding open, " "low, or close values. " "Double check that your data " "is entered in O-H-L-C order") for lst in [open, high, close]: for index in range(len(low)): if low[index] > lst[index]: raise exceptions.PlotlyError("Oops! Looks like some of " "your low values are greater " "than the corresponding high" ", open, or close values. " "Double check that your data " "is entered in O-H-L-C order") direction_opts = ('increasing', 'decreasing', 'both') if direction not in direction_opts: raise exceptions.PlotlyError("direction must be defined as " "'increasing', 'decreasing', or " "'both'") @staticmethod def _validate_distplot(hist_data, curve_type): """ Distplot-specific validations :raises: (PlotlyError) If hist_data is not a list of lists :raises: (PlotlyError) If curve_type is not valid (i.e. not 'kde' or 'normal'). """ try: import pandas as pd _pandas_imported = True except ImportError: _pandas_imported = False hist_data_types = (list,) if _numpy_imported: hist_data_types += (np.ndarray,) if _pandas_imported: hist_data_types += (pd.core.series.Series,) if not isinstance(hist_data[0], hist_data_types): raise exceptions.PlotlyError("Oops, this function was written " "to handle multiple datasets, if " "you want to plot just one, make " "sure your hist_data variable is " "still a list of lists, i.e. x = " "[1, 2, 3] -> x = [[1, 2, 3]]") curve_opts = ('kde', 'normal') if curve_type not in curve_opts: raise exceptions.PlotlyError("curve_type must be defined as " "'kde' or 'normal'") if _scipy_imported is False: raise ImportError("FigureFactory.create_distplot requires scipy") @staticmethod def _validate_positive_scalars(**kwargs): """ Validates that all values given in key/val pairs are positive. Accepts kwargs to improve Exception messages. :raises: (PlotlyError) If any value is < 0 or raises. """ for key, val in kwargs.items(): try: if val <= 0: raise ValueError('{} must be > 0, got {}'.format(key, val)) except TypeError: raise exceptions.PlotlyError('{} must be a number, got {}' .format(key, val)) @staticmethod def _validate_streamline(x, y): """ Streamline-specific validations Specifically, this checks that x and y are both evenly spaced, and that the package numpy is available. See FigureFactory.create_streamline() for params :raises: (ImportError) If numpy is not available. :raises: (PlotlyError) If x is not evenly spaced. :raises: (PlotlyError) If y is not evenly spaced. """ if _numpy_imported is False: raise ImportError("FigureFactory.create_streamline requires numpy") for index in range(len(x) - 1): if ((x[index + 1] - x[index]) - (x[1] - x[0])) > .0001: raise exceptions.PlotlyError("x must be a 1 dimensional, " "evenly spaced array") for index in range(len(y) - 1): if ((y[index + 1] - y[index]) - (y[1] - y[0])) > .0001: raise exceptions.PlotlyError("y must be a 1 dimensional, " "evenly spaced array") @staticmethod def _validate_annotated_heatmap(z, x, y, annotation_text): """ Annotated-heatmap-specific validations Check that if a text matrix is supplied, it has the same dimensions as the z matrix. See FigureFactory.create_annotated_heatmap() for params :raises: (PlotlyError) If z and text matrices do not have the same dimensions. """ if annotation_text is not None and isinstance(annotation_text, list): FigureFactory._validate_equal_length(z, annotation_text) for lst in range(len(z)): if len(z[lst]) != len(annotation_text[lst]): raise exceptions.PlotlyError("z and text should have the " "same dimensions") if x: if len(x) != len(z[0]): raise exceptions.PlotlyError("oops, the x list that you " "provided does not match the " "width of your z matrix ") if y: if len(y) != len(z): raise exceptions.PlotlyError("oops, the y list that you " "provided does not match the " "length of your z matrix ") @staticmethod def _validate_table(table_text, font_colors): """ Table-specific validations Check that font_colors is supplied correctly (1, 3, or len(text) colors). :raises: (PlotlyError) If font_colors is supplied incorretly. See FigureFactory.create_table() for params """ font_colors_len_options = [1, 3, len(table_text)] if len(font_colors) not in font_colors_len_options: raise exceptions.PlotlyError("Oops, font_colors should be a list " "of length 1, 3 or len(text)") @staticmethod def _flatten(array): """ Uses list comprehension to flatten array :param (array): An iterable to flatten :raises (PlotlyError): If iterable is not nested. :rtype (list): The flattened list. """ try: return [item for sublist in array for item in sublist] except TypeError: raise exceptions.PlotlyError("Your data array could not be " "flattened! Make sure your data is " "entered as lists or ndarrays!") @staticmethod def _hex_to_rgb(value): """ Calculates rgb values from a hex color code. :param (string) value: Hex color string :rtype (tuple) (r_value, g_value, b_value): tuple of rgb values """ value = value.lstrip('#') hex_total_length = len(value) rgb_section_length = hex_total_length // 3 return tuple(int(value[i:i + rgb_section_length], 16) for i in range(0, hex_total_length, rgb_section_length)) @staticmethod def create_quiver(x, y, u, v, scale=.1, arrow_scale=.3, angle=math.pi / 9, **kwargs): """ Returns data for a quiver plot. :param (list|ndarray) x: x coordinates of the arrow locations :param (list|ndarray) y: y coordinates of the arrow locations :param (list|ndarray) u: x components of the arrow vectors :param (list|ndarray) v: y components of the arrow vectors :param (float in [0,1]) scale: scales size of the arrows(ideally to avoid overlap). Default = .1 :param (float in [0,1]) arrow_scale: value multiplied to length of barb to get length of arrowhead. Default = .3 :param (angle in radians) angle: angle of arrowhead. Default = pi/9 :param kwargs: kwargs passed through plotly.graph_objs.Scatter for more information on valid kwargs call help(plotly.graph_objs.Scatter) :rtype (dict): returns a representation of quiver figure. Example 1: Trivial Quiver ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import math # 1 Arrow from (0,0) to (1,1) fig = FF.create_quiver(x=[0], y=[0], u=[1], v=[1], scale=1) py.plot(fig, filename='quiver') ``` Example 2: Quiver plot using meshgrid ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np import math # Add data x,y = np.meshgrid(np.arange(0, 2, .2), np.arange(0, 2, .2)) u = np.cos(x)*y v = np.sin(x)*y #Create quiver fig = FF.create_quiver(x, y, u, v) # Plot py.plot(fig, filename='quiver') ``` Example 3: Styling the quiver plot ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np import math # Add data x, y = np.meshgrid(np.arange(-np.pi, math.pi, .5), np.arange(-math.pi, math.pi, .5)) u = np.cos(x)*y v = np.sin(x)*y # Create quiver fig = FF.create_quiver(x, y, u, v, scale=.2, arrow_scale=.3, angle=math.pi/6, name='Wind Velocity', line=Line(width=1)) # Add title to layout fig['layout'].update(title='Quiver Plot') # Plot py.plot(fig, filename='quiver') ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs FigureFactory._validate_equal_length(x, y, u, v) FigureFactory._validate_positive_scalars(arrow_scale=arrow_scale, scale=scale) barb_x, barb_y = _Quiver(x, y, u, v, scale, arrow_scale, angle).get_barbs() arrow_x, arrow_y = _Quiver(x, y, u, v, scale, arrow_scale, angle).get_quiver_arrows() quiver = graph_objs.Scatter(x=barb_x + arrow_x, y=barb_y + arrow_y, mode='lines', **kwargs) data = [quiver] layout = graph_objs.Layout(hovermode='closest') return graph_objs.Figure(data=data, layout=layout) @staticmethod def create_streamline(x, y, u, v, density=1, angle=math.pi / 9, arrow_scale=.09, **kwargs): """ Returns data for a streamline plot. :param (list|ndarray) x: 1 dimensional, evenly spaced list or array :param (list|ndarray) y: 1 dimensional, evenly spaced list or array :param (ndarray) u: 2 dimensional array :param (ndarray) v: 2 dimensional array :param (float|int) density: controls the density of streamlines in plot. This is multiplied by 30 to scale similiarly to other available streamline functions such as matplotlib. Default = 1 :param (angle in radians) angle: angle of arrowhead. Default = pi/9 :param (float in [0,1]) arrow_scale: value to scale length of arrowhead Default = .09 :param kwargs: kwargs passed through plotly.graph_objs.Scatter for more information on valid kwargs call help(plotly.graph_objs.Scatter) :rtype (dict): returns a representation of streamline figure. Example 1: Plot simple streamline and increase arrow size ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np import math # Add data x = np.linspace(-3, 3, 100) y = np.linspace(-3, 3, 100) Y, X = np.meshgrid(x, y) u = -1 - X**2 + Y v = 1 + X - Y**2 u = u.T # Transpose v = v.T # Transpose # Create streamline fig = FF.create_streamline(x, y, u, v, arrow_scale=.1) # Plot py.plot(fig, filename='streamline') ``` Example 2: from nbviewer.ipython.org/github/barbagroup/AeroPython ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np import math # Add data N = 50 x_start, x_end = -2.0, 2.0 y_start, y_end = -1.0, 1.0 x = np.linspace(x_start, x_end, N) y = np.linspace(y_start, y_end, N) X, Y = np.meshgrid(x, y) ss = 5.0 x_s, y_s = -1.0, 0.0 # Compute the velocity field on the mesh grid u_s = ss/(2*np.pi) * (X-x_s)/((X-x_s)**2 + (Y-y_s)**2) v_s = ss/(2*np.pi) * (Y-y_s)/((X-x_s)**2 + (Y-y_s)**2) # Create streamline fig = FF.create_streamline(x, y, u_s, v_s, density=2, name='streamline') # Add source point point = Scatter(x=[x_s], y=[y_s], mode='markers', marker=Marker(size=14), name='source point') # Plot fig['data'].append(point) py.plot(fig, filename='streamline') ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs FigureFactory._validate_equal_length(x, y) FigureFactory._validate_equal_length(u, v) FigureFactory._validate_streamline(x, y) FigureFactory._validate_positive_scalars(density=density, arrow_scale=arrow_scale) streamline_x, streamline_y = _Streamline(x, y, u, v, density, angle, arrow_scale).sum_streamlines() arrow_x, arrow_y = _Streamline(x, y, u, v, density, angle, arrow_scale).get_streamline_arrows() streamline = graph_objs.Scatter(x=streamline_x + arrow_x, y=streamline_y + arrow_y, mode='lines', **kwargs) data = [streamline] layout = graph_objs.Layout(hovermode='closest') return graph_objs.Figure(data=data, layout=layout) @staticmethod def _make_increasing_ohlc(open, high, low, close, dates, **kwargs): """ Makes increasing ohlc sticks _make_increasing_ohlc() and _make_decreasing_ohlc separate the increasing trace from the decreasing trace so kwargs (such as color) can be passed separately to increasing or decreasing traces when direction is set to 'increasing' or 'decreasing' in FigureFactory.create_candlestick() :param (list) open: opening values :param (list) high: high values :param (list) low: low values :param (list) close: closing values :param (list) dates: list of datetime objects. Default: None :param kwargs: kwargs to be passed to increasing trace via plotly.graph_objs.Scatter. :rtype (trace) ohlc_incr_data: Scatter trace of all increasing ohlc sticks. """ (flat_increase_x, flat_increase_y, text_increase) = _OHLC(open, high, low, close, dates).get_increase() if 'name' in kwargs: showlegend = True else: kwargs.setdefault('name', 'Increasing') showlegend = False kwargs.setdefault('line', dict(color=_DEFAULT_INCREASING_COLOR, width=1)) kwargs.setdefault('text', text_increase) ohlc_incr = dict(type='scatter', x=flat_increase_x, y=flat_increase_y, mode='lines', showlegend=showlegend, **kwargs) return ohlc_incr @staticmethod def _make_decreasing_ohlc(open, high, low, close, dates, **kwargs): """ Makes decreasing ohlc sticks :param (list) open: opening values :param (list) high: high values :param (list) low: low values :param (list) close: closing values :param (list) dates: list of datetime objects. Default: None :param kwargs: kwargs to be passed to increasing trace via plotly.graph_objs.Scatter. :rtype (trace) ohlc_decr_data: Scatter trace of all decreasing ohlc sticks. """ (flat_decrease_x, flat_decrease_y, text_decrease) = _OHLC(open, high, low, close, dates).get_decrease() kwargs.setdefault('line', dict(color=_DEFAULT_DECREASING_COLOR, width=1)) kwargs.setdefault('text', text_decrease) kwargs.setdefault('showlegend', False) kwargs.setdefault('name', 'Decreasing') ohlc_decr = dict(type='scatter', x=flat_decrease_x, y=flat_decrease_y, mode='lines', **kwargs) return ohlc_decr @staticmethod def create_ohlc(open, high, low, close, dates=None, direction='both', **kwargs): """ BETA function that creates an ohlc chart :param (list) open: opening values :param (list) high: high values :param (list) low: low values :param (list) close: closing :param (list) dates: list of datetime objects. Default: None :param (string) direction: direction can be 'increasing', 'decreasing', or 'both'. When the direction is 'increasing', the returned figure consists of all units where the close value is greater than the corresponding open value, and when the direction is 'decreasing', the returned figure consists of all units where the close value is less than or equal to the corresponding open value. When the direction is 'both', both increasing and decreasing units are returned. Default: 'both' :param kwargs: kwargs passed through plotly.graph_objs.Scatter. These kwargs describe other attributes about the ohlc Scatter trace such as the color or the legend name. For more information on valid kwargs call help(plotly.graph_objs.Scatter) :rtype (dict): returns a representation of an ohlc chart figure. Example 1: Simple OHLC chart from a Pandas DataFrame ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from datetime import datetime import pandas.io.data as web df = web.DataReader("aapl", 'yahoo', datetime(2008, 8, 15), datetime(2008, 10, 15)) fig = FF.create_ohlc(df.Open, df.High, df.Low, df.Close, dates=df.index) py.plot(fig, filename='finance/aapl-ohlc') ``` Example 2: Add text and annotations to the OHLC chart ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from datetime import datetime import pandas.io.data as web df = web.DataReader("aapl", 'yahoo', datetime(2008, 8, 15), datetime(2008, 10, 15)) fig = FF.create_ohlc(df.Open, df.High, df.Low, df.Close, dates=df.index) # Update the fig - all options here: https://plot.ly/python/reference/#Layout fig['layout'].update({ 'title': 'The Great Recession', 'yaxis': {'title': 'AAPL Stock'}, 'shapes': [{ 'x0': '2008-09-15', 'x1': '2008-09-15', 'type': 'line', 'y0': 0, 'y1': 1, 'xref': 'x', 'yref': 'paper', 'line': {'color': 'rgb(40,40,40)', 'width': 0.5} }], 'annotations': [{ 'text': "the fall of Lehman Brothers", 'x': '2008-09-15', 'y': 1.02, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'left' }] }) py.plot(fig, filename='finance/aapl-recession-ohlc', validate=False) ``` Example 3: Customize the OHLC colors ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from plotly.graph_objs import Line, Marker from datetime import datetime import pandas.io.data as web df = web.DataReader("aapl", 'yahoo', datetime(2008, 1, 1), datetime(2009, 4, 1)) # Make increasing ohlc sticks and customize their color and name fig_increasing = FF.create_ohlc(df.Open, df.High, df.Low, df.Close, dates=df.index, direction='increasing', name='AAPL', line=Line(color='rgb(150, 200, 250)')) # Make decreasing ohlc sticks and customize their color and name fig_decreasing = FF.create_ohlc(df.Open, df.High, df.Low, df.Close, dates=df.index, direction='decreasing', line=Line(color='rgb(128, 128, 128)')) # Initialize the figure fig = fig_increasing # Add decreasing data with .extend() fig['data'].extend(fig_decreasing['data']) py.iplot(fig, filename='finance/aapl-ohlc-colors', validate=False) ``` Example 4: OHLC chart with datetime objects ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from datetime import datetime # Add data open_data = [33.0, 33.3, 33.5, 33.0, 34.1] high_data = [33.1, 33.3, 33.6, 33.2, 34.8] low_data = [32.7, 32.7, 32.8, 32.6, 32.8] close_data = [33.0, 32.9, 33.3, 33.1, 33.1] dates = [datetime(year=2013, month=10, day=10), datetime(year=2013, month=11, day=10), datetime(year=2013, month=12, day=10), datetime(year=2014, month=1, day=10), datetime(year=2014, month=2, day=10)] # Create ohlc fig = FF.create_ohlc(open_data, high_data, low_data, close_data, dates=dates) py.iplot(fig, filename='finance/simple-ohlc', validate=False) ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs if dates is not None: FigureFactory._validate_equal_length(open, high, low, close, dates) else: FigureFactory._validate_equal_length(open, high, low, close) FigureFactory._validate_ohlc(open, high, low, close, direction, **kwargs) if direction is 'increasing': ohlc_incr = FigureFactory._make_increasing_ohlc(open, high, low, close, dates, **kwargs) data = [ohlc_incr] elif direction is 'decreasing': ohlc_decr = FigureFactory._make_decreasing_ohlc(open, high, low, close, dates, **kwargs) data = [ohlc_decr] else: ohlc_incr = FigureFactory._make_increasing_ohlc(open, high, low, close, dates, **kwargs) ohlc_decr = FigureFactory._make_decreasing_ohlc(open, high, low, close, dates, **kwargs) data = [ohlc_incr, ohlc_decr] layout = graph_objs.Layout(xaxis=dict(zeroline=False), hovermode='closest') return graph_objs.Figure(data=data, layout=layout) @staticmethod def _make_increasing_candle(open, high, low, close, dates, **kwargs): """ Makes boxplot trace for increasing candlesticks _make_increasing_candle() and _make_decreasing_candle separate the increasing traces from the decreasing traces so kwargs (such as color) can be passed separately to increasing or decreasing traces when direction is set to 'increasing' or 'decreasing' in FigureFactory.create_candlestick() :param (list) open: opening values :param (list) high: high values :param (list) low: low values :param (list) close: closing values :param (list) dates: list of datetime objects. Default: None :param kwargs: kwargs to be passed to increasing trace via plotly.graph_objs.Scatter. :rtype (list) candle_incr_data: list of the box trace for increasing candlesticks. """ increase_x, increase_y = _Candlestick( open, high, low, close, dates, **kwargs).get_candle_increase() if 'line' in kwargs: kwargs.setdefault('fillcolor', kwargs['line']['color']) else: kwargs.setdefault('fillcolor', _DEFAULT_INCREASING_COLOR) if 'name' in kwargs: kwargs.setdefault('showlegend', True) else: kwargs.setdefault('showlegend', False) kwargs.setdefault('name', 'Increasing') kwargs.setdefault('line', dict(color=_DEFAULT_INCREASING_COLOR)) candle_incr_data = dict(type='box', x=increase_x, y=increase_y, whiskerwidth=0, boxpoints=False, **kwargs) return [candle_incr_data] @staticmethod def _make_decreasing_candle(open, high, low, close, dates, **kwargs): """ Makes boxplot trace for decreasing candlesticks :param (list) open: opening values :param (list) high: high values :param (list) low: low values :param (list) close: closing values :param (list) dates: list of datetime objects. Default: None :param kwargs: kwargs to be passed to decreasing trace via plotly.graph_objs.Scatter. :rtype (list) candle_decr_data: list of the box trace for decreasing candlesticks. """ decrease_x, decrease_y = _Candlestick( open, high, low, close, dates, **kwargs).get_candle_decrease() if 'line' in kwargs: kwargs.setdefault('fillcolor', kwargs['line']['color']) else: kwargs.setdefault('fillcolor', _DEFAULT_DECREASING_COLOR) kwargs.setdefault('showlegend', False) kwargs.setdefault('line', dict(color=_DEFAULT_DECREASING_COLOR)) kwargs.setdefault('name', 'Decreasing') candle_decr_data = dict(type='box', x=decrease_x, y=decrease_y, whiskerwidth=0, boxpoints=False, **kwargs) return [candle_decr_data] @staticmethod def create_candlestick(open, high, low, close, dates=None, direction='both', **kwargs): """ BETA function that creates a candlestick chart :param (list) open: opening values :param (list) high: high values :param (list) low: low values :param (list) close: closing values :param (list) dates: list of datetime objects. Default: None :param (string) direction: direction can be 'increasing', 'decreasing', or 'both'. When the direction is 'increasing', the returned figure consists of all candlesticks where the close value is greater than the corresponding open value, and when the direction is 'decreasing', the returned figure consists of all candlesticks where the close value is less than or equal to the corresponding open value. When the direction is 'both', both increasing and decreasing candlesticks are returned. Default: 'both' :param kwargs: kwargs passed through plotly.graph_objs.Scatter. These kwargs describe other attributes about the ohlc Scatter trace such as the color or the legend name. For more information on valid kwargs call help(plotly.graph_objs.Scatter) :rtype (dict): returns a representation of candlestick chart figure. Example 1: Simple candlestick chart from a Pandas DataFrame ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from datetime import datetime import pandas.io.data as web df = web.DataReader("aapl", 'yahoo', datetime(2007, 10, 1), datetime(2009, 4, 1)) fig = FF.create_candlestick(df.Open, df.High, df.Low, df.Close, dates=df.index) py.plot(fig, filename='finance/aapl-candlestick', validate=False) ``` Example 2: Add text and annotations to the candlestick chart ``` fig = FF.create_candlestick(df.Open, df.High, df.Low, df.Close, dates=df.index) # Update the fig - all options here: https://plot.ly/python/reference/#Layout fig['layout'].update({ 'title': 'The Great Recession', 'yaxis': {'title': 'AAPL Stock'}, 'shapes': [{ 'x0': '2007-12-01', 'x1': '2007-12-01', 'y0': 0, 'y1': 1, 'xref': 'x', 'yref': 'paper', 'line': {'color': 'rgb(30,30,30)', 'width': 1} }], 'annotations': [{ 'x': '2007-12-01', 'y': 0.05, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'left', 'text': 'Official start of the recession' }] }) py.plot(fig, filename='finance/aapl-recession-candlestick', validate=False) ``` Example 3: Customize the candlestick colors ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from plotly.graph_objs import Line, Marker from datetime import datetime import pandas.io.data as web df = web.DataReader("aapl", 'yahoo', datetime(2008, 1, 1), datetime(2009, 4, 1)) # Make increasing candlesticks and customize their color and name fig_increasing = FF.create_candlestick(df.Open, df.High, df.Low, df.Close, dates=df.index, direction='increasing', name='AAPL', marker=Marker(color='rgb(150, 200, 250)'), line=Line(color='rgb(150, 200, 250)')) # Make decreasing candlesticks and customize their color and name fig_decreasing = FF.create_candlestick(df.Open, df.High, df.Low, df.Close, dates=df.index, direction='decreasing', marker=Marker(color='rgb(128, 128, 128)'), line=Line(color='rgb(128, 128, 128)')) # Initialize the figure fig = fig_increasing # Add decreasing data with .extend() fig['data'].extend(fig_decreasing['data']) py.iplot(fig, filename='finance/aapl-candlestick-custom', validate=False) ``` Example 4: Candlestick chart with datetime objects ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF from datetime import datetime # Add data open_data = [33.0, 33.3, 33.5, 33.0, 34.1] high_data = [33.1, 33.3, 33.6, 33.2, 34.8] low_data = [32.7, 32.7, 32.8, 32.6, 32.8] close_data = [33.0, 32.9, 33.3, 33.1, 33.1] dates = [datetime(year=2013, month=10, day=10), datetime(year=2013, month=11, day=10), datetime(year=2013, month=12, day=10), datetime(year=2014, month=1, day=10), datetime(year=2014, month=2, day=10)] # Create ohlc fig = FF.create_candlestick(open_data, high_data, low_data, close_data, dates=dates) py.iplot(fig, filename='finance/simple-candlestick', validate=False) ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs if dates is not None: FigureFactory._validate_equal_length(open, high, low, close, dates) else: FigureFactory._validate_equal_length(open, high, low, close) FigureFactory._validate_ohlc(open, high, low, close, direction, **kwargs) if direction is 'increasing': candle_incr_data = FigureFactory._make_increasing_candle( open, high, low, close, dates, **kwargs) data = candle_incr_data elif direction is 'decreasing': candle_decr_data = FigureFactory._make_decreasing_candle( open, high, low, close, dates, **kwargs) data = candle_decr_data else: candle_incr_data = FigureFactory._make_increasing_candle( open, high, low, close, dates, **kwargs) candle_decr_data = FigureFactory._make_decreasing_candle( open, high, low, close, dates, **kwargs) data = candle_incr_data + candle_decr_data layout = graph_objs.Layout() return graph_objs.Figure(data=data, layout=layout) @staticmethod def create_distplot(hist_data, group_labels, bin_size=1., curve_type='kde', colors=[], rug_text=[], show_hist=True, show_curve=True, show_rug=True): """ BETA function that creates a distplot similar to seaborn.distplot The distplot can be composed of all or any combination of the following 3 components: (1) histogram, (2) curve: (a) kernal density estimation or (b) normal curve, and (3) rug plot. Additionally, multiple distplots (from multiple datasets) can be created in the same plot. :param (list[list]) hist_data: Use list of lists to plot multiple data sets on the same plot. :param (list[str]) group_labels: Names for each data set. :param (float) bin_size: Size of histogram bins. Default = 1. :param (str) curve_type: 'kde' or 'normal'. Default = 'kde' :param (bool) show_hist: Add histogram to distplot? Default = True :param (bool) show_curve: Add curve to distplot? Default = True :param (bool) show_rug: Add rug to distplot? Default = True :param (list[str]) colors: Colors for traces. :param (list[list]) rug_text: Hovertext values for rug_plot, :return (dict): Representation of a distplot figure. Example 1: Simple distplot of 1 data set ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF hist_data = [[1.1, 1.1, 2.5, 3.0, 3.5, 3.5, 4.1, 4.4, 4.5, 4.5, 5.0, 5.0, 5.2, 5.5, 5.5, 5.5, 5.5, 5.5, 6.1, 7.0]] group_labels = ['distplot example'] fig = FF.create_distplot(hist_data, group_labels) url = py.plot(fig, filename='Simple distplot', validate=False) ``` Example 2: Two data sets and added rug text ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF # Add histogram data hist1_x = [0.8, 1.2, 0.2, 0.6, 1.6, -0.9, -0.07, 1.95, 0.9, -0.2, -0.5, 0.3, 0.4, -0.37, 0.6] hist2_x = [0.8, 1.5, 1.5, 0.6, 0.59, 1.0, 0.8, 1.7, 0.5, 0.8, -0.3, 1.2, 0.56, 0.3, 2.2] # Group data together hist_data = [hist1_x, hist2_x] group_labels = ['2012', '2013'] # Add text rug_text_1 = ['a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h1', 'i1', 'j1', 'k1', 'l1', 'm1', 'n1', 'o1'] rug_text_2 = ['a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2', 'i2', 'j2', 'k2', 'l2', 'm2', 'n2', 'o2'] # Group text together rug_text_all = [rug_text_1, rug_text_2] # Create distplot fig = FF.create_distplot( hist_data, group_labels, rug_text=rug_text_all, bin_size=.2) # Add title fig['layout'].update(title='Dist Plot') # Plot! url = py.plot(fig, filename='Distplot with rug text', validate=False) ``` Example 3: Plot with normal curve and hide rug plot ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np x1 = np.random.randn(190) x2 = np.random.randn(200)+1 x3 = np.random.randn(200)-1 x4 = np.random.randn(210)+2 hist_data = [x1, x2, x3, x4] group_labels = ['2012', '2013', '2014', '2015'] fig = FF.create_distplot( hist_data, group_labels, curve_type='normal', show_rug=False, bin_size=.4) url = py.plot(fig, filename='hist and normal curve', validate=False) Example 4: Distplot with Pandas ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np import pandas as pd df = pd.DataFrame({'2012': np.random.randn(200), '2013': np.random.randn(200)+1}) py.iplot(FF.create_distplot([df[c] for c in df.columns], df.columns), filename='examples/distplot with pandas', validate=False) ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs FigureFactory._validate_distplot(hist_data, curve_type) FigureFactory._validate_equal_length(hist_data, group_labels) hist = _Distplot( hist_data, group_labels, bin_size, curve_type, colors, rug_text, show_hist, show_curve).make_hist() if curve_type == 'normal': curve = _Distplot( hist_data, group_labels, bin_size, curve_type, colors, rug_text, show_hist, show_curve).make_normal() else: curve = _Distplot( hist_data, group_labels, bin_size, curve_type, colors, rug_text, show_hist, show_curve).make_kde() rug = _Distplot( hist_data, group_labels, bin_size, curve_type, colors, rug_text, show_hist, show_curve).make_rug() data = [] if show_hist: data.append(hist) if show_curve: data.append(curve) if show_rug: data.append(rug) layout = graph_objs.Layout( barmode='overlay', hovermode='closest', legend=dict(traceorder='reversed'), xaxis1=dict(domain=[0.0, 1.0], anchor='y2', zeroline=False), yaxis1=dict(domain=[0.35, 1], anchor='free', position=0.0), yaxis2=dict(domain=[0, 0.25], anchor='x1', dtick=1, showticklabels=False)) else: layout = graph_objs.Layout( barmode='overlay', hovermode='closest', legend=dict(traceorder='reversed'), xaxis1=dict(domain=[0.0, 1.0], anchor='y2', zeroline=False), yaxis1=dict(domain=[0., 1], anchor='free', position=0.0)) data = sum(data, []) return graph_objs.Figure(data=data, layout=layout) @staticmethod def create_dendrogram(X, orientation="bottom", labels=None, colorscale=None): """ BETA function that returns a dendrogram Plotly figure object. :param (ndarray) X: Matrix of observations as array of arrays :param (str) orientation: 'top', 'right', 'bottom', or 'left' :param (list) labels: List of axis category labels(observation labels) :param (list) colorscale: Optional colorscale for dendrogram tree clusters Example 1: Simple bottom oriented dendrogram ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np X = np.random.rand(10,10) dendro = FF.create_dendrogram(X) plot_url = py.plot(dendro, filename='simple-dendrogram') ``` Example 2: Dendrogram to put on the left of the heatmap ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np X = np.random.rand(5,5) names = ['Jack', 'Oxana', 'John', 'Chelsea', 'Mark'] dendro = FF.create_dendrogram(X, orientation='right', labels=names) dendro['layout'].update({'width':700, 'height':500}) py.iplot(dendro, filename='vertical-dendrogram') ``` Example 3: Dendrogram with Pandas ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import numpy as np import pandas as pd Index= ['A','B','C','D','E','F','G','H','I','J'] df = pd.DataFrame(abs(np.random.randn(10, 10)), index=Index) fig = FF.create_dendrogram(df, labels=Index) url = py.plot(fig, filename='pandas-dendrogram') ``` """ dependencies = (_scipy_imported and _scipy__spatial_imported and _scipy__cluster__hierarchy_imported) if dependencies is False: raise ImportError("FigureFactory.create_dendrogram requires scipy, \ scipy.spatial and scipy.hierarchy") s = X.shape if len(s) != 2: exceptions.PlotlyError("X should be 2-dimensional array.") dendrogram = _Dendrogram(X, orientation, labels, colorscale) return {'layout': dendrogram.layout, 'data': dendrogram.data} @staticmethod def create_annotated_heatmap(z, x=None, y=None, annotation_text=None, colorscale='RdBu', font_colors=None, showscale=False, reversescale=False, **kwargs): """ BETA function that creates annotated heatmaps This function adds annotations to each cell of the heatmap. :param (list[list]|ndarray) z: z matrix to create heatmap. :param (list) x: x axis labels. :param (list) y: y axis labels. :param (list[list]|ndarray) annotation_text: Text strings for annotations. Should have the same dimensions as the z matrix. If no text is added, the values of the z matrix are annotated. Default = z matrix values. :param (list|str) colorscale: heatmap colorscale. :param (list) font_colors: List of two color strings: [min_text_color, max_text_color] where min_text_color is applied to annotations for heatmap values < (max_value - min_value)/2. If font_colors is not defined, the colors are defined logically as black or white depending on the heatmap's colorscale. :param (bool) showscale: Display colorscale. Default = False :param kwargs: kwargs passed through plotly.graph_objs.Heatmap. These kwargs describe other attributes about the annotated Heatmap trace such as the colorscale. For more information on valid kwargs call help(plotly.graph_objs.Heatmap) Example 1: Simple annotated heatmap with default configuration ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF z = [[0.300000, 0.00000, 0.65, 0.300000], [1, 0.100005, 0.45, 0.4300], [0.300000, 0.00000, 0.65, 0.300000], [1, 0.100005, 0.45, 0.00000]] figure = FF.create_annotated_heatmap(z) py.iplot(figure) ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs # Avoiding mutables in the call signature font_colors = font_colors if font_colors is not None else [] FigureFactory._validate_annotated_heatmap(z, x, y, annotation_text) annotations = _AnnotatedHeatmap(z, x, y, annotation_text, colorscale, font_colors, reversescale, **kwargs).make_annotations() if x or y: trace = dict(type='heatmap', z=z, x=x, y=y, colorscale=colorscale, showscale=showscale, **kwargs) layout = dict(annotations=annotations, xaxis=dict(ticks='', dtick=1, side='top', gridcolor='rgb(0, 0, 0)'), yaxis=dict(ticks='', dtick=1, ticksuffix=' ')) else: trace = dict(type='heatmap', z=z, colorscale=colorscale, showscale=showscale, **kwargs) layout = dict(annotations=annotations, xaxis=dict(ticks='', side='top', gridcolor='rgb(0, 0, 0)', showticklabels=False), yaxis=dict(ticks='', ticksuffix=' ', showticklabels=False)) data = [trace] return graph_objs.Figure(data=data, layout=layout) @staticmethod def create_table(table_text, colorscale=None, font_colors=None, index=False, index_title='', annotation_offset=.45, height_constant=30, hoverinfo='none', **kwargs): """ BETA function that creates data tables :param (pandas.Dataframe | list[list]) text: data for table. :param (str|list[list]) colorscale: Colorscale for table where the color at value 0 is the header color, .5 is the first table color and 1 is the second table color. (Set .5 and 1 to avoid the striped table effect). Default=[[0, '#66b2ff'], [.5, '#d9d9d9'], [1, '#ffffff']] :param (list) font_colors: Color for fonts in table. Can be a single color, three colors, or a color for each row in the table. Default=['#000000'] (black text for the entire table) :param (int) height_constant: Constant multiplied by # of rows to create table height. Default=30. :param (bool) index: Create (header-colored) index column index from Pandas dataframe or list[0] for each list in text. Default=False. :param (string) index_title: Title for index column. Default=''. :param kwargs: kwargs passed through plotly.graph_objs.Heatmap. These kwargs describe other attributes about the annotated Heatmap trace such as the colorscale. For more information on valid kwargs call help(plotly.graph_objs.Heatmap) Example 1: Simple Plotly Table ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF text = [['Country', 'Year', 'Population'], ['US', 2000, 282200000], ['Canada', 2000, 27790000], ['US', 2010, 309000000], ['Canada', 2010, 34000000]] table = FF.create_table(text) py.iplot(table) ``` Example 2: Table with Custom Coloring ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF text = [['Country', 'Year', 'Population'], ['US', 2000, 282200000], ['Canada', 2000, 27790000], ['US', 2010, 309000000], ['Canada', 2010, 34000000]] table = FF.create_table(text, colorscale=[[0, '#000000'], [.5, '#80beff'], [1, '#cce5ff']], font_colors=['#ffffff', '#000000', '#000000']) py.iplot(table) ``` Example 3: Simple Plotly Table with Pandas ``` import plotly.plotly as py from plotly.tools import FigureFactory as FF import pandas as pd df = pd.read_csv('http://www.stat.ubc.ca/~jenny/notOcto/STAT545A/examples/gapminder/data/gapminderDataFiveYear.txt', sep='\t') df_p = df[0:25] table_simple = FF.create_table(df_p) py.iplot(table_simple) ``` """ # TODO: protected until #282 from plotly.graph_objs import graph_objs # Avoiding mutables in the call signature colorscale = \ colorscale if colorscale is not None else [[0, '#00083e'], [.5, '#ededee'], [1, '#ffffff']] font_colors = font_colors if font_colors is not None else ['#ffffff', '#000000', '#000000'] FigureFactory._validate_table(table_text, font_colors) table_matrix = _Table(table_text, colorscale, font_colors, index, index_title, annotation_offset, **kwargs).get_table_matrix() annotations = _Table(table_text, colorscale, font_colors, index, index_title, annotation_offset, **kwargs).make_table_annotations() trace = dict(type='heatmap', z=table_matrix, opacity=.75, colorscale=colorscale, showscale=False, hoverinfo=hoverinfo, **kwargs) data = [trace] layout = dict(annotations=annotations, height=len(table_matrix)*height_constant + 50, margin=dict(t=0, b=0, r=0, l=0), yaxis=dict(autorange='reversed', zeroline=False, gridwidth=2, ticks='', dtick=1, tick0=.5, showticklabels=False), xaxis=dict(zeroline=False, gridwidth=2, ticks='', dtick=1, tick0=-0.5, showticklabels=False)) return graph_objs.Figure(data=data, layout=layout) class _Quiver(FigureFactory): """ Refer to FigureFactory.create_quiver() for docstring """ def __init__(self, x, y, u, v, scale, arrow_scale, angle, **kwargs): try: x = FigureFactory._flatten(x) except exceptions.PlotlyError: pass try: y = FigureFactory._flatten(y) except exceptions.PlotlyError: pass try: u = FigureFactory._flatten(u) except exceptions.PlotlyError: pass try: v = FigureFactory._flatten(v) except exceptions.PlotlyError: pass self.x = x self.y = y self.u = u self.v = v self.scale = scale self.arrow_scale = arrow_scale self.angle = angle self.end_x = [] self.end_y = [] self.scale_uv() barb_x, barb_y = self.get_barbs() arrow_x, arrow_y = self.get_quiver_arrows() def scale_uv(self): """ Scales u and v to avoid overlap of the arrows. u and v are added to x and y to get the endpoints of the arrows so a smaller scale value will result in less overlap of arrows. """ self.u = [i * self.scale for i in self.u] self.v = [i * self.scale for i in self.v] def get_barbs(self): """ Creates x and y startpoint and endpoint pairs After finding the endpoint of each barb this zips startpoint and endpoint pairs to create 2 lists: x_values for barbs and y values for barbs :rtype: (list, list) barb_x, barb_y: list of startpoint and endpoint x_value pairs separated by a None to create the barb of the arrow, and list of startpoint and endpoint y_value pairs separated by a None to create the barb of the arrow. """ self.end_x = [i + j for i, j in zip(self.x, self.u)] self.end_y = [i + j for i, j in zip(self.y, self.v)] empty = [None] * len(self.x) barb_x = FigureFactory._flatten(zip(self.x, self.end_x, empty)) barb_y = FigureFactory._flatten(zip(self.y, self.end_y, empty)) return barb_x, barb_y def get_quiver_arrows(self): """ Creates lists of x and y values to plot the arrows Gets length of each barb then calculates the length of each side of the arrow. Gets angle of barb and applies angle to each side of the arrowhead. Next uses arrow_scale to scale the length of arrowhead and creates x and y values for arrowhead point1 and point2. Finally x and y values for point1, endpoint and point2s for each arrowhead are separated by a None and zipped to create lists of x and y values for the arrows. :rtype: (list, list) arrow_x, arrow_y: list of point1, endpoint, point2 x_values separated by a None to create the arrowhead and list of point1, endpoint, point2 y_values separated by a None to create the barb of the arrow. """ dif_x = [i - j for i, j in zip(self.end_x, self.x)] dif_y = [i - j for i, j in zip(self.end_y, self.y)] # Get barb lengths(default arrow length = 30% barb length) barb_len = [None] * len(self.x) for index in range(len(barb_len)): barb_len[index] = math.hypot(dif_x[index], dif_y[index]) # Make arrow lengths arrow_len = [None] * len(self.x) arrow_len = [i * self.arrow_scale for i in barb_len] # Get barb angles barb_ang = [None] * len(self.x) for index in range(len(barb_ang)): barb_ang[index] = math.atan2(dif_y[index], dif_x[index]) # Set angles to create arrow ang1 = [i + self.angle for i in barb_ang] ang2 = [i - self.angle for i in barb_ang] cos_ang1 = [None] * len(ang1) for index in range(len(ang1)): cos_ang1[index] = math.cos(ang1[index]) seg1_x = [i * j for i, j in zip(arrow_len, cos_ang1)] sin_ang1 = [None] * len(ang1) for index in range(len(ang1)): sin_ang1[index] = math.sin(ang1[index]) seg1_y = [i * j for i, j in zip(arrow_len, sin_ang1)] cos_ang2 = [None] * len(ang2) for index in range(len(ang2)): cos_ang2[index] = math.cos(ang2[index]) seg2_x = [i * j for i, j in zip(arrow_len, cos_ang2)] sin_ang2 = [None] * len(ang2) for index in range(len(ang2)): sin_ang2[index] = math.sin(ang2[index]) seg2_y = [i * j for i, j in zip(arrow_len, sin_ang2)] # Set coordinates to create arrow for index in range(len(self.end_x)): point1_x = [i - j for i, j in zip(self.end_x, seg1_x)] point1_y = [i - j for i, j in zip(self.end_y, seg1_y)] point2_x = [i - j for i, j in zip(self.end_x, seg2_x)] point2_y = [i - j for i, j in zip(self.end_y, seg2_y)] # Combine lists to create arrow empty = [None] * len(self.end_x) arrow_x = FigureFactory._flatten(zip(point1_x, self.end_x, point2_x, empty)) arrow_y = FigureFactory._flatten(zip(point1_y, self.end_y, point2_y, empty)) return arrow_x, arrow_y class _Streamline(FigureFactory): """ Refer to FigureFactory.create_streamline() for docstring """ def __init__(self, x, y, u, v, density, angle, arrow_scale, **kwargs): self.x = np.array(x) self.y = np.array(y) self.u = np.array(u) self.v = np.array(v) self.angle = angle self.arrow_scale = arrow_scale self.density = int(30 * density) # Scale similarly to other functions self.delta_x = self.x[1] - self.x[0] self.delta_y = self.y[1] - self.y[0] self.val_x = self.x self.val_y = self.y # Set up spacing self.blank = np.zeros((self.density, self.density)) self.spacing_x = len(self.x) / float(self.density - 1) self.spacing_y = len(self.y) / float(self.density - 1) self.trajectories = [] # Rescale speed onto axes-coordinates self.u = self.u / (self.x[-1] - self.x[0]) self.v = self.v / (self.y[-1] - self.y[0]) self.speed = np.sqrt(self.u ** 2 + self.v ** 2) # Rescale u and v for integrations. self.u *= len(self.x) self.v *= len(self.y) self.st_x = [] self.st_y = [] self.get_streamlines() streamline_x, streamline_y = self.sum_streamlines() arrows_x, arrows_y = self.get_streamline_arrows() def blank_pos(self, xi, yi): """ Set up positions for trajectories to be used with rk4 function. """ return (int((xi / self.spacing_x) + 0.5), int((yi / self.spacing_y) + 0.5)) def value_at(self, a, xi, yi): """ Set up for RK4 function, based on Bokeh's streamline code """ if isinstance(xi, np.ndarray): self.x = xi.astype(np.int) self.y = yi.astype(np.int) else: self.val_x = np.int(xi) self.val_y = np.int(yi) a00 = a[self.val_y, self.val_x] a01 = a[self.val_y, self.val_x + 1] a10 = a[self.val_y + 1, self.val_x] a11 = a[self.val_y + 1, self.val_x + 1] xt = xi - self.val_x yt = yi - self.val_y a0 = a00 * (1 - xt) + a01 * xt a1 = a10 * (1 - xt) + a11 * xt return a0 * (1 - yt) + a1 * yt def rk4_integrate(self, x0, y0): """ RK4 forward and back trajectories from the initial conditions. Adapted from Bokeh's streamline -uses Runge-Kutta method to fill x and y trajectories then checks length of traj (s in units of axes) """ def f(xi, yi): dt_ds = 1. / self.value_at(self.speed, xi, yi) ui = self.value_at(self.u, xi, yi) vi = self.value_at(self.v, xi, yi) return ui * dt_ds, vi * dt_ds def g(xi, yi): dt_ds = 1. / self.value_at(self.speed, xi, yi) ui = self.value_at(self.u, xi, yi) vi = self.value_at(self.v, xi, yi) return -ui * dt_ds, -vi * dt_ds check = lambda xi, yi: (0 <= xi < len(self.x) - 1 and 0 <= yi < len(self.y) - 1) xb_changes = [] yb_changes = [] def rk4(x0, y0, f): ds = 0.01 stotal = 0 xi = x0 yi = y0 xb, yb = self.blank_pos(xi, yi) xf_traj = [] yf_traj = [] while check(xi, yi): xf_traj.append(xi) yf_traj.append(yi) try: k1x, k1y = f(xi, yi) k2x, k2y = f(xi + .5 * ds * k1x, yi + .5 * ds * k1y) k3x, k3y = f(xi + .5 * ds * k2x, yi + .5 * ds * k2y) k4x, k4y = f(xi + ds * k3x, yi + ds * k3y) except IndexError: break xi += ds * (k1x + 2 * k2x + 2 * k3x + k4x) / 6. yi += ds * (k1y + 2 * k2y + 2 * k3y + k4y) / 6. if not check(xi, yi): break stotal += ds new_xb, new_yb = self.blank_pos(xi, yi) if new_xb != xb or new_yb != yb: if self.blank[new_yb, new_xb] == 0: self.blank[new_yb, new_xb] = 1 xb_changes.append(new_xb) yb_changes.append(new_yb) xb = new_xb yb = new_yb else: break if stotal > 2: break return stotal, xf_traj, yf_traj sf, xf_traj, yf_traj = rk4(x0, y0, f) sb, xb_traj, yb_traj = rk4(x0, y0, g) stotal = sf + sb x_traj = xb_traj[::-1] + xf_traj[1:] y_traj = yb_traj[::-1] + yf_traj[1:] if len(x_traj) < 1: return None if stotal > .2: initxb, inityb = self.blank_pos(x0, y0) self.blank[inityb, initxb] = 1 return x_traj, y_traj else: for xb, yb in zip(xb_changes, yb_changes): self.blank[yb, xb] = 0 return None def traj(self, xb, yb): """ Integrate trajectories :param (int) xb: results of passing xi through self.blank_pos :param (int) xy: results of passing yi through self.blank_pos Calculate each trajectory based on rk4 integrate method. """ if xb < 0 or xb >= self.density or yb < 0 or yb >= self.density: return if self.blank[yb, xb] == 0: t = self.rk4_integrate(xb * self.spacing_x, yb * self.spacing_y) if t is not None: self.trajectories.append(t) def get_streamlines(self): """ Get streamlines by building trajectory set. """ for indent in range(self.density // 2): for xi in range(self.density - 2 * indent): self.traj(xi + indent, indent) self.traj(xi + indent, self.density - 1 - indent) self.traj(indent, xi + indent) self.traj(self.density - 1 - indent, xi + indent) self.st_x = [np.array(t[0]) * self.delta_x + self.x[0] for t in self.trajectories] self.st_y = [np.array(t[1]) * self.delta_y + self.y[0] for t in self.trajectories] for index in range(len(self.st_x)): self.st_x[index] = self.st_x[index].tolist() self.st_x[index].append(np.nan) for index in range(len(self.st_y)): self.st_y[index] = self.st_y[index].tolist() self.st_y[index].append(np.nan) def get_streamline_arrows(self): """ Makes an arrow for each streamline. Gets angle of streamline at 1/3 mark and creates arrow coordinates based off of user defined angle and arrow_scale. :param (array) st_x: x-values for all streamlines :param (array) st_y: y-values for all streamlines :param (angle in radians) angle: angle of arrowhead. Default = pi/9 :param (float in [0,1]) arrow_scale: value to scale length of arrowhead Default = .09 :rtype (list, list) arrows_x: x-values to create arrowhead and arrows_y: y-values to create arrowhead """ arrow_end_x = np.empty((len(self.st_x))) arrow_end_y = np.empty((len(self.st_y))) arrow_start_x = np.empty((len(self.st_x))) arrow_start_y = np.empty((len(self.st_y))) for index in range(len(self.st_x)): arrow_end_x[index] = (self.st_x[index] [int(len(self.st_x[index]) / 3)]) arrow_start_x[index] = (self.st_x[index] [(int(len(self.st_x[index]) / 3)) - 1]) arrow_end_y[index] = (self.st_y[index] [int(len(self.st_y[index]) / 3)]) arrow_start_y[index] = (self.st_y[index] [(int(len(self.st_y[index]) / 3)) - 1]) dif_x = arrow_end_x - arrow_start_x dif_y = arrow_end_y - arrow_start_y streamline_ang = np.arctan(dif_y / dif_x) ang1 = streamline_ang + (self.angle) ang2 = streamline_ang - (self.angle) seg1_x = np.cos(ang1) * self.arrow_scale seg1_y = np.sin(ang1) * self.arrow_scale seg2_x = np.cos(ang2) * self.arrow_scale seg2_y = np.sin(ang2) * self.arrow_scale point1_x = np.empty((len(dif_x))) point1_y = np.empty((len(dif_y))) point2_x = np.empty((len(dif_x))) point2_y = np.empty((len(dif_y))) for index in range(len(dif_x)): if dif_x[index] >= 0: point1_x[index] = arrow_end_x[index] - seg1_x[index] point1_y[index] = arrow_end_y[index] - seg1_y[index] point2_x[index] = arrow_end_x[index] - seg2_x[index] point2_y[index] = arrow_end_y[index] - seg2_y[index] else: point1_x[index] = arrow_end_x[index] + seg1_x[index] point1_y[index] = arrow_end_y[index] + seg1_y[index] point2_x[index] = arrow_end_x[index] + seg2_x[index] point2_y[index] = arrow_end_y[index] + seg2_y[index] space = np.empty((len(point1_x))) space[:] = np.nan # Combine arrays into matrix arrows_x = np.matrix([point1_x, arrow_end_x, point2_x, space]) arrows_x = np.array(arrows_x) arrows_x = arrows_x.flatten('F') arrows_x = arrows_x.tolist() # Combine arrays into matrix arrows_y = np.matrix([point1_y, arrow_end_y, point2_y, space]) arrows_y = np.array(arrows_y) arrows_y = arrows_y.flatten('F') arrows_y = arrows_y.tolist() return arrows_x, arrows_y def sum_streamlines(self): """ Makes all streamlines readable as a single trace. :rtype (list, list): streamline_x: all x values for each streamline combined into single list and streamline_y: all y values for each streamline combined into single list """ streamline_x = sum(self.st_x, []) streamline_y = sum(self.st_y, []) return streamline_x, streamline_y class _OHLC(FigureFactory): """ Refer to FigureFactory.create_ohlc_increase() for docstring. """ def __init__(self, open, high, low, close, dates, **kwargs): self.open = open self.high = high self.low = low self.close = close self.empty = [None] * len(open) self.dates = dates self.all_x = [] self.all_y = [] self.increase_x = [] self.increase_y = [] self.decrease_x = [] self.decrease_y = [] self.get_all_xy() self.separate_increase_decrease() def get_all_xy(self): """ Zip data to create OHLC shape OHLC shape: low to high vertical bar with horizontal branches for open and close values. If dates were added, the smallest date difference is calculated and multiplied by .2 to get the length of the open and close branches. If no date data was provided, the x-axis is a list of integers and the length of the open and close branches is .2. """ self.all_y = list(zip(self.open, self.open, self.high, self.low, self.close, self.close, self.empty)) if self.dates is not None: date_dif = [] for i in range(len(self.dates) - 1): date_dif.append(self.dates[i + 1] - self.dates[i]) date_dif_min = (min(date_dif)) / 5 self.all_x = [[x - date_dif_min, x, x, x, x, x + date_dif_min, None] for x in self.dates] else: self.all_x = [[x - .2, x, x, x, x, x + .2, None] for x in range(len(self.open))] def separate_increase_decrease(self): """ Separate data into two groups: increase and decrease (1) Increase, where close > open and (2) Decrease, where close <= open """ for index in range(len(self.open)): if self.close[index] is None: pass elif self.close[index] > self.open[index]: self.increase_x.append(self.all_x[index]) self.increase_y.append(self.all_y[index]) else: self.decrease_x.append(self.all_x[index]) self.decrease_y.append(self.all_y[index]) def get_increase(self): """ Flatten increase data and get increase text :rtype (list, list, list): flat_increase_x: x-values for the increasing trace, flat_increase_y: y=values for the increasing trace and text_increase: hovertext for the increasing trace """ flat_increase_x = FigureFactory._flatten(self.increase_x) flat_increase_y = FigureFactory._flatten(self.increase_y) text_increase = (("Open", "Open", "High", "Low", "Close", "Close", '') * (len(self.increase_x))) return flat_increase_x, flat_increase_y, text_increase def get_decrease(self): """ Flatten decrease data and get decrease text :rtype (list, list, list): flat_decrease_x: x-values for the decreasing trace, flat_decrease_y: y=values for the decreasing trace and text_decrease: hovertext for the decreasing trace """ flat_decrease_x = FigureFactory._flatten(self.decrease_x) flat_decrease_y = FigureFactory._flatten(self.decrease_y) text_decrease = (("Open", "Open", "High", "Low", "Close", "Close", '') * (len(self.decrease_x))) return flat_decrease_x, flat_decrease_y, text_decrease class _Candlestick(FigureFactory): """ Refer to FigureFactory.create_candlestick() for docstring. """ def __init__(self, open, high, low, close, dates, **kwargs): self.open = open self.high = high self.low = low self.close = close if dates is not None: self.x = dates else: self.x = [x for x in range(len(self.open))] self.get_candle_increase() def get_candle_increase(self): """ Separate increasing data from decreasing data. The data is increasing when close value > open value and decreasing when the close value <= open value. """ increase_y = [] increase_x = [] for index in range(len(self.open)): if self.close[index] > self.open[index]: increase_y.append(self.low[index]) increase_y.append(self.open[index]) increase_y.append(self.close[index]) increase_y.append(self.close[index]) increase_y.append(self.close[index]) increase_y.append(self.high[index]) increase_x.append(self.x[index]) increase_x = [[x, x, x, x, x, x] for x in increase_x] increase_x = FigureFactory._flatten(increase_x) return increase_x, increase_y def get_candle_decrease(self): """ Separate increasing data from decreasing data. The data is increasing when close value > open value and decreasing when the close value <= open value. """ decrease_y = [] decrease_x = [] for index in range(len(self.open)): if self.close[index] <= self.open[index]: decrease_y.append(self.low[index]) decrease_y.append(self.open[index]) decrease_y.append(self.close[index]) decrease_y.append(self.close[index]) decrease_y.append(self.close[index]) decrease_y.append(self.high[index]) decrease_x.append(self.x[index]) decrease_x = [[x, x, x, x, x, x] for x in decrease_x] decrease_x = FigureFactory._flatten(decrease_x) return decrease_x, decrease_y class _Distplot(FigureFactory): """ Refer to TraceFactory.create_distplot() for docstring """ def __init__(self, hist_data, group_labels, bin_size, curve_type, colors, rug_text, show_hist, show_curve): self.hist_data = hist_data self.group_labels = group_labels self.bin_size = bin_size self.show_hist = show_hist self.show_curve = show_curve self.trace_number = len(hist_data) if rug_text: self.rug_text = rug_text else: self.rug_text = [None] * self.trace_number self.start = [] self.end = [] if colors: self.colors = colors else: self.colors = [ "rgb(31, 119, 180)", "rgb(255, 127, 14)", "rgb(44, 160, 44)", "rgb(214, 39, 40)", "rgb(148, 103, 189)", "rgb(140, 86, 75)", "rgb(227, 119, 194)", "rgb(127, 127, 127)", "rgb(188, 189, 34)", "rgb(23, 190, 207)"] self.curve_x = [None] * self.trace_number self.curve_y = [None] * self.trace_number for trace in self.hist_data: self.start.append(min(trace) * 1.) self.end.append(max(trace) * 1.) def make_hist(self): """ Makes the histogram(s) for FigureFactory.create_distplot(). :rtype (list) hist: list of histogram representations """ hist = [None] * self.trace_number for index in range(self.trace_number): hist[index] = dict(type='histogram', x=self.hist_data[index], xaxis='x1', yaxis='y1', histnorm='probability', name=self.group_labels[index], legendgroup=self.group_labels[index], marker=dict(color=self.colors[index]), autobinx=False, xbins=dict(start=self.start[index], end=self.end[index], size=self.bin_size), opacity=.7) return hist def make_kde(self): """ Makes the kernal density estimation(s) for create_distplot(). This is called when curve_type = 'kde' in create_distplot(). :rtype (list) curve: list of kde representations """ curve = [None] * self.trace_number for index in range(self.trace_number): self.curve_x[index] = [self.start[index] + x * (self.end[index] - self.start[index]) / 500 for x in range(500)] self.curve_y[index] = (scipy.stats.gaussian_kde (self.hist_data[index]) (self.curve_x[index])) self.curve_y[index] *= self.bin_size for index in range(self.trace_number): curve[index] = dict(type='scatter', x=self.curve_x[index], y=self.curve_y[index], xaxis='x1', yaxis='y1', mode='lines', name=self.group_labels[index], legendgroup=self.group_labels[index], showlegend=False if self.show_hist else True, marker=dict(color=self.colors[index])) return curve def make_normal(self): """ Makes the normal curve(s) for create_distplot(). This is called when curve_type = 'normal' in create_distplot(). :rtype (list) curve: list of normal curve representations """ curve = [None] * self.trace_number mean = [None] * self.trace_number sd = [None] * self.trace_number for index in range(self.trace_number): mean[index], sd[index] = (scipy.stats.norm.fit (self.hist_data[index])) self.curve_x[index] = [self.start[index] + x * (self.end[index] - self.start[index]) / 500 for x in range(500)] self.curve_y[index] = scipy.stats.norm.pdf( self.curve_x[index], loc=mean[index], scale=sd[index]) self.curve_y[index] *= self.bin_size for index in range(self.trace_number): curve[index] = dict(type='scatter', x=self.curve_x[index], y=self.curve_y[index], xaxis='x1', yaxis='y1', mode='lines', name=self.group_labels[index], legendgroup=self.group_labels[index], showlegend=False if self.show_hist else True, marker=dict(color=self.colors[index])) return curve def make_rug(self): """ Makes the rug plot(s) for create_distplot(). :rtype (list) rug: list of rug plot representations """ rug = [None] * self.trace_number for index in range(self.trace_number): rug[index] = dict(type='scatter', x=self.hist_data[index], y=([self.group_labels[index]] * len(self.hist_data[index])), xaxis='x1', yaxis='y2', mode='markers', name=self.group_labels[index], legendgroup=self.group_labels[index], showlegend=(False if self.show_hist or self.show_curve else True), text=self.rug_text[index], marker=dict(color=self.colors[index], symbol='line-ns-open')) return rug class _Dendrogram(FigureFactory): """Refer to FigureFactory.create_dendrogram() for docstring.""" def __init__(self, X, orientation='bottom', labels=None, colorscale=None, width="100%", height="100%", xaxis='xaxis', yaxis='yaxis'): # TODO: protected until #282 from plotly.graph_objs import graph_objs self.orientation = orientation self.labels = labels self.xaxis = xaxis self.yaxis = yaxis self.data = [] self.leaves = [] self.sign = {self.xaxis: 1, self.yaxis: 1} self.layout = {self.xaxis: {}, self.yaxis: {}} if self.orientation in ['left', 'bottom']: self.sign[self.xaxis] = 1 else: self.sign[self.xaxis] = -1 if self.orientation in ['right', 'bottom']: self.sign[self.yaxis] = 1 else: self.sign[self.yaxis] = -1 (dd_traces, xvals, yvals, ordered_labels, leaves) = self.get_dendrogram_traces(X, colorscale) self.labels = ordered_labels self.leaves = leaves yvals_flat = yvals.flatten() xvals_flat = xvals.flatten() self.zero_vals = [] for i in range(len(yvals_flat)): if yvals_flat[i] == 0.0 and xvals_flat[i] not in self.zero_vals: self.zero_vals.append(xvals_flat[i]) self.zero_vals.sort() self.layout = self.set_figure_layout(width, height) self.data = graph_objs.Data(dd_traces) def get_color_dict(self, colorscale): """ Returns colorscale used for dendrogram tree clusters. :param (list) colorscale: Colors to use for the plot in rgb format. :rtype (dict): A dict of default colors mapped to the user colorscale. """ # These are the color codes returned for dendrograms # We're replacing them with nicer colors d = {'r': 'red', 'g': 'green', 'b': 'blue', 'c': 'cyan', 'm': 'magenta', 'y': 'yellow', 'k': 'black', 'w': 'white'} default_colors = OrderedDict(sorted(d.items(), key=lambda t: t[0])) if colorscale is None: colorscale = [ 'rgb(0,116,217)', # blue 'rgb(35,205,205)', # cyan 'rgb(61,153,112)', # green 'rgb(40,35,35)', # black 'rgb(133,20,75)', # magenta 'rgb(255,65,54)', # red 'rgb(255,255,255)', # white 'rgb(255,220,0)'] # yellow for i in range(len(default_colors.keys())): k = list(default_colors.keys())[i] # PY3 won't index keys if i < len(colorscale): default_colors[k] = colorscale[i] return default_colors def set_axis_layout(self, axis_key): """ Sets and returns default axis object for dendrogram figure. :param (str) axis_key: E.g., 'xaxis', 'xaxis1', 'yaxis', yaxis1', etc. :rtype (dict): An axis_key dictionary with set parameters. """ axis_defaults = { 'type': 'linear', 'ticks': 'outside', 'mirror': 'allticks', 'rangemode': 'tozero', 'showticklabels': True, 'zeroline': False, 'showgrid': False, 'showline': True, } if len(self.labels) != 0: axis_key_labels = self.xaxis if self.orientation in ['left', 'right']: axis_key_labels = self.yaxis if axis_key_labels not in self.layout: self.layout[axis_key_labels] = {} self.layout[axis_key_labels]['tickvals'] = \ [zv*self.sign[axis_key] for zv in self.zero_vals] self.layout[axis_key_labels]['ticktext'] = self.labels self.layout[axis_key_labels]['tickmode'] = 'array' self.layout[axis_key].update(axis_defaults) return self.layout[axis_key] def set_figure_layout(self, width, height): """ Sets and returns default layout object for dendrogram figure. """ self.layout.update({ 'showlegend': False, 'autosize': False, 'hovermode': 'closest', 'width': width, 'height': height }) self.set_axis_layout(self.xaxis) self.set_axis_layout(self.yaxis) return self.layout def get_dendrogram_traces(self, X, colorscale): """ Calculates all the elements needed for plotting a dendrogram. :param (ndarray) X: Matrix of observations as array of arrays :param (list) colorscale: Color scale for dendrogram tree clusters :rtype (tuple): Contains all the traces in the following order: (a) trace_list: List of Plotly trace objects for dendrogram tree (b) icoord: All X points of the dendrogram tree as array of arrays with length 4 (c) dcoord: All Y points of the dendrogram tree as array of arrays with length 4 (d) ordered_labels: leaf labels in the order they are going to appear on the plot (e) P['leaves']: left-to-right traversal of the leaves """ # TODO: protected until #282 from plotly.graph_objs import graph_objs d = scs.distance.pdist(X) Z = sch.linkage(d, method='complete') P = sch.dendrogram(Z, orientation=self.orientation, labels=self.labels, no_plot=True) icoord = scp.array(P['icoord']) dcoord = scp.array(P['dcoord']) ordered_labels = scp.array(P['ivl']) color_list = scp.array(P['color_list']) colors = self.get_color_dict(colorscale) trace_list = [] for i in range(len(icoord)): # xs and ys are arrays of 4 points that make up the '∩' shapes # of the dendrogram tree if self.orientation in ['top', 'bottom']: xs = icoord[i] else: xs = dcoord[i] if self.orientation in ['top', 'bottom']: ys = dcoord[i] else: ys = icoord[i] color_key = color_list[i] trace = graph_objs.Scatter( x=np.multiply(self.sign[self.xaxis], xs), y=np.multiply(self.sign[self.yaxis], ys), mode='lines', marker=graph_objs.Marker(color=colors[color_key]) ) try: x_index = int(self.xaxis[-1]) except ValueError: x_index = '' try: y_index = int(self.yaxis[-1]) except ValueError: y_index = '' trace['xaxis'] = 'x' + x_index trace['yaxis'] = 'y' + y_index trace_list.append(trace) return trace_list, icoord, dcoord, ordered_labels, P['leaves'] class _AnnotatedHeatmap(FigureFactory): """ Refer to TraceFactory.create_annotated_heatmap() for docstring """ def __init__(self, z, x, y, annotation_text, colorscale, font_colors, reversescale, **kwargs): from plotly.graph_objs import graph_objs self.z = z if x: self.x = x else: self.x = range(len(z[0])) if y: self.y = y else: self.y = range(len(z)) if annotation_text is not None: self.annotation_text = annotation_text else: self.annotation_text = self.z self.colorscale = colorscale self.reversescale = reversescale self.font_colors = font_colors def get_text_color(self): """ Get font color for annotations. The annotated heatmap can feature two text colors: min_text_color and max_text_color. The min_text_color is applied to annotations for heatmap values < (max_value - min_value)/2. The user can define these two colors. Otherwise the colors are defined logically as black or white depending on the heatmap's colorscale. :rtype (string, string) min_text_color, max_text_color: text color for annotations for heatmap values < (max_value - min_value)/2 and text color for annotations for heatmap values >= (max_value - min_value)/2 """ # Plotly colorscales ranging from a lighter shade to a darker shade colorscales = ['Greys', 'Greens', 'Blues', 'YIGnBu', 'YIOrRd', 'RdBu', 'Picnic', 'Jet', 'Hot', 'Blackbody', 'Earth', 'Electric', 'Viridis'] # Plotly colorscales ranging from a darker shade to a lighter shade colorscales_reverse = ['Reds'] if self.font_colors: min_text_color = self.font_colors[0] max_text_color = self.font_colors[-1] elif self.colorscale in colorscales and self.reversescale: min_text_color = '#000000' max_text_color = '#FFFFFF' elif self.colorscale in colorscales: min_text_color = '#FFFFFF' max_text_color = '#000000' elif self.colorscale in colorscales_reverse and self.reversescale: min_text_color = '#FFFFFF' max_text_color = '#000000' elif self.colorscale in colorscales_reverse: min_text_color = '#000000' max_text_color = '#FFFFFF' elif isinstance(self.colorscale, list): if 'rgb' in self.colorscale[0][1]: min_col = map(int, self.colorscale[0][1].strip('rgb()').split(',')) max_col = map(int, self.colorscale[-1][1].strip('rgb()').split(',')) elif '#' in self.colorscale[0][1]: min_col = FigureFactory._hex_to_rgb(self.colorscale[0][1]) max_col = FigureFactory._hex_to_rgb(self.colorscale[-1][1]) else: min_col = [255, 255, 255] max_col = [255, 255, 255] if (min_col[0]*0.299 + min_col[1]*0.587 + min_col[2]*0.114) > 186: min_text_color = '#000000' else: min_text_color = '#FFFFFF' if (max_col[0]*0.299 + max_col[1]*0.587 + max_col[2]*0.114) > 186: max_text_color = '#000000' else: max_text_color = '#FFFFFF' else: min_text_color = '#000000' max_text_color = '#000000' return min_text_color, max_text_color def get_z_mid(self): """ Get the mid value of z matrix :rtype (float) z_avg: average val from z matrix """ if _numpy_imported and isinstance(self.z, np.ndarray): z_min = np.amin(self.z) z_max = np.amax(self.z) else: z_min = min(min(self.z)) z_max = max(max(self.z)) z_mid = (z_max+z_min) / 2 return z_mid def make_annotations(self): """ Get annotations for each cell of the heatmap with graph_objs.Annotation :rtype (list[dict]) annotations: list of annotations for each cell of the heatmap """ from plotly.graph_objs import graph_objs min_text_color, max_text_color = _AnnotatedHeatmap.get_text_color(self) z_mid = _AnnotatedHeatmap.get_z_mid(self) annotations = [] for n, row in enumerate(self.z): for m, val in enumerate(row): font_color = min_text_color if val < z_mid else max_text_color annotations.append( graph_objs.Annotation( text=str(self.annotation_text[n][m]), x=self.x[m], y=self.y[n], xref='x1', yref='y1', font=dict(color=font_color), showarrow=False)) return annotations class _Table(FigureFactory): """ Refer to TraceFactory.create_table() for docstring """ def __init__(self, table_text, colorscale, font_colors, index, index_title, annotation_offset, **kwargs): from plotly.graph_objs import graph_objs if _pandas_imported and isinstance(table_text, pd.DataFrame): headers = table_text.columns.tolist() table_text_index = table_text.index.tolist() table_text = table_text.values.tolist() table_text.insert(0, headers) if index: table_text_index.insert(0, index_title) for i in range(len(table_text)): table_text[i].insert(0, table_text_index[i]) self.table_text = table_text self.colorscale = colorscale self.font_colors = font_colors self.index = index self.annotation_offset = annotation_offset self.x = range(len(table_text[0])) self.y = range(len(table_text)) def get_table_matrix(self): """ Create z matrix to make heatmap with striped table coloring :rtype (list[list]) table_matrix: z matrix to make heatmap with striped table coloring. """ header = [0] * len(self.table_text[0]) odd_row = [.5] * len(self.table_text[0]) even_row = [1] * len(self.table_text[0]) table_matrix = [None] * len(self.table_text) table_matrix[0] = header for i in range(1, len(self.table_text), 2): table_matrix[i] = odd_row for i in range(2, len(self.table_text), 2): table_matrix[i] = even_row if self.index: for array in table_matrix: array[0] = 0 return table_matrix def get_table_font_color(self): """ Fill font-color array. Table text color can vary by row so this extends a single color or creates an array to set a header color and two alternating colors to create the striped table pattern. :rtype (list[list]) all_font_colors: list of font colors for each row in table. """ if len(self.font_colors) == 1: all_font_colors = self.font_colors*len(self.table_text) elif len(self.font_colors) == 3: all_font_colors = list(range(len(self.table_text))) all_font_colors[0] = self.font_colors[0] for i in range(1, len(self.table_text), 2): all_font_colors[i] = self.font_colors[1] for i in range(2, len(self.table_text), 2): all_font_colors[i] = self.font_colors[2] elif len(self.font_colors) == len(self.table_text): all_font_colors = self.font_colors else: all_font_colors = ['#000000']*len(self.table_text) return all_font_colors def make_table_annotations(self): """ Generate annotations to fill in table text :rtype (list) annotations: list of annotations for each cell of the table. """ from plotly.graph_objs import graph_objs table_matrix = _Table.get_table_matrix(self) all_font_colors = _Table.get_table_font_color(self) annotations = [] for n, row in enumerate(self.table_text): for m, val in enumerate(row): # Bold text in header and index format_text = ('' + str(val) + '' if n == 0 or self.index and m < 1 else str(val)) # Match font color of index to font color of header font_color = (self.font_colors[0] if self.index and m == 0 else all_font_colors[n]) annotations.append( graph_objs.Annotation( text=format_text, x=self.x[m] - self.annotation_offset, y=self.y[n], xref='x1', yref='y1', align="left", xanchor="left", font=dict(color=font_color), showarrow=False)) return annotations plotly-1.9.5+dfsg.orig/plotly/exceptions.py0000644000175000017500000001405312645550357020354 0ustar noahfxnoahfx""" exceptions ========== A module that contains plotly's exception hierarchy. """ import json # Base Plotly Error class PlotlyError(Exception): pass class InputError(PlotlyError): pass class PlotlyRequestError(PlotlyError): def __init__(self, requests_exception): self.status_code = requests_exception.response.status_code self.HTTPError = requests_exception content_type = requests_exception.response.headers['content-type'] if 'json' in content_type: content = requests_exception.response.content if content != '': res_payload = json.loads( requests_exception.response.content.decode('utf8') ) if 'detail' in res_payload: self.message = res_payload['detail'] else: self.message = '' else: self.message = '' elif content_type == 'text/plain': self.message = requests_exception.response.content else: try: self.message = requests_exception.message except AttributeError: self.message = 'unknown error' def __str__(self): return self.message # Grid Errors COLUMN_NOT_YET_UPLOADED_MESSAGE = ( "Hm... it looks like your column '{column_name}' hasn't " "been uploaded to Plotly yet. You need to upload your " "column to Plotly before you can assign it to '{reference}'.\n" "To upload, try `plotly.plotly.grid_objs.upload` or " "`plotly.plotly.grid_objs.append_column`.\n" "Questions? chris@plot.ly" ) NON_UNIQUE_COLUMN_MESSAGE = ( "Yikes, plotly grids currently " "can't have duplicate column names. Rename " "the column \"{0}\" and try again." ) class PlotlyEmptyDataError(PlotlyError): pass # Graph Objects Errors class PlotlyGraphObjectError(PlotlyError): def __init__(self, message='', path=(), notes=()): """ General graph object error for validation failures. :param (str|unicode) message: The error message. :param (iterable) path: A path pointing to the error. :param notes: Add additional notes, but keep default exception message. """ self.message = message self.plain_message = message # for backwards compat self.path = list(path) self.notes = notes super(PlotlyGraphObjectError, self).__init__(message) def __str__(self): """This is called by Python to present the error message.""" format_dict = { 'message': self.message, 'path': '[' + ']['.join(repr(k) for k in self.path) + ']', 'notes': '\n'.join(self.notes) } return ('{message}\n\nPath To Error: {path}\n\n{notes}' .format(**format_dict)) class PlotlyDictKeyError(PlotlyGraphObjectError): def __init__(self, obj, path, notes=()): """See PlotlyGraphObjectError.__init__ for param docs.""" format_dict = {'attribute': path[-1], 'object_name': obj._name} message = ("'{attribute}' is not allowed in '{object_name}'" .format(**format_dict)) notes = [obj.help(return_help=True)] + list(notes) super(PlotlyDictKeyError, self).__init__( message=message, path=path, notes=notes ) class PlotlyDictValueError(PlotlyGraphObjectError): def __init__(self, obj, path, notes=()): """See PlotlyGraphObjectError.__init__ for param docs.""" format_dict = {'attribute': path[-1], 'object_name': obj._name} message = ("'{attribute}' has invalid value inside '{object_name}'" .format(**format_dict)) notes = [obj.help(path[-1], return_help=True)] + list(notes) super(PlotlyDictValueError, self).__init__( message=message, notes=notes, path=path ) class PlotlyListEntryError(PlotlyGraphObjectError): def __init__(self, obj, path, notes=()): """See PlotlyGraphObjectError.__init__ for param docs.""" format_dict = {'index': path[-1], 'object_name': obj._name} message = ("Invalid entry found in '{object_name}' at index, '{index}'" .format(**format_dict)) notes = [obj.help(return_help=True)] + list(notes) super(PlotlyListEntryError, self).__init__( message=message, path=path, notes=notes ) class PlotlyDataTypeError(PlotlyGraphObjectError): def __init__(self, obj, path, notes=()): """See PlotlyGraphObjectError.__init__ for param docs.""" format_dict = {'index': path[-1], 'object_name': obj._name} message = ("Invalid entry found in '{object_name}' at index, '{index}'" .format(**format_dict)) note = "It's invalid because it does't contain a valid 'type' value." notes = [note] + list(notes) super(PlotlyDataTypeError, self).__init__( message=message, path=path, notes=notes ) # Local Config Errors class PlotlyLocalError(PlotlyError): pass class PlotlyLocalCredentialsError(PlotlyLocalError): def __init__(self): message = ( "\n" "Couldn't find a 'username', 'api-key' pair for you on your local " "machine. To sign in temporarily (until you stop running Python), " "run:\n" ">>> import plotly.plotly as py\n" ">>> py.sign_in('username', 'api_key')\n\n" "Even better, save your credentials permanently using the 'tools' " "module:\n" ">>> import plotly.tools as tls\n" ">>> tls.set_credentials_file(username='username', " "api_key='api-key')\n\n" "For more help, see https://plot.ly/python.\n" ) super(PlotlyLocalCredentialsError, self).__init__(message) # Server Errors class PlotlyServerError(PlotlyError): pass class PlotlyConnectionError(PlotlyServerError): pass class PlotlyCredentialError(PlotlyServerError): pass class PlotlyAccountError(PlotlyServerError): pass class PlotlyRateLimitError(PlotlyServerError): pass plotly-1.9.5+dfsg.orig/plotly/offline/0000755000175000017500000000000012651150115017221 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/offline/__init__.py0000644000175000017500000000032512647020762021343 0ustar noahfxnoahfx""" offline ====== This module provides offline functionality. """ from . offline import ( download_plotlyjs, enable_mpl_offline, init_notebook_mode, iplot, iplot_mpl, plot, plot_mpl ) plotly-1.9.5+dfsg.orig/plotly/offline/offline.py0000644000175000017500000004166712647020762021244 0ustar noahfxnoahfx""" Plotly Offline A module to use Plotly's graphing library with Python without connecting to a public or private plotly enterprise server. """ from __future__ import absolute_import import json import os import uuid import warnings from pkg_resources import resource_string import webbrowser import plotly from plotly import tools, utils from plotly.exceptions import PlotlyError try: import IPython _ipython_imported = True except ImportError: _ipython_imported = False try: import matplotlib _matplotlib_imported = True except ImportError: _matplotlib_imported = False __PLOTLY_OFFLINE_INITIALIZED = False def download_plotlyjs(download_url): warnings.warn(''' `download_plotlyjs` is deprecated and will be removed in the next release. plotly.js is shipped with this module, it is no longer necessary to download this bundle separately. ''', DeprecationWarning) pass def get_plotlyjs(): path = os.path.join('offline', 'plotly.min.js') plotlyjs = resource_string('plotly', path).decode('utf-8') return plotlyjs def init_notebook_mode(): """ Initialize Plotly Offline mode in an IPython Notebook. Run this function at the start of an IPython notebook to load the necessary javascript files for creating Plotly graphs with plotly.offline.iplot. """ if not tools._ipython_imported: raise ImportError('`iplot` can only run inside an IPython Notebook.') from IPython.display import HTML, display global __PLOTLY_OFFLINE_INITIALIZED __PLOTLY_OFFLINE_INITIALIZED = True display(HTML('' + '')) def _plot_html(figure_or_data, show_link, link_text, validate, default_width, default_height): figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) width = figure.get('layout', {}).get('width', default_width) height = figure.get('layout', {}).get('height', default_height) try: float(width) except (ValueError, TypeError): pass else: width = str(width) + 'px' try: float(width) except (ValueError, TypeError): pass else: width = str(width) + 'px' plotdivid = uuid.uuid4() jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder) jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder) config = {} config['showLink'] = show_link config['linkText'] = link_text jconfig = json.dumps(config) # TODO: The get_config 'source of truth' should # really be somewhere other than plotly.plotly plotly_platform_url = plotly.plotly.get_config().get('plotly_domain', 'https://plot.ly') if (plotly_platform_url != 'https://plot.ly' and link_text == 'Export to plot.ly'): link_domain = plotly_platform_url\ .replace('https://', '')\ .replace('http://', '') link_text = link_text.replace('plot.ly', link_domain) script = 'Plotly.newPlot("{id}", {data}, {layout}, {config})'.format( id=plotdivid, data=jdata, layout=jlayout, config=jconfig) plotly_html_div = ( '' '
' '
' '' '').format( id=plotdivid, script=script, height=height, width=width) return plotly_html_div, plotdivid, width, height def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly', validate=True): """ Draw plotly graphs inside an IPython notebook without connecting to an external server. To save the chart to Plotly Cloud or Plotly Enterprise, use `plotly.plotly.iplot`. To embed an image of the chart, use `plotly.image.ishow`. figure_or_data -- a plotly.graph_objs.Figure or plotly.graph_objs.Data or dict or list that describes a Plotly graph. See https://plot.ly/python/ for examples of graph descriptions. Keyword arguments: show_link (default=True) -- display a link in the bottom-right corner of of the chart that will export the chart to Plotly Cloud or Plotly Enterprise link_text (default='Export to plot.ly') -- the text of export link validate (default=True) -- validate that all of the keys in the figure are valid? omit if your version of plotly.js has become outdated with your version of graph_reference.json or if you need to include extra, unnecessary keys in your figure. Example: ``` from plotly.offline import init_notebook_mode, iplot init_notebook_mode() iplot([{'x': [1, 2, 3], 'y': [5, 2, 7]}]) ``` """ if not __PLOTLY_OFFLINE_INITIALIZED: raise PlotlyError('\n'.join([ 'Plotly Offline mode has not been initialized in this notebook. ' 'Run: ', '', 'import plotly', 'plotly.offline.init_notebook_mode() ' '# run at the start of every ipython notebook', ])) if not tools._ipython_imported: raise ImportError('`iplot` can only run inside an IPython Notebook.') from IPython.display import HTML, display plot_html, plotdivid, width, height = _plot_html( figure_or_data, show_link, link_text, validate, '100%', 525) display(HTML(plot_html)) def plot(figure_or_data, show_link=True, link_text='Export to plot.ly', validate=True, output_type='file', include_plotlyjs=True, filename='temp-plot.html', auto_open=True): """ Create a plotly graph locally as an HTML document or string. Example: ``` from plotly.offline import plot import plotly.graph_objs as go plot([go.Scatter(x=[1, 2, 3], y=[3, 2, 6])], filename='my-graph.html') ``` More examples below. figure_or_data -- a plotly.graph_objs.Figure or plotly.graph_objs.Data or dict or list that describes a Plotly graph. See https://plot.ly/python/ for examples of graph descriptions. Keyword arguments: show_link (default=True) -- display a link in the bottom-right corner of of the chart that will export the chart to Plotly Cloud or Plotly Enterprise link_text (default='Export to plot.ly') -- the text of export link validate (default=True) -- validate that all of the keys in the figure are valid? omit if your version of plotly.js has become outdated with your version of graph_reference.json or if you need to include extra, unnecessary keys in your figure. output_type ('file' | 'div' - default 'file') -- if 'file', then the graph is saved as a standalone HTML file and `plot` returns None. If 'div', then `plot` returns a string that just contains the HTML
that contains the graph and the script to generate the graph. Use 'file' if you want to save and view a single graph at a time in a standalone HTML file. Use 'div' if you are embedding these graphs in an HTML file with other graphs or HTML markup, like a HTML report or an website. include_plotlyjs (default=True) -- If True, include the plotly.js source code in the output file or string. Set as False if your HTML file already contains a copy of the plotly.js library. filename (default='temp-plot.html') -- The local filename to save the outputted chart to. If the filename already exists, it will be overwritten. This argument only applies if `output_type` is 'file'. auto_open (default=True) -- If True, open the saved file in a web browser after saving. This argument only applies if `output_type` is 'file'. """ if output_type not in ['div', 'file']: raise ValueError( "`output_type` argument must be 'div' or 'file'. " "You supplied `" + output_type + "``") if not filename.endswith('.html') and output_type == 'file': warnings.warn( "Your filename `" + filename + "` didn't end with .html. " "Adding .html to the end of your file.") filename += '.html' plot_html, plotdivid, width, height = _plot_html( figure_or_data, show_link, link_text, validate, '100%', '100%') figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) resize_script = '' if width == '100%' or height == '100%': resize_script = ( '' '' ).format(id=plotdivid) if output_type == 'file': with open(filename, 'w') as f: if include_plotlyjs: plotly_js_script = ''.join([ '', ]) else: plotly_js_script = '' f.write(''.join([ '', '', '', plotly_js_script, plot_html, resize_script, '', ''])) url = 'file://' + os.path.abspath(filename) if auto_open: webbrowser.open(url) return url elif output_type == 'div': if include_plotlyjs: return ''.join([ '
', '', plot_html, '
' ]) else: return plot_html def plot_mpl(mpl_fig, resize=False, strip_style=False, verbose=False, show_link=True, link_text='Export to plot.ly', validate=True, output_type='file', include_plotlyjs=True, filename='temp-plot.html', auto_open=True): """ Convert a matplotlib figure to a Plotly graph stored locally as HTML. For more information on converting matplotlib visualizations to plotly graphs, call help(plotly.tools.mpl_to_plotly) For more information on creating plotly charts locally as an HTML document or string, call help(plotly.offline.plot) mpl_fig -- a matplotlib figure object to convert to a plotly graph Keyword arguments: resize (default=False) -- allow plotly to choose the figure size. strip_style (default=False) -- allow plotly to choose style options. verbose (default=False) -- print message. show_link (default=True) -- display a link in the bottom-right corner of of the chart that will export the chart to Plotly Cloud or Plotly Enterprise link_text (default='Export to plot.ly') -- the text of export link validate (default=True) -- validate that all of the keys in the figure are valid? omit if your version of plotly.js has become outdated with your version of graph_reference.json or if you need to include extra, unnecessary keys in your figure. output_type ('file' | 'div' - default 'file') -- if 'file', then the graph is saved as a standalone HTML file and `plot` returns None. If 'div', then `plot` returns a string that just contains the HTML
that contains the graph and the script to generate the graph. Use 'file' if you want to save and view a single graph at a time in a standalone HTML file. Use 'div' if you are embedding these graphs in an HTML file with other graphs or HTML markup, like a HTML report or an website. include_plotlyjs (default=True) -- If True, include the plotly.js source code in the output file or string. Set as False if your HTML file already contains a copy of the plotly.js library. filename (default='temp-plot.html') -- The local filename to save the outputted chart to. If the filename already exists, it will be overwritten. This argument only applies if `output_type` is 'file'. auto_open (default=True) -- If True, open the saved file in a web browser after saving. This argument only applies if `output_type` is 'file'. Example: ``` from plotly.offline import init_notebook_mode, plot_mpl import matplotlib.pyplot as plt init_notebook_mode() fig = plt.figure() x = [10, 15, 20, 25, 30] y = [100, 250, 200, 150, 300] plt.plot(x, y, "o") plot_mpl(fig) ``` """ plotly_plot = tools.mpl_to_plotly(mpl_fig, resize, strip_style, verbose) return plot(plotly_plot, show_link, link_text, validate, output_type, include_plotlyjs, filename, auto_open) def iplot_mpl(mpl_fig, resize=False, strip_style=False, verbose=False, show_link=True, link_text='Export to plot.ly', validate=True): """ Convert a matplotlib figure to a plotly graph and plot inside an IPython notebook without connecting to an external server. To save the chart to Plotly Cloud or Plotly Enterprise, use `plotly.plotly.plot_mpl`. For more information on converting matplotlib visualizations to plotly graphs call `help(plotly.tools.mpl_to_plotly)` For more information on plotting plotly charts offline in an Ipython notebook call `help(plotly.offline.iplot)` mpl_fig -- a matplotlib.figure to convert to a plotly graph Keyword arguments: resize (default=False) -- allow plotly to choose the figure size. strip_style (default=False) -- allow plotly to choose style options. verbose (default=False) -- print message. show_link (default=True) -- display a link in the bottom-right corner of of the chart that will export the chart to Plotly Cloud or Plotly Enterprise show_link (default=True) -- display a link in the bottom-right corner of of the chart that will export the chart to Plotly Cloud or Plotly Enterprise link_text (default='Export to plot.ly') -- the text of export link validate (default=True) -- validate that all of the keys in the figure are valid? omit if your version of plotly.js has become outdated with your version of graph_reference.json or if you need to include extra, unnecessary keys in your figure. Example: ``` from plotly.offline import init_notebook_mode, iplot_mpl import matplotlib.pyplot as plt init_notebook_mode() fig = plt.figure() x = [10, 15, 20, 25, 30] y = [100, 250, 200, 150, 300] plt.plot(x, y, "o") iplot_mpl(fig) ``` """ plotly_plot = tools.mpl_to_plotly(mpl_fig, resize, strip_style, verbose) return iplot(plotly_plot, show_link, link_text, validate) def enable_mpl_offline(resize=False, strip_style=False, verbose=False, show_link=True, link_text='Export to plot.ly', validate=True): """ Convert mpl plots to locally hosted HTML documents. This function should be used with the inline matplotlib backend that ships with IPython that can be enabled with `%pylab inline` or `%matplotlib inline`. This works by adding an HTML formatter for Figure objects; the existing SVG/PNG formatters will remain enabled. (idea taken from `mpld3._display.enable_notebook`) Example: ``` from plotly.offline import init_notebook_mode, plotly_takeover import matplotlib.pyplot as plt init_notebook_mode() enable_mpl_offline() fig = plt.figure() x = [10, 15, 20, 25, 30] y = [100, 250, 200, 150, 300] plt.plot(x, y, "o") fig ``` """ if not __PLOTLY_OFFLINE_INITIALIZED: init_notebook_mode() ip = IPython.core.getipython.get_ipython() formatter = ip.display_formatter.formatters['text/html'] formatter.for_type(matplotlib.figure.Figure, lambda fig: iplot_mpl(fig, resize, strip_style, verbose, show_link, link_text, validate)) plotly-1.9.5+dfsg.orig/plotly/plotly/0000755000175000017500000000000012647020776017140 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/plotly/__init__.py0000644000175000017500000000073012645550357021252 0ustar noahfxnoahfx""" plotly ====== This module defines functionality that requires interaction between your local machine and Plotly. Almost all functionality used here will require a verifiable account (username/api-key pair) and a network connection. """ from . plotly import ( sign_in, update_plot_options, get_credentials, iplot, plot, iplot_mpl, plot_mpl, get_figure, Stream, image, grid_ops, meta_ops, file_ops, get_config ) plotly-1.9.5+dfsg.orig/plotly/plotly/chunked_requests/0000755000175000017500000000000012647020776022514 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly/plotly/chunked_requests/chunked_request.py0000644000175000017500000002446112645550474026267 0ustar noahfxnoahfximport time import six import os from six.moves import http_client from six.moves.urllib.parse import urlparse class Stream: def __init__(self, server, port=80, headers={}, url='/'): ''' Initialize a stream object and an HTTP Connection with chunked Transfer-Encoding to server:port with optional headers. ''' self.maxtries = 5 self._tries = 0 self._delay = 1 self._closed = False self._server = server self._port = port self._headers = headers self._url = url self._connect() def write(self, data, reconnect_on=('', 200, )): ''' Send `data` to the server in chunk-encoded form. Check the connection before writing and reconnect if disconnected and if the response status code is in `reconnect_on`. The response may either be an HTTPResponse object or an empty string. ''' if not self._isconnected(): # Attempt to get the response. response = self._getresponse() # Reconnect depending on the status code. if ((response == '' and '' in reconnect_on) or (response and isinstance(response, http_client.HTTPResponse) and response.status in reconnect_on)): self._reconnect() elif response and isinstance(response, http_client.HTTPResponse): # If an HTTPResponse was recieved then # make the users aware instead of # auto-reconnecting in case the # server is responding with an important # message that might prevent # future requests from going through, # like Invalid Credentials. # This allows the user to determine when # to reconnect. raise Exception("Server responded with " "status code: {status_code}\n" "and message: {msg}." .format(status_code=response.status, msg=response.read())) elif response == '': raise Exception("Attempted to write but socket " "was not connected.") try: msg = data msglen = format(len(msg), 'x') # msg length in hex # Send the message in chunk-encoded form self._conn.sock.setblocking(1) self._conn.send('{msglen}\r\n{msg}\r\n' .format(msglen=msglen, msg=msg).encode('utf-8')) self._conn.sock.setblocking(0) except http_client.socket.error: self._reconnect() self.write(data) def _get_proxy_config(self): """ Determine if self._url should be passed through a proxy. If so, return the appropriate proxy_server and proxy_port """ proxy_server = None proxy_port = None ## only doing HTTPConnection, so only use http_proxy proxy = os.environ.get("http_proxy") no_proxy = os.environ.get("no_proxy") no_proxy_url = no_proxy and self._url in no_proxy if proxy and not no_proxy_url: p = urlparse(proxy) proxy_server = p.hostname proxy_port = p.port return proxy_server, proxy_port def _connect(self): ''' Initialize an HTTP connection with chunked Transfer-Encoding to server:port with optional headers. ''' server = self._server port = self._port headers = self._headers proxy_server, proxy_port = self._get_proxy_config() if (proxy_server and proxy_port): self._conn = http_client.HTTPConnection(proxy_server, proxy_port) self._conn.set_tunnel(server, port) else: self._conn = http_client.HTTPConnection(server, port) self._conn.putrequest('POST', self._url) self._conn.putheader('Transfer-Encoding', 'chunked') for header in headers: self._conn.putheader(header, headers[header]) self._conn.endheaders() # Set blocking to False prevents recv # from blocking while waiting for a response. self._conn.sock.setblocking(False) self._bytes = six.b('') self._reset_retries() time.sleep(0.5) def close(self): ''' Close the connection to server. If available, return a http_client.HTTPResponse object. Closing the connection involves sending the Transfer-Encoding terminating bytes. ''' self._reset_retries() self._closed = True # Chunked-encoded posts are terminated with '0\r\n\r\n' # For some reason, either Python or node.js seems to # require an extra \r\n. try: self._conn.send('\r\n0\r\n\r\n'.encode('utf-8')) except http_client.socket.error: # In case the socket has already been closed return '' return self._getresponse() def _getresponse(self): ''' Read from recv and return a HTTPResponse object if possible. Either 1 - The client has succesfully closed the connection: Return '' 2 - The server has already closed the connection: Return the response if possible. ''' # Wait for a response self._conn.sock.setblocking(True) # Parse the response response = self._bytes while True: try: _bytes = self._conn.sock.recv(1) except http_client.socket.error: # For error 54: Connection reset by peer # (and perhaps others) return six.b('') if _bytes == six.b(''): break else: response += _bytes # Set recv to be non-blocking again self._conn.sock.setblocking(False) # Convert the response string to a http_client.HTTPResponse # object with a bit of a hack if response != six.b(''): # Taken from # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html try: response = http_client.HTTPResponse(_FakeSocket(response)) response.begin() except: # Bad headers ... etc. response = six.b('') return response def _isconnected(self): ''' Return True if the socket is still connected to the server, False otherwise. This check is done in 3 steps: 1 - Check if we have closed the connection 2 - Check if the original socket connection failed 3 - Check if the server has returned any data. If they have, assume that the server closed the response after they sent the data, i.e. that the data was the HTTP response. ''' # 1 - check if we've closed the connection. if self._closed: return False # 2 - Check if the original socket connection failed # If this failed, then no socket was initialized if self._conn.sock is None: return False try: # 3 - Check if the server has returned any data. # If they have, then start to store the response # in _bytes. self._bytes = six.b('') self._bytes = self._conn.sock.recv(1) return False except http_client.socket.error as e: # Check why recv failed # Windows machines are the error codes # that start with 1 # (http://msdn.microsoft.com/en-ca/library/windows/desktop/ms740668(v=vs.85).aspx) if e.errno == 35 or e.errno == 10035: # This is the "Resource temporarily unavailable" error # which is thrown cuz there was nothing to receive, i.e. # the server hasn't returned a response yet. # This is a non-fatal error and the operation # should be tried again. # So, assume that the connection is still open. return True elif e.errno == 54 or e.errno == 10054: # This is the "Connection reset by peer" error # which is thrown cuz the server reset the # socket, so the connection is closed. return False elif e.errno == 11: # This is the "Resource temporarily unavailable" error # which happens because the "operation would have blocked # but nonblocking operation was requested". # We require non-blocking reading of this socket because # we don't want to wait around for a response, we just # want to see if a response is currently available. So # let's just assume that we're still connected and # hopefully recieve some data on the next try. return True else: # Unknown scenario raise e def _reconnect(self): ''' Connect if disconnected. Retry self.maxtries times with delays ''' if not self._isconnected(): try: self._connect() except http_client.socket.error as e: # Attempt to reconnect if the connection was refused if e.errno == 61 or e.errno == 10061: # errno 61 is the "Connection Refused" error time.sleep(self._delay) self._delay += self._delay # fibonacii delays self._tries += 1 if self._tries < self.maxtries: self._reconnect() else: self._reset_retries() raise e else: # Unknown scenario raise e # Reconnect worked - reset _closed self._closed = False def _reset_retries(self): ''' Reset the connect counters and delays ''' self._tries = 0 self._delay = 1 class _FakeSocket(six.StringIO): # Used to construct a http_client.HTTPResponse object # from a string. # Thx to: http://pythonwise.blogspot.ca/2010/02/parse-http-response.html def makefile(self, *args, **kwargs): return self plotly-1.9.5+dfsg.orig/plotly/plotly/chunked_requests/__init__.py0000644000175000017500000000004412645550357024624 0ustar noahfxnoahfxfrom . chunked_request import Streamplotly-1.9.5+dfsg.orig/plotly/plotly/plotly.py0000644000175000017500000015154012645550357021044 0ustar noahfxnoahfx""" plotly ====== A module that contains the plotly class, a liaison between the user and ploty's servers. 1. get DEFAULT_PLOT_OPTIONS for options 2. update plot_options with .plotly/ dir 3. update plot_options with _plot_options 4. update plot_options with kwargs! """ from __future__ import absolute_import import base64 import copy import json import os import warnings import requests import six import six.moves from requests.auth import HTTPBasicAuth from plotly import exceptions, tools, utils, version, files from plotly.plotly import chunked_requests from plotly.session import (sign_in, update_session_plot_options, get_session_plot_options, get_session_credentials, get_session_config) __all__ = None DEFAULT_PLOT_OPTIONS = { 'filename': "plot from API", 'fileopt': "new", 'world_readable': files.FILE_CONTENT[files.CONFIG_FILE]['world_readable'], 'auto_open': files.FILE_CONTENT[files.CONFIG_FILE]['auto_open'], 'validate': True, 'sharing': files.FILE_CONTENT[files.CONFIG_FILE]['sharing'] } # test file permissions and make sure nothing is corrupted tools.ensure_local_plotly_files() # don't break backwards compatibility sign_in = sign_in update_plot_options = update_session_plot_options def get_credentials(): """Returns the credentials that will be sent to plotly.""" credentials = tools.get_credentials_file() session_credentials = get_session_credentials() for credentials_key in credentials: # checking for not false, but truthy value here is the desired behavior session_value = session_credentials.get(credentials_key) if session_value is False or session_value: credentials[credentials_key] = session_value return credentials def get_config(): """Returns either module config or file config.""" config = tools.get_config_file() session_config = get_session_config() for config_key in config: # checking for not false, but truthy value here is the desired behavior session_value = session_config.get(config_key) if session_value is False or session_value: config[config_key] = session_value return config def _plot_option_logic(plot_options_from_call_signature): """ Given some plot_options as part of a plot call, decide on final options. Precendence: 1 - Start with DEFAULT_PLOT_OPTIONS 2 - Update each key with ~/.plotly/.config options (tls.get_config) 3 - Update each key with session plot options (set by py.sign_in) 4 - Update each key with plot, iplot call signature options """ default_plot_options = copy.deepcopy(DEFAULT_PLOT_OPTIONS) file_options = tools.get_config_file() session_options = get_session_plot_options() plot_options_from_call_signature = copy.deepcopy(plot_options_from_call_signature) # Validate options and fill in defaults w world_readable and sharing for option_set in [plot_options_from_call_signature, session_options, file_options]: utils.validate_world_readable_and_sharing_settings(option_set) utils.set_sharing_and_world_readable(option_set) # dynamic defaults if ('filename' in option_set and 'fileopt' not in option_set): option_set['fileopt'] = 'overwrite' user_plot_options = {} user_plot_options.update(default_plot_options) user_plot_options.update(file_options) user_plot_options.update(session_options) user_plot_options.update(plot_options_from_call_signature) user_plot_options = {k: v for k, v in user_plot_options.items() if k in default_plot_options} return user_plot_options def iplot(figure_or_data, **plot_options): """Create a unique url for this plot in Plotly and open in IPython. plot_options keyword agruments: filename (string) -- the name that will be associated with this figure fileopt ('new' | 'overwrite' | 'extend' | 'append') - 'new': create a new, unique url for this plot - 'overwrite': overwrite the file associated with `filename` with this - 'extend': add additional numbers (data) to existing traces - 'append': add additional traces to existing data lists sharing ('public' | 'private' | 'secret') -- Toggle who can view this graph - 'public': Anyone can view this graph. It will appear in your profile and can appear in search engines. You do not need to be logged in to Plotly to view this chart. - 'private': Only you can view this plot. It will not appear in the Plotly feed, your profile, or search engines. You must be logged in to Plotly to view this graph. You can privately share this graph with other Plotly users in your online Plotly account and they will need to be logged in to view this plot. - 'secret': Anyone with this secret link can view this chart. It will not appear in the Plotly feed, your profile, or search engines. If it is embedded inside a webpage or an IPython notebook, anybody who is viewing that page will be able to view the graph. You do not need to be logged in to view this plot. world_readable (default=True) -- Deprecated: use "sharing". Make this figure private/public """ if 'auto_open' not in plot_options: plot_options['auto_open'] = False url = plot(figure_or_data, **plot_options) if isinstance(figure_or_data, dict): layout = figure_or_data.get('layout', {}) else: layout = {} embed_options = dict() embed_options['width'] = layout.get('width', '100%') embed_options['height'] = layout.get('height', 525) try: float(embed_options['width']) except (ValueError, TypeError): pass else: embed_options['width'] = str(embed_options['width']) + 'px' try: float(embed_options['height']) except (ValueError, TypeError): pass else: embed_options['height'] = str(embed_options['height']) + 'px' return tools.embed(url, **embed_options) def plot(figure_or_data, validate=True, **plot_options): """Create a unique url for this plot in Plotly and optionally open url. plot_options keyword agruments: filename (string) -- the name that will be associated with this figure fileopt ('new' | 'overwrite' | 'extend' | 'append') -- 'new' creates a 'new': create a new, unique url for this plot 'overwrite': overwrite the file associated with `filename` with this 'extend': add additional numbers (data) to existing traces 'append': add additional traces to existing data lists auto_open (default=True) -- Toggle browser options True: open this plot in a new browser tab False: do not open plot in the browser, but do return the unique url sharing ('public' | 'private' | 'secret') -- Toggle who can view this graph - 'public': Anyone can view this graph. It will appear in your profile and can appear in search engines. You do not need to be logged in to Plotly to view this chart. - 'private': Only you can view this plot. It will not appear in the Plotly feed, your profile, or search engines. You must be logged in to Plotly to view this graph. You can privately share this graph with other Plotly users in your online Plotly account and they will need to be logged in to view this plot. - 'secret': Anyone with this secret link can view this chart. It will not appear in the Plotly feed, your profile, or search engines. If it is embedded inside a webpage or an IPython notebook, anybody who is viewing that page will be able to view the graph. You do not need to be logged in to view this plot. world_readable (default=True) -- Deprecated: use "sharing". Make this figure private/public """ figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) for entry in figure['data']: if ('type' in entry) and (entry['type'] == 'scattergl'): continue for key, val in list(entry.items()): try: if len(val) > 40000: msg = ("Woah there! Look at all those points! Due to " "browser limitations, the Plotly SVG drawing " "functions have a hard time " "graphing more than 500k data points for line " "charts, or 40k points for other types of charts. " "Here are some suggestions:\n" "(1) Use the `plotly.graph_objs.Scattergl` " "trace object to generate a WebGl graph.\n" "(2) Trying using the image API to return an image " "instead of a graph URL\n" "(3) Use matplotlib\n" "(4) See if you can create your visualization with " "fewer data points\n\n" "If the visualization you're using aggregates " "points (e.g., box plot, histogram, etc.) you can " "disregard this warning.") warnings.warn(msg) except TypeError: pass plot_options = _plot_option_logic(plot_options) res = _send_to_plotly(figure, **plot_options) if res['error'] == '': if plot_options['auto_open']: _open_url(res['url']) return res['url'] else: raise exceptions.PlotlyAccountError(res['error']) def iplot_mpl(fig, resize=True, strip_style=False, update=None, **plot_options): """Replot a matplotlib figure with plotly in IPython. This function: 1. converts the mpl figure into JSON (run help(plolty.tools.mpl_to_plotly)) 2. makes a request to Plotly to save this figure in your account 3. displays the image in your IPython output cell Positional agruments: fig -- a figure object from matplotlib Keyword arguments: resize (default=True) -- allow plotly to choose the figure size strip_style (default=False) -- allow plotly to choose style options update (default=None) -- update the resulting figure with an 'update' dictionary-like object resembling a plotly 'Figure' object Additional keyword arguments: plot_options -- run help(plotly.plotly.iplot) """ fig = tools.mpl_to_plotly(fig, resize=resize, strip_style=strip_style) if update and isinstance(update, dict): fig.update(update) fig.validate() elif update is not None: raise exceptions.PlotlyGraphObjectError( "'update' must be dictionary-like and a valid plotly Figure " "object. Run 'help(plotly.graph_objs.Figure)' for more info." ) return iplot(fig, **plot_options) def plot_mpl(fig, resize=True, strip_style=False, update=None, **plot_options): """Replot a matplotlib figure with plotly. This function: 1. converts the mpl figure into JSON (run help(plolty.tools.mpl_to_plotly)) 2. makes a request to Plotly to save this figure in your account 3. opens your figure in a browser tab OR returns the unique figure url Positional agruments: fig -- a figure object from matplotlib Keyword arguments: resize (default=True) -- allow plotly to choose the figure size strip_style (default=False) -- allow plotly to choose style options update (default=None) -- update the resulting figure with an 'update' dictionary-like object resembling a plotly 'Figure' object Additional keyword arguments: plot_options -- run help(plotly.plotly.plot) """ fig = tools.mpl_to_plotly(fig, resize=resize, strip_style=strip_style) if update and isinstance(update, dict): fig.update(update) fig.validate() elif update is not None: raise exceptions.PlotlyGraphObjectError( "'update' must be dictionary-like and a valid plotly Figure " "object. Run 'help(plotly.graph_objs.Figure)' for more info." ) return plot(fig, **plot_options) def get_figure(file_owner_or_url, file_id=None, raw=False): """Returns a JSON figure representation for the specified file Plotly uniquely identifies figures with a 'file_owner'/'file_id' pair. Since each file is given a corresponding unique url, you may also simply pass a valid plotly url as the first argument. Examples: fig = get_figure('https://plot.ly/~chris/1638') fig = get_figure('chris', 1638) Note, if you're using a file_owner string as the first argument, you MUST specify a `file_id` keyword argument. Else, if you're using a url string as the first argument, you MUST NOT specify a `file_id` keyword argument, or file_id must be set to Python's None value. Positional arguments: file_owner_or_url (string) -- a valid plotly username OR a valid plotly url Keyword arguments: file_id (default=None) -- an int or string that can be converted to int if you're using a url, don't fill this in! raw (default=False) -- if true, return unicode JSON string verbatim** **by default, plotly will return a Figure object (run help(plotly .graph_objs.Figure)). This representation decodes the keys and values from unicode (if possible), removes information irrelevant to the figure representation, and converts the JSON dictionary objects to plotly `graph objects`. """ plotly_rest_url = get_config()['plotly_domain'] if file_id is None: # assume we're using a url url = file_owner_or_url if url[:len(plotly_rest_url)] != plotly_rest_url: raise exceptions.PlotlyError( "Because you didn't supply a 'file_id' in the call, " "we're assuming you're trying to snag a figure from a url. " "You supplied the url, '{0}', we expected it to start with " "'{1}'." "\nRun help on this function for more information." "".format(url, plotly_rest_url)) head = plotly_rest_url + "/~" file_owner = url.replace(head, "").split('/')[0] file_id = url.replace(head, "").split('/')[1] else: file_owner = file_owner_or_url resource = "/apigetfile/{username}/{file_id}".format(username=file_owner, file_id=file_id) credentials = get_credentials() validate_credentials(credentials) username, api_key = credentials['username'], credentials['api_key'] headers = {'plotly-username': username, 'plotly-apikey': api_key, 'plotly-version': version.__version__, 'plotly-platform': 'python'} try: int(file_id) except ValueError: raise exceptions.PlotlyError( "The 'file_id' argument was not able to be converted into an " "integer number. Make sure that the positional 'file_id' argument " "is a number that can be converted into an integer or a string " "that can be converted into an integer." ) if int(file_id) < 0: raise exceptions.PlotlyError( "The 'file_id' argument must be a non-negative number." ) response = requests.get(plotly_rest_url + resource, headers=headers, verify=get_config()['plotly_ssl_verification']) if response.status_code == 200: if six.PY3: content = json.loads(response.content.decode('utf-8')) else: content = json.loads(response.content) response_payload = content['payload'] figure = response_payload['figure'] utils.decode_unicode(figure) if raw: return figure else: return tools.get_valid_graph_obj(figure, obj_type='Figure') else: try: content = json.loads(response.content) raise exceptions.PlotlyError(content) except: raise exceptions.PlotlyError( "There was an error retrieving this file") @utils.template_doc(**tools.get_config_file()) class Stream: """ Interface to Plotly's real-time graphing API. Initialize a Stream object with a stream_id found in {plotly_domain}/settings. Real-time graphs are initialized with a call to `plot` that embeds your unique `stream_id`s in each of the graph's traces. The `Stream` interface plots data to these traces, as identified with the unique stream_id, in real-time. Every viewer of the graph sees the same data at the same time. View examples and tutorials here: https://plot.ly/python/streaming/ Stream example: # Initialize a streaming graph # by embedding stream_id's in the graph's traces import plotly.plotly as py from plotly.graph_objs import Data, Scatter, Stream stream_id = "your_stream_id" # See {plotly_domain}/settings py.plot(Data([Scatter(x=[], y=[], stream=Stream(token=stream_id, maxpoints=100))])) # Stream data to the import trace stream = Stream(stream_id) # Initialize a stream object stream.open() # Open the stream stream.write(dict(x=1, y=1)) # Plot (1, 1) in your graph """ @utils.template_doc(**tools.get_config_file()) def __init__(self, stream_id): """ Initialize a Stream object with your unique stream_id. Find your stream_id at {plotly_domain}/settings. For more help, see: `help(plotly.plotly.Stream)` or see examples and tutorials here: https://plot.ly/python/streaming/ """ self.stream_id = stream_id self.connected = False self._stream = None def heartbeat(self, reconnect_on=(200, '', 408)): """ Keep stream alive. Streams will close after ~1 min of inactivity. If the interval between stream writes is > 30 seconds, you should consider adding a heartbeat between your stream.write() calls like so: >>> stream.heartbeat() """ try: self._stream.write('\n', reconnect_on=reconnect_on) except AttributeError: raise exceptions.PlotlyError( "Stream has not been opened yet, " "cannot write to a closed connection. " "Call `open()` on the stream to open the stream." ) def open(self): """ Open streaming connection to plotly. For more help, see: `help(plotly.plotly.Stream)` or see examples and tutorials here: https://plot.ly/python/streaming/ """ streaming_url = get_config()['plotly_streaming_domain'] self._stream = chunked_requests.Stream( streaming_url, 80, {'Host': streaming_url, 'plotly-streamtoken': self.stream_id}) def write(self, trace, layout=None, validate=True, reconnect_on=(200, '', 408)): """ Write to an open stream. Once you've instantiated a 'Stream' object with a 'stream_id', you can 'write' to it in real time. positional arguments: trace - A valid plotly trace object (e.g., Scatter, Heatmap, etc.). Not all keys in these are `stremable` run help(Obj) on the type of trace your trying to stream, for each valid key, if the key is streamable, it will say 'streamable = True'. Trace objects must be dictionary-like. keyword arguments: layout (default=None) - A valid Layout object Run help(plotly.graph_objs.Layout) validate (default = True) - Validate this stream before sending? This will catch local errors if set to True. Some valid keys for trace dictionaries: 'x', 'y', 'text', 'z', 'marker', 'line' Examples: >>> write(dict(x=1, y=2)) # assumes 'scatter' type >>> write(Bar(x=[1, 2, 3], y=[10, 20, 30])) >>> write(Scatter(x=1, y=2, text='scatter text')) >>> write(Scatter(x=1, y=3, marker=Marker(color='blue'))) >>> write(Heatmap(z=[[1, 2, 3], [4, 5, 6]])) The connection to plotly's servers is checked before writing and reconnected if disconnected and if the response status code is in `reconnect_on`. For more help, see: `help(plotly.plotly.Stream)` or see examples and tutorials here: http://nbviewer.ipython.org/github/plotly/python-user-guide/blob/master/s7_streaming/s7_streaming.ipynb """ stream_object = dict() stream_object.update(trace) if 'type' not in stream_object: stream_object['type'] = 'scatter' if validate: try: tools.validate(stream_object, stream_object['type']) except exceptions.PlotlyError as err: raise exceptions.PlotlyError( "Part of the data object with type, '{0}', is invalid. " "This will default to 'scatter' if you do not supply a " "'type'. If you do not want to validate your data objects " "when streaming, you can set 'validate=False' in the call " "to 'your_stream.write()'. Here's why the object is " "invalid:\n\n{1}".format(stream_object['type'], err) ) if layout is not None: try: tools.validate(layout, 'Layout') except exceptions.PlotlyError as err: raise exceptions.PlotlyError( "Your layout kwarg was invalid. " "Here's why:\n\n{0}".format(err) ) del stream_object['type'] if layout is not None: stream_object.update(dict(layout=layout)) # TODO: allow string version of this? jdata = json.dumps(stream_object, cls=utils.PlotlyJSONEncoder) jdata += "\n" try: self._stream.write(jdata, reconnect_on=reconnect_on) except AttributeError: raise exceptions.PlotlyError( "Stream has not been opened yet, " "cannot write to a closed connection. " "Call `open()` on the stream to open the stream.") def close(self): """ Close the stream connection to plotly's streaming servers. For more help, see: `help(plotly.plotly.Stream)` or see examples and tutorials here: https://plot.ly/python/streaming/ """ try: self._stream.close() except AttributeError: raise exceptions.PlotlyError("Stream has not been opened yet.") class image: """ Helper functions wrapped around plotly's static image generation api. """ @staticmethod def get(figure_or_data, format='png', width=None, height=None, scale=None): """Return a static image of the plot described by `figure_or_data`. positional arguments: - figure_or_data: The figure dict-like or data list-like object that describes a plotly figure. Same argument used in `py.plot`, `py.iplot`, see https://plot.ly/python for examples - format: 'png', 'svg', 'jpeg', 'pdf' - width: output width - height: output height - scale: Increase the resolution of the image by `scale` amount (e.g. `3`) Only valid for PNG and JPEG images. example: ``` import plotly.plotly as py fig = {'data': [{'x': [1, 2, 3], 'y': [3, 1, 5], 'type': 'bar'}]} py.image.get(fig, 'png', scale=3) ``` """ # TODO: format is a built-in name... we shouldn't really use it if isinstance(figure_or_data, dict): figure = figure_or_data elif isinstance(figure_or_data, list): figure = {'data': figure_or_data} else: raise exceptions.PlotlyEmptyDataError( "`figure_or_data` must be a dict or a list." ) if format not in ['png', 'svg', 'jpeg', 'pdf']: raise exceptions.PlotlyError( "Invalid format. This version of your Plotly-Python " "package currently only supports png, svg, jpeg, and pdf. " "Learn more about image exporting, and the currently " "supported file types here: " "https://plot.ly/python/static-image-export/" ) if scale is not None: try: scale = float(scale) except: raise exceptions.PlotlyError( "Invalid scale parameter. Scale must be a number." ) headers = _api_v2.headers() headers['plotly_version'] = version.__version__ headers['content-type'] = 'application/json' payload = {'figure': figure, 'format': format} if width is not None: payload['width'] = width if height is not None: payload['height'] = height if scale is not None: payload['scale'] = scale url = _api_v2.api_url('images/') res = requests.post( url, data=json.dumps(payload, cls=utils.PlotlyJSONEncoder), headers=headers, verify=get_config()['plotly_ssl_verification'], ) headers = res.headers if res.status_code == 200: if ('content-type' in headers and headers['content-type'] in ['image/png', 'image/jpeg', 'application/pdf', 'image/svg+xml']): return res.content elif ('content-type' in headers and 'json' in headers['content-type']): return_data = json.loads(res.content) return return_data['image'] else: try: if ('content-type' in headers and 'json' in headers['content-type']): return_data = json.loads(res.content) else: return_data = {'error': res.content} except: raise exceptions.PlotlyError("The response " "from plotly could " "not be translated.") raise exceptions.PlotlyError(return_data['error']) @classmethod def ishow(cls, figure_or_data, format='png', width=None, height=None, scale=None): """Display a static image of the plot described by `figure_or_data` in an IPython Notebook. positional arguments: - figure_or_data: The figure dict-like or data list-like object that describes a plotly figure. Same argument used in `py.plot`, `py.iplot`, see https://plot.ly/python for examples - format: 'png', 'svg', 'jpeg', 'pdf' - width: output width - height: output height - scale: Increase the resolution of the image by `scale` amount Only valid for PNG and JPEG images. example: ``` import plotly.plotly as py fig = {'data': [{'x': [1, 2, 3], 'y': [3, 1, 5], 'type': 'bar'}]} py.image.ishow(fig, 'png', scale=3) """ if format == 'pdf': raise exceptions.PlotlyError( "Aw, snap! " "It's not currently possible to embed a pdf into " "an IPython notebook. You can save the pdf " "with the `image.save_as` or you can " "embed an png, jpeg, or svg.") img = cls.get(figure_or_data, format, width, height, scale) from IPython.display import display, Image, SVG if format == 'svg': display(SVG(img)) else: display(Image(img)) @classmethod def save_as(cls, figure_or_data, filename, format=None, width=None, height=None, scale=None): """Save a image of the plot described by `figure_or_data` locally as `filename`. Valid image formats are 'png', 'svg', 'jpeg', and 'pdf'. The format is taken as the extension of the filename or as the supplied format. positional arguments: - figure_or_data: The figure dict-like or data list-like object that describes a plotly figure. Same argument used in `py.plot`, `py.iplot`, see https://plot.ly/python for examples - filename: The filepath to save the image to - format: 'png', 'svg', 'jpeg', 'pdf' - width: output width - height: output height - scale: Increase the resolution of the image by `scale` amount Only valid for PNG and JPEG images. example: ``` import plotly.plotly as py fig = {'data': [{'x': [1, 2, 3], 'y': [3, 1, 5], 'type': 'bar'}]} py.image.save_as(fig, 'my_image.png', scale=3) ``` """ # todo: format shadows built-in name (base, ext) = os.path.splitext(filename) if not ext and not format: filename += '.png' elif ext and not format: format = ext[1:] elif not ext and format: filename += '.' + format img = cls.get(figure_or_data, format, width, height, scale) f = open(filename, 'wb') f.write(img) f.close() class file_ops: """ Interface to Plotly's File System API """ @classmethod def mkdirs(cls, folder_path): """ Create folder(s) specified by folder_path in your Plotly account. If the intermediate directories do not exist, they will be created. If they already exist, no error will be thrown. Mimics the shell's mkdir -p. Returns: - 200 if folders already existed, nothing was created - 201 if path was created Raises: - exceptions.PlotlyRequestError with status code 400 if the path already exists. Usage: >> mkdirs('new folder') >> mkdirs('existing folder/new folder') >> mkdirs('new/folder/path') """ # trim trailing slash TODO: necessesary? if folder_path[-1] == '/': folder_path = folder_path[0:-1] payload = { 'path': folder_path } url = _api_v2.api_url('folders') res = requests.post(url, data=payload, headers=_api_v2.headers(), verify=get_config()['plotly_ssl_verification']) _api_v2.response_handler(res) return res.status_code class grid_ops: """ Interface to Plotly's Grid API. Plotly Grids are Plotly's tabular data object, rendered in an online spreadsheet. Plotly graphs can be made from references of columns of Plotly grid objects. Free-form JSON Metadata can be saved with Plotly grids. To create a Plotly grid in your Plotly account from Python, see `grid_ops.upload`. To add rows or columns to an existing Plotly grid, see `grid_ops.append_rows` and `grid_ops.append_columns` respectively. To delete one of your grid objects, see `grid_ops.delete`. """ @classmethod def _fill_in_response_column_ids(cls, request_columns, response_columns, grid_id): for req_col in request_columns: for resp_col in response_columns: if resp_col['name'] == req_col.name: req_col.id = '{0}/{1}'.format(grid_id, resp_col['uid']) response_columns.remove(resp_col) @classmethod def upload(cls, grid, filename, world_readable=True, auto_open=True, meta=None): """ Upload a grid to your Plotly account with the specified filename. Positional arguments: - grid: A plotly.grid_objs.Grid object, call `help(plotly.grid_ops.Grid)` for more info. - filename: Name of the grid to be saved in your Plotly account. To save a grid in a folder in your Plotly account, separate specify a filename with folders and filename separated by backslashes (`/`). If a grid, plot, or folder already exists with the same filename, a `plotly.exceptions.RequestError` will be thrown with status_code 409 Optional keyword arguments: - world_readable (default=True): make this grid publically (True) or privately (False) viewable. - auto_open (default=True): Automatically open this grid in the browser (True) - meta (default=None): Optional Metadata to associate with this grid. Metadata is any arbitrary JSON-encodable object, for example: `{"experiment name": "GaAs"}` Filenames must be unique. To overwrite a grid with the same filename, you'll first have to delete the grid with the blocking name. See `plotly.plotly.grid_ops.delete`. Usage example 1: Upload a plotly grid ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') ``` Usage example 2: Make a graph based with data that is sourced from a newly uploaded Plotly grid ``` import plotly.plotly as py from plotly.grid_objs import Grid, Column from plotly.graph_objs import Scatter # Upload a grid column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') # Build a Plotly graph object sourced from the # grid's columns trace = Scatter(xsrc=grid[0], ysrc=grid[1]) py.plot([trace], filename='graph from grid') ``` """ # Make a folder path if filename[-1] == '/': filename = filename[0:-1] paths = filename.split('/') parent_path = '/'.join(paths[0:-1]) filename = paths[-1] if parent_path != '': file_ops.mkdirs(parent_path) # transmorgify grid object into plotly's format grid_json = grid._to_plotly_grid_json() if meta is not None: grid_json['metadata'] = meta payload = { 'filename': filename, 'data': json.dumps(grid_json, cls=utils.PlotlyJSONEncoder), 'world_readable': world_readable } if parent_path != '': payload['parent_path'] = parent_path upload_url = _api_v2.api_url('grids') req = requests.post(upload_url, data=payload, headers=_api_v2.headers(), verify=get_config()['plotly_ssl_verification']) res = _api_v2.response_handler(req) response_columns = res['file']['cols'] grid_id = res['file']['fid'] grid_url = res['file']['web_url'] # mutate the grid columns with the id's returned from the server cls._fill_in_response_column_ids(grid, response_columns, grid_id) grid.id = grid_id if meta is not None: meta_ops.upload(meta, grid=grid) if auto_open: _open_url(grid_url) return grid_url @classmethod def append_columns(cls, columns, grid=None, grid_url=None): """ Append columns to a Plotly grid. `columns` is an iterable of plotly.grid_objs.Column objects and only one of `grid` and `grid_url` needs to specified. `grid` is a ploty.grid_objs.Grid object that has already been uploaded to plotly with the grid_ops.upload method. `grid_url` is a unique URL of a `grid` in your plotly account. Usage example 1: Upload a grid to Plotly, and then append a column ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') grid = Grid([column_1]) py.grid_ops.upload(grid, 'time vs voltage') # append a column to the grid column_2 = Column([4, 2, 5], 'voltage') py.grid_ops.append_columns([column_2], grid=grid) ``` Usage example 2: Append a column to a grid that already exists on Plotly ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py grid_url = 'https://plot.ly/~chris/3143' column_1 = Column([1, 2, 3], 'time') py.grid_ops.append_columns([column_1], grid_url=grid_url) ``` """ grid_id = _api_v2.parse_grid_id_args(grid, grid_url) # Verify unique column names column_names = [c.name for c in columns] if grid: existing_column_names = [c.name for c in grid] column_names.extend(existing_column_names) duplicate_name = utils.get_first_duplicate(column_names) if duplicate_name: err = exceptions.NON_UNIQUE_COLUMN_MESSAGE.format(duplicate_name) raise exceptions.InputError(err) payload = { 'cols': json.dumps(columns, cls=utils.PlotlyJSONEncoder) } api_url = (_api_v2.api_url('grids') + '/{grid_id}/col'.format(grid_id=grid_id)) res = requests.post(api_url, data=payload, headers=_api_v2.headers(), verify=get_config()['plotly_ssl_verification']) res = _api_v2.response_handler(res) cls._fill_in_response_column_ids(columns, res['cols'], grid_id) if grid: grid.extend(columns) @classmethod def append_rows(cls, rows, grid=None, grid_url=None): """ Append rows to a Plotly grid. `rows` is an iterable of rows, where each row is a list of numbers, strings, or dates. The number of items in each row must be equal to the number of columns in the grid. If appending rows to a grid with columns of unequal length, Plotly will fill the columns with shorter length with empty strings. Only one of `grid` and `grid_url` needs to specified. `grid` is a ploty.grid_objs.Grid object that has already been uploaded to plotly with the grid_ops.upload method. `grid_url` is a unique URL of a `grid` in your plotly account. Usage example 1: Upload a grid to Plotly, and then append rows ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') column_2 = Column([5, 2, 7], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') # append a row to the grid row = [1, 5] py.grid_ops.append_rows([row], grid=grid) ``` Usage example 2: Append a row to a grid that already exists on Plotly ``` from plotly.grid_objs import Grid import plotly.plotly as py grid_url = 'https://plot.ly/~chris/3143' row = [1, 5] py.grid_ops.append_rows([row], grid=grid_url) ``` """ grid_id = _api_v2.parse_grid_id_args(grid, grid_url) if grid: n_columns = len([column for column in grid]) for row_i, row in enumerate(rows): if len(row) != n_columns: raise exceptions.InputError( "The number of entries in " "each row needs to equal the number of columns in " "the grid. Row {0} has {1} {2} but your " "grid has {3} {4}. " .format(row_i, len(row), 'entry' if len(row) == 1 else 'entries', n_columns, 'column' if n_columns == 1 else 'columns')) payload = { 'rows': json.dumps(rows, cls=utils.PlotlyJSONEncoder) } api_url = (_api_v2.api_url('grids') + '/{grid_id}/row'.format(grid_id=grid_id)) res = requests.post(api_url, data=payload, headers=_api_v2.headers(), verify=get_config()['plotly_ssl_verification']) _api_v2.response_handler(res) if grid: longest_column_length = max([len(col.data) for col in grid]) for column in grid: n_empty_rows = longest_column_length - len(column.data) empty_string_rows = ['' for _ in range(n_empty_rows)] column.data.extend(empty_string_rows) column_extensions = zip(*rows) for local_column, column_extension in zip(grid, column_extensions): local_column.data.extend(column_extension) @classmethod def delete(cls, grid=None, grid_url=None): """ Delete a grid from your Plotly account. Only one of `grid` or `grid_url` needs to be specified. `grid` is a plotly.grid_objs.Grid object that has already been uploaded to Plotly. `grid_url` is the URL of the Plotly grid to delete Usage example 1: Upload a grid to plotly, then delete it ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') # now delete it, and free up that filename py.grid_ops.delete(grid) ``` Usage example 2: Delete a plotly grid by url ``` import plotly.plotly as py grid_url = 'https://plot.ly/~chris/3' py.grid_ops.delete(grid_url=grid_url) ``` """ grid_id = _api_v2.parse_grid_id_args(grid, grid_url) api_url = _api_v2.api_url('grids') + '/' + grid_id res = requests.delete(api_url, headers=_api_v2.headers(), verify=get_config()['plotly_ssl_verification']) _api_v2.response_handler(res) class meta_ops: """ Interface to Plotly's Metadata API. In Plotly, Metadata is arbitrary, free-form JSON data that is associated with Plotly grids. Metadata is viewable with any grid that is shared and grids are searchable by key value pairs in the Metadata. Metadata is any JSON-encodable object. To upload Metadata, either use the optional keyword argument `meta` in the `py.grid_ops.upload` method, or use `py.meta_ops.upload`. """ @classmethod def upload(cls, meta, grid=None, grid_url=None): """ Upload Metadata to a Plotly grid. Metadata is any JSON-encodable object. For example, a dictionary, string, or list. Only one of `grid` or `grid_url` needs to be specified. `grid` is a plotly.grid_objs.Grid object that has already been uploaded to Plotly. `grid_url` is the URL of the Plotly grid to attach Metadata to. Usage example 1: Upload a grid to Plotly, then attach Metadata to it ``` from plotly.grid_objs import Grid, Column import plotly.plotly as py column_1 = Column([1, 2, 3], 'time') column_2 = Column([4, 2, 5], 'voltage') grid = Grid([column_1, column_2]) py.grid_ops.upload(grid, 'time vs voltage') # now attach Metadata to the grid meta = {'experment': 'GaAs'} py.meta_ops.upload(meta, grid=grid) ``` Usage example 2: Upload Metadata to an existing Plotly grid ``` import plotly.plotly as py grid_url = 'https://plot.ly/~chris/3143' meta = {'experment': 'GaAs'} py.meta_ops.upload(meta, grid_url=grid_Url) ``` """ grid_id = _api_v2.parse_grid_id_args(grid, grid_url) payload = { 'metadata': json.dumps(meta, cls=utils.PlotlyJSONEncoder) } api_url = _api_v2.api_url('grids') + '/{grid_id}'.format(grid_id=grid_id) res = requests.patch(api_url, data=payload, headers=_api_v2.headers(), verify=get_config()['plotly_ssl_verification']) return _api_v2.response_handler(res) class _api_v2: """ Request and response helper class for communicating with Plotly's v2 API """ @classmethod def parse_grid_id_args(cls, grid, grid_url): """ Return the grid_id from the non-None input argument. Raise an error if more than one argument was supplied. """ if grid is not None: id_from_grid = grid.id else: id_from_grid = None args = [id_from_grid, grid_url] arg_names = ('grid', 'grid_url') supplied_arg_names = [arg_name for arg_name, arg in zip(arg_names, args) if arg is not None] if not supplied_arg_names: raise exceptions.InputError( "One of the two keyword arguments is required:\n" " `grid` or `grid_url`\n\n" "grid: a plotly.graph_objs.Grid object that has already\n" " been uploaded to Plotly.\n\n" "grid_url: the url where the grid can be accessed on\n" " Plotly, e.g. 'https://plot.ly/~chris/3043'\n\n" ) elif len(supplied_arg_names) > 1: raise exceptions.InputError( "Only one of `grid` or `grid_url` is required. \n" "You supplied both. \n" ) else: supplied_arg_name = supplied_arg_names.pop() if supplied_arg_name == 'grid_url': path = six.moves.urllib.parse.urlparse(grid_url).path file_owner, file_id = path.replace("/~", "").split('/')[0:2] return '{0}:{1}'.format(file_owner, file_id) else: return grid.id @classmethod def response_handler(cls, response): try: response.raise_for_status() except requests.exceptions.HTTPError as requests_exception: if (response.status_code == 404 and get_config()['plotly_api_domain'] != tools.get_config_defaults()['plotly_api_domain']): raise exceptions.PlotlyError( "This endpoint is unavailable at {url}. If you are using " "Plotly Enterprise, you may need to upgrade your Plotly " "Enterprise server to request against this endpoint or " "this endpoint may not be available yet.\nQuestions? " "support@plot.ly or your plotly administrator." .format(url=get_config()['plotly_api_domain']) ) else: raise requests_exception if ('content-type' in response.headers and 'json' in response.headers['content-type'] and len(response.content) > 0): response_dict = json.loads(response.content.decode('utf8')) if 'warnings' in response_dict and len(response_dict['warnings']): warnings.warn('\n'.join(response_dict['warnings'])) return response_dict @classmethod def api_url(cls, resource): return ('{0}/v2/{1}'.format(get_config()['plotly_api_domain'], resource)) @classmethod def headers(cls): credentials = get_credentials() # todo, validate here? username, api_key = credentials['username'], credentials['api_key'] encoded_api_auth = base64.b64encode(six.b('{0}:{1}'.format( username, api_key))).decode('utf8') headers = { 'plotly-client-platform': 'python {0}'.format(version.__version__) } if get_config()['plotly_proxy_authorization']: proxy_username = credentials['proxy_username'] proxy_password = credentials['proxy_password'] encoded_proxy_auth = base64.b64encode(six.b('{0}:{1}'.format( proxy_username, proxy_password))).decode('utf8') headers['authorization'] = 'Basic ' + encoded_proxy_auth headers['plotly-authorization'] = 'Basic ' + encoded_api_auth else: headers['authorization'] = 'Basic ' + encoded_api_auth return headers def validate_credentials(credentials): """ Currently only checks for truthy username and api_key """ username = credentials.get('username') api_key = credentials.get('api_key') if not username or not api_key: raise exceptions.PlotlyLocalCredentialsError() def add_share_key_to_url(plot_url, attempt=0): """ Update plot's url to include the secret key """ urlsplit = six.moves.urllib.parse.urlparse(plot_url) file_owner = urlsplit.path.split('/')[1].split('~')[1] file_id = urlsplit.path.split('/')[2] url = _api_v2.api_url("files/") + file_owner + ":" + file_id new_response = requests.patch(url, headers=_api_v2.headers(), data={"share_key_enabled": "True", "world_readable": "False"}) _api_v2.response_handler(new_response) # decode bytes for python 3.3: https://bugs.python.org/issue10976 str_content = new_response.content.decode('utf-8') new_response_data = json.loads(str_content) plot_url += '?share_key=' + new_response_data['share_key'] # sometimes a share key is added, but access is still denied # check for access, and retry a couple of times if this is the case # https://github.com/plotly/streambed/issues/4089 embed_url = plot_url.split('?')[0] + '.embed' + plot_url.split('?')[1] access_res = requests.get(embed_url) if access_res.status_code == 404: attempt += 1 if attempt == 5: return plot_url plot_url = add_share_key_to_url(plot_url.split('?')[0], attempt) return plot_url def _send_to_plotly(figure, **plot_options): """ """ fig = tools._replace_newline(figure) # does not mutate figure data = json.dumps(fig['data'] if 'data' in fig else [], cls=utils.PlotlyJSONEncoder) credentials = get_credentials() validate_credentials(credentials) username = credentials['username'] api_key = credentials['api_key'] kwargs = json.dumps(dict(filename=plot_options['filename'], fileopt=plot_options['fileopt'], world_readable=plot_options['world_readable'], sharing=plot_options['sharing'], layout=fig['layout'] if 'layout' in fig else {}), cls=utils.PlotlyJSONEncoder) # TODO: It'd be cool to expose the platform for RaspPi and others payload = dict(platform='python', version=version.__version__, args=data, un=username, key=api_key, origin='plot', kwargs=kwargs) url = get_config()['plotly_domain'] + "/clientresp" r = requests.post(url, data=payload, verify=get_config()['plotly_ssl_verification']) r.raise_for_status() r = json.loads(r.text) if 'error' in r and r['error'] != '': raise exceptions.PlotlyError(r['error']) # Check if the url needs a secret key if (plot_options['sharing'] == 'secret' and 'share_key=' not in r['url']): # add_share_key_to_url updates the url to include the share_key r['url'] = add_share_key_to_url(r['url']) if 'error' in r and r['error'] != '': print(r['error']) if 'warning' in r and r['warning'] != '': warnings.warn(r['warning']) if 'message' in r and r['message'] != '': print(r['message']) return r def _open_url(url): try: from webbrowser import open as wbopen wbopen(url) except: # TODO: what should we except here? this is dangerous pass plotly-1.9.5+dfsg.orig/plotly/session.py0000644000175000017500000001237512645550357017663 0ustar noahfxnoahfx""" The session module handles the user's current credentials, config and plot opts This allows users to dynamically change which plotly domain they're using, which user they're signed in as, and plotting defaults. """ from __future__ import absolute_import import copy import six from plotly import exceptions _session = { 'credentials': {}, 'config': {}, 'plot_options': {} } CREDENTIALS_KEYS = { 'username': six.string_types, 'api_key': six.string_types, 'stream_ids': list } CONFIG_KEYS = { 'plotly_domain': six.string_types, 'plotly_streaming_domain': six.string_types, 'plotly_api_domain': six.string_types, 'plotly_ssl_verification': bool, 'plotly_proxy_authorization': bool, 'world_readable': bool, 'auto_open': bool, 'sharing': six.string_types } PLOT_OPTIONS = { 'filename': six.string_types, 'fileopt': six.string_types, 'validate': bool, 'world_readable': bool, 'auto_open': bool, 'sharing': six.string_types } SHARING_OPTIONS = ['public', 'private', 'secret'] def sign_in(username, api_key, **kwargs): """ Set set session credentials and config (not saved to file). If unspecified, credentials and config are searched for in `.plotly` dir. :param (str) username: The username you'd use to sign in to Plotly :param (str) api_key: The api key associated with above username :param (list|optional) stream_ids: Stream tokens for above credentials :param (str|optional) proxy_username: The un associated with with your Proxy :param (str|optional) proxy_password: The pw associated with your Proxy un :param (str|optional) plotly_domain: :param (str|optional) plotly_streaming_domain: :param (str|optional) plotly_api_domain: :param (bool|optional) plotly_ssl_verification: :param (bool|optional) plotly_proxy_authorization: :param (bool|optional) world_readable: """ # TODO: verify these _credentials with plotly # kwargs will contain all our info kwargs.update(username=username, api_key=api_key) # raise error if key isn't valid anywhere for key in kwargs: if key not in CREDENTIALS_KEYS and key not in CONFIG_KEYS: raise exceptions.PlotlyError( "{} is not a valid config or credentials key".format(key) ) # add credentials, raise error if type is wrong. for key in CREDENTIALS_KEYS: if key in kwargs: if not isinstance(kwargs[key], CREDENTIALS_KEYS[key]): raise exceptions.PlotlyError( "{} must be of type '{}'" .format(key, CREDENTIALS_KEYS[key]) ) _session['credentials'][key] = kwargs[key] # add config, raise error if type is wrong. for key in CONFIG_KEYS: if key in kwargs: if not isinstance(kwargs[key], CONFIG_KEYS[key]): raise exceptions.PlotlyError("{} must be of type '{}'" .format(key, CONFIG_KEYS[key])) _session['config'][key] = kwargs.get(key) # add plot options, raise error if type is wrong. for key in PLOT_OPTIONS: if key in kwargs: if not isinstance(kwargs[key], CONFIG_KEYS[key]): raise exceptions.PlotlyError("{} must be of type '{}'" .format(key, CONFIG_KEYS[key])) _session['plot_options'][key] = kwargs.get(key) def update_session_plot_options(**kwargs): """ Update the _session plot_options :param (str|optional) filename: What the file will be named in Plotly :param (str|optional) fileopt: 'overwrite', 'append', 'new', or 'extend' :param (bool|optional) world_readable: Make public or private. :param (dict|optional) sharing: 'public', 'private', 'secret' :param (bool|optional) auto_open: For `plot`, open in new browser tab? :param (bool|optional) validate: Error locally if data doesn't pass? """ # raise exception if key is invalid or value is the wrong type for key in kwargs: if key not in PLOT_OPTIONS: raise exceptions.PlotlyError( "{} is not a valid config or plot option key".format(key) ) if not isinstance(kwargs[key], PLOT_OPTIONS[key]): raise exceptions.PlotlyError("{} must be of type '{}'" .format(key, PLOT_OPTIONS[key])) # raise exception if sharing is invalid if (key == 'sharing' and not (kwargs[key] in SHARING_OPTIONS)): raise exceptions.PlotlyError("'{0}' must be of either '{1}', '{2}'" " or '{3}'" .format(key, *SHARING_OPTIONS)) # update local _session dict with new plot options _session['plot_options'].update(kwargs) def get_session_plot_options(): """ Returns a copy of the user supplied plot options. Use `update_plot_options()` to change. """ return copy.deepcopy(_session['plot_options']) def get_session_config(): """Returns either module config or file config.""" return copy.deepcopy(_session['config']) def get_session_credentials(): """Returns the credentials that will be sent to plotly.""" return copy.deepcopy(_session['credentials']) plotly-1.9.5+dfsg.orig/plotly/files.py0000644000175000017500000000302212645550357017267 0ustar noahfxnoahfximport os # file structure PLOTLY_DIR = os.path.join(os.path.expanduser("~"), ".plotly") CREDENTIALS_FILE = os.path.join(PLOTLY_DIR, ".credentials") CONFIG_FILE = os.path.join(PLOTLY_DIR, ".config") GRAPH_REFERENCE_FILE = os.path.join(PLOTLY_DIR, ".graph_reference") TEST_DIR = os.path.join(os.path.expanduser("~"), ".test") TEST_FILE = os.path.join(PLOTLY_DIR, ".permission_test") # this sets both the DEFAULTS and the TYPES for these files FILE_CONTENT = {CREDENTIALS_FILE: {'username': '', 'api_key': '', 'proxy_username': '', 'proxy_password': '', 'stream_ids': []}, CONFIG_FILE: {'plotly_domain': 'https://plot.ly', 'plotly_streaming_domain': 'stream.plot.ly', 'plotly_api_domain': 'https://api.plot.ly', 'plotly_ssl_verification': True, 'plotly_proxy_authorization': False, 'world_readable': True, 'sharing': 'public', 'auto_open': True}} try: os.mkdir(TEST_DIR) os.rmdir(TEST_DIR) if not os.path.exists(PLOTLY_DIR): os.mkdir(PLOTLY_DIR) f = open(TEST_FILE, 'w') f.write('testing\n') f.close() os.remove(TEST_FILE) _file_permissions = True except: _file_permissions = False def check_file_permissions(): return _file_permissions plotly-1.9.5+dfsg.orig/setup.cfg0000644000175000017500000000014512647020776016113 0ustar noahfxnoahfx[metadata] description-file = README.rst [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 plotly-1.9.5+dfsg.orig/plotly.egg-info/0000755000175000017500000000000012647020776017307 5ustar noahfxnoahfxplotly-1.9.5+dfsg.orig/plotly.egg-info/SOURCES.txt0000644000175000017500000000267612647020776021206 0ustar noahfxnoahfxREADME.rst setup.cfg setup.py plotly/__init__.py plotly/exceptions.py plotly/files.py plotly/graph_reference.py plotly/session.py plotly/tools.py plotly/utils.py plotly/version.py plotly.egg-info/PKG-INFO plotly.egg-info/SOURCES.txt plotly.egg-info/dependency_links.txt plotly.egg-info/not-zip-safe plotly.egg-info/requires.txt plotly.egg-info/top_level.txt plotly/graph_objs/__init__.py plotly/graph_objs/graph_objs.py plotly/graph_objs/graph_objs_tools.py plotly/graph_reference/default-schema.json plotly/grid_objs/__init__.py plotly/grid_objs/grid_objs.py plotly/matplotlylib/__init__.py plotly/matplotlylib/mpltools.py plotly/matplotlylib/renderer.py plotly/matplotlylib/mplexporter/__init__.py plotly/matplotlylib/mplexporter/_py3k_compat.py plotly/matplotlylib/mplexporter/exporter.py plotly/matplotlylib/mplexporter/tools.py plotly/matplotlylib/mplexporter/utils.py plotly/matplotlylib/mplexporter/renderers/__init__.py plotly/matplotlylib/mplexporter/renderers/base.py plotly/matplotlylib/mplexporter/renderers/fake_renderer.py plotly/matplotlylib/mplexporter/renderers/vega_renderer.py plotly/matplotlylib/mplexporter/renderers/vincent_renderer.py plotly/offline/__init__.py plotly/offline/offline.py plotly/offline/plotly.min.js plotly/plotly/__init__.py plotly/plotly/plotly.py plotly/plotly/chunked_requests/__init__.py plotly/plotly/chunked_requests/chunked_request.py plotly/widgets/__init__.py plotly/widgets/graphWidget.js plotly/widgets/graph_widget.pyplotly-1.9.5+dfsg.orig/plotly.egg-info/PKG-INFO0000644000175000017500000001142312647020776020405 0ustar noahfxnoahfxMetadata-Version: 1.1 Name: plotly Version: 1.9.5 Summary: Python plotting library for collaborative, interactive, publication-quality graphs. Home-page: https://plot.ly/python/ Author: Chris P Author-email: chris@plot.ly License: MIT Description: ======= plotly: ======= -------------------------- It's all about the graphs. -------------------------- The Nutshell ~~~~~~~~~~~~ Use this package to make collaborative, interactive, publication-quality graphs from Python. Here's how you import:: import plotly.plotly as py # for sending things to plotly import plotly.tools as tls # for mpl, config, etc. from plotly.graph_objs import * # __all__ is safely defined Here's how you sign in:: py.sign_in('PythonAPI', 'ubpiol2cve') # get your own at https://plot.ly/ Here's how you plot data or a figure:: py.plot(data_or_figure_here) Here's what you get: * an account on plotly * a unique url for your data/figures * an interactive web-application to edit your figure or make new figures * a platform on which to share your data/figures with the world You can also convert supported matplotlib figures:: py.plot_mpl(mplfig) Stop fighting with your figures; start designing them. Check out our Quickstart_ to get going. About ~~~~~ Plotly_ is an online collaborative data analysis and graphing tool. The Python API allows you to access all of Plotly's functionality from Python. Plotly figures are shared, tracked, and edited all online and the data is always accessible from the graph. That's it. Find out more, sign up, and start sharing by visiting us at https://plot.ly. Install via pip ~~~~~~~~~~~~~~~ Assuming you have already installed pip, you can simply enter the following in a terminal program:: $ pip install plotly Contributing! ~~~~~~~~~~~~~ If you want to contribute to making Plotly's Python API experience better, head to our `GitHub repo`_. Instructions for installing from here, updating the included submodules, and contributing are detailed there! Plotly, matplotlib, and mpld3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The matplotlylib sub-package allows you to convert matplotlib figures to plotly figures, with a one-liner:: py.plot_mpl(fig) Checkout the `Plotly and mpld3`_ IPython notebook for more infomataion. Introduction to working with out API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checkout the `Plotly and Python`_ IPython notebook to get a more in depth exposition of our Python API. Plotly's *guide book* ~~~~~~~~~~~~~~~~~~~~~ Still here? Don't worry, we've got more documentation for you. Checkout a *highly* complete `set of notebooks`_ for walk-throughs on all the features we offer! Details ~~~~~~~ The plotly package depends on requests, which will be installed by pip for you. To use the matplotlylib subpackage, you'll also need to have matplotlib 1.3.1 properly installed on your machine. The matpotlylib package is based on the mplexporter framework for crawling and exporting matplotlib images. Created by: Plotly_, `@plotlygraphs`_, `feedback@plot.ly`_ License: MIT .. _Plotly: https://plot.ly .. _Quickstart: https://plot.ly/python .. _GitHub repo: https://github.com/plotly/python-api .. _Plotly and mpld3: https://plot.ly/python/matplotlib-to-plotly-tutorial/ .. _Plotly and Python: https://plot.ly/python/overview/ .. _set of notebooks: https://plot.ly/python/user-guide/ .. _plotly profile: https://plot.ly/~mpld3/ .. _@plotlygraphs: https://twitter.com/plotlygraphs .. _feedback@plot.ly: feedback@plot.ly Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Topic :: Scientific/Engineering :: Visualization plotly-1.9.5+dfsg.orig/plotly.egg-info/dependency_links.txt0000644000175000017500000000000112647020776023355 0ustar noahfxnoahfx plotly-1.9.5+dfsg.orig/plotly.egg-info/requires.txt0000644000175000017500000000002212647020776021701 0ustar noahfxnoahfxrequests six pytz plotly-1.9.5+dfsg.orig/plotly.egg-info/top_level.txt0000644000175000017500000000032312647020776022037 0ustar noahfxnoahfxplotly plotly/graph_objs plotly/grid_objs plotly/matplotlylib plotly/matplotlylib/mplexporter plotly/matplotlylib/mplexporter/renderers plotly/offline plotly/plotly plotly/plotly/chunked_requests plotly/widgets plotly-1.9.5+dfsg.orig/plotly.egg-info/not-zip-safe0000644000175000017500000000000112647020776021535 0ustar noahfxnoahfx