diff --git a/.gitignore b/.gitignore index 5bb4e110325..203c5234d37 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ tests/test_orca/images/linux/failed/ doc/python/raw.githubusercontent.com/ +docs/ +docs_tmp/ + # Don't ignore dataset files !*.csv.gz !*.geojson.gz @@ -59,6 +62,8 @@ doc/python/.mapbox_token doc/.ipynb_checkpoints tags doc/check-or-enforce-order.py +files.figshare.com +*.zip tests/percy/*.html tests/percy/pandas2/*.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad666ea805c..f4cfaf94447 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ then explains the technical aspects of preparing your contribution. ## Code of Conduct -Please note that all contributos are required to abide by our [Code of Conduct](CODE_OF_CONDUCT.md). +Please note that all contributos are required to abide by our Code of Conduct. ## Different Ways to Contribute @@ -19,7 +19,7 @@ it is important to understand the structure of the code and the repository. - The [`plotly.graph_objects`](https://plotly.com/python/graph-objects/) module (usually imported as `go`) is [generated from the plotly.js schema](https://plotly.com/python/figure-structure/), so changes to be made in this package need to be contributed to [plotly.js](https://github.com/plotly/plotly.js) - or to the code generation system in `./codegen/`. + or to the code generation system in `./bin/codegen/`. Code generation creates traces and layout classes that have a direct correspondence to their JavaScript counterparts, while higher-level methods that work on figures regardless of the current schema (e.g., `BaseFigure.for_each_trace`) are defined in `plotly/basedatatypes.py`. @@ -38,16 +38,17 @@ it is important to understand the structure of the code and the repository. These are organized in subdirectories according to what they test: see the "Setup" section below for more details. -- Documentation is found in `doc/`, and its structure is described in [its README file](doc/README.md). +- Documentation is found in `doc/`, and its structure is described in its README file. The documentation is a great place to start contributing, since you can add or modify examples without setting up a full environment. -Code and documentation are not the only way to contribute: -you can also help by: +Code and documentation are not the only way to contribute. +You can also help by: - Reporting bugs at . Please take a moment to see if your problem has already been reported, and if so, add a comment to the existing issue; - we will try to prioritize those that affect the most people. + we will try to prioritize those that affect the most people + and that are accompanied by small, runnable examples. - Submitting feature requests (also at ). Again, please add a comment to an existing issue if the feature you want has already been requested. @@ -219,11 +220,11 @@ Once you have done that, run the `updateplotlyjs` command: ```bash -python commands.py updateplotlyjs +python bin/updatejs.py ``` This downloads new versions of `plot-schema.json` and `plotly.min.js` from the `plotly/plotly.js` GitHub repository -and places them in `plotly/package_data`. +and places them in `resources` and `plotly/package_data` respectively. It then regenerates all of the `graph_objs` classes based on the new schema. ### Using a Development Branch of Plotly.js @@ -232,7 +233,8 @@ If your development branch is in [the plotly.js repository](https://github.com/p you can update to development versions of `plotly.js` with this command: ```bash -python commands.py updateplotlyjsdev --devrepo reponame --devbranch branchname +# FIXME commands.py didn't provide --devrepo or --devbranch +python bin/updatejs.py --dev --devrepo reponame --devbranch branchname ``` This fetches the `plotly.js` in the CircleCI artifact of the branch `branchname` of the repo `reponame`. @@ -255,5 +257,6 @@ You can then run the following command *in your local plotly.py repository*: ```bash -python commands.py updateplotlyjsdev --local /path/to/your/plotly.js/ +# FIXME: commands.py didn't provide --local +python bin/updatejs.py --dev --local /path/to/your/plotly.js/ ``` diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..6f03affc55f --- /dev/null +++ b/Makefile @@ -0,0 +1,80 @@ +# Manage plotly.py project. + +RUN = uv run +PACKAGE_DIRS = _plotly_utils plotly +CODE_DIRS = ${PACKAGE_DIRS} scripts +EXAMPLE_SRC = $(wildcard doc/python/*.md) +EXAMPLE_DST = $(patsubst doc/python/%.md,pages/examples/%.md,${EXAMPLE_SRC}) +MKDOCS_TEMP_DIR = ./docs_tmp + +## commands: show available commands +commands: + @grep -h -E '^##' ${MAKEFILE_LIST} | sed -e 's/## //g' | column -t -s ':' + +## docs: rebuild documentation +.PHONY: docs +docs: + ${RUN} mkdocs build + +## docs-lint: check documentation +docs-lint: + ${RUN} pydoclint ${PACKAGE_DIRS} + +## docs-tmp: rebuild documentation saving Markdown in ./tmp +docs-tmp: + @rm -rf ${MKDOCS_TEMP_DIR} + MKDOCS_TEMP_DIR=${MKDOCS_TEMP_DIR} ${RUN} mkdocs build + +## examples: generate Markdown for individual doc/python +examples: ${EXAMPLE_DST} + +pages/examples/%.md: doc/python/%.md + @mkdir -p pages/examples + ${RUN} bin/run_markdown.py --outdir pages/examples --inline --verbose 2 $< + +## examples-force: force complete rebuild of examples +examples-force: + touch ${EXAMPLES_SRC} + make examples + +## examples-toc: generate YAML table of contents for examples +examples-toc: + @python bin/build_example_toc.py ${EXAMPLE_SRC} + +## format: reformat code +format: + ${RUN} ruff format ${CODE_DIRS} + +## generate: generate code +generate: + ${RUN} bin/generate_code.py --codedir plotly + ${RUN} ruff format plotly + +## lint: check the code +lint: + ${RUN} ruff check ${CODE_DIRS} + +## test: run tests +test: + ${RUN} pytest tests + +## updatejs: update JavaScript bundle +updatejs: + ${RUN} bin/updatejs.py --codedir plotly + +## --: -- + +## clean: clean up repository +clean: + @find . -name '*~' -delete + @find . -name '.DS_Store' -delete + @rm -rf .coverage + @rm -rf .pytest_cache + @rm -rf .ruff_cache + @rm -rf dist + @rm -rf docs + @rm -rf pages/examples + +## sync: update Python packages +sync: + uv sync --extra dev diff --git a/README.md b/README.md index 11f117aca59..8e6ef158f46 100644 --- a/README.md +++ b/README.md @@ -76,13 +76,13 @@ Built on top of [plotly.js](https://github.com/plotly/plotly.js), `plotly.py` is ## Installation -plotly.py may be installed using pip +plotly.py may be installed using pip: ``` pip install plotly ``` -or conda. +or conda: ``` conda install -c conda-forge plotly @@ -90,8 +90,7 @@ conda install -c conda-forge plotly ### Jupyter Widget Support -For use as a Jupyter widget, install `jupyter` and `anywidget` -packages using `pip`: +For use as a Jupyter widget, install the `jupyter` and `anywidget` packages using `pip`: ``` pip install jupyter anywidget @@ -112,14 +111,14 @@ command line utility (legacy as of `plotly` version 4.9). #### Kaleido -The [`kaleido`](https://github.com/plotly/Kaleido) package has no dependencies and can be installed -using pip +The [`kaleido`](https://github.com/plotly/Kaleido) package has no dependencies +and can be installed using pip: ``` pip install -U kaleido ``` -or conda +or conda: ``` conda install -c conda-forge python-kaleido @@ -129,13 +128,13 @@ conda install -c conda-forge python-kaleido Some plotly.py features rely on fairly large geographic shape files. The county choropleth figure factory is one such example. These shape files are distributed as a -separate `plotly-geo` package. This package can be installed using pip... +separate `plotly-geo` package. This package can be installed using pip: ``` pip install plotly-geo==1.0.0 ``` -or conda +or conda: ``` conda install -c plotly plotly-geo=1.0.0 @@ -145,7 +144,7 @@ conda install -c plotly plotly-geo=1.0.0 ## Copyright and Licenses -Code and documentation copyright 2019 Plotly, Inc. +Code and documentation copyright Plotly, Inc. Code released under the [MIT license](https://github.com/plotly/plotly.py/blob/main/LICENSE.txt). diff --git a/_plotly_utils/basevalidators.py b/_plotly_utils/basevalidators.py index 0d7e387bbc3..f36aa5c5aff 100644 --- a/_plotly_utils/basevalidators.py +++ b/_plotly_utils/basevalidators.py @@ -21,6 +21,9 @@ def fullmatch(regex, string, flags=0): regex_string = regex return re.match("(?:" + regex_string + r")\Z", string, flags=flags) +# Constants +INDENT = 8 + # Utility functions # ----------------- @@ -523,7 +526,9 @@ def description(self): enum_regexs = [] for v, regex in zip(self.values, self.val_regexs): if regex is not None: - enum_regexs.append(regex.pattern) + enum_pattern = regex.pattern + escaped_pattern = enum_pattern.replace("[", r"\[").replace("]", r"\]") + enum_regexs.append(escaped_pattern) else: enum_vals.append(v) desc = """\ @@ -535,16 +540,16 @@ def description(self): enum_vals_str = "\n".join( textwrap.wrap( repr(enum_vals), - initial_indent=" " * 12, - subsequent_indent=" " * 12, + initial_indent=" " * INDENT, + subsequent_indent=" " * INDENT, break_on_hyphens=False, ) ) desc = ( desc - + """ - - One of the following enumeration values: + + """\n + - One of the following enumeration values:\n {enum_vals_str}""".format(enum_vals_str=enum_vals_str) ) @@ -552,24 +557,25 @@ def description(self): enum_regexs_str = "\n".join( textwrap.wrap( repr(enum_regexs), - initial_indent=" " * 12, - subsequent_indent=" " * 12, + initial_indent=" " * INDENT, + subsequent_indent=" " * INDENT, break_on_hyphens=False, + break_long_words=False, ) ) desc = ( desc - + """ - - A string that matches one of the following regular expressions: + + """\n + - A string that matches one of the following regular expressions:\n {enum_regexs_str}""".format(enum_regexs_str=enum_regexs_str) ) if self.array_ok: desc = ( desc - + """ - - A tuple, list, or one-dimensional numpy array of the above""" + + """\n + - A tuple, list, or one-dimensional numpy array of the above""" ) return desc @@ -716,22 +722,22 @@ def __init__( def description(self): desc = """\ - The '{plotly_name}' property is a number and may be specified as:""".format( + The '{plotly_name}' property is a number and may be specified as:""".format( plotly_name=self.plotly_name ) if not self.has_min_max: desc = ( desc - + """ - - An int or float""" + + """\n + - An int or float""" ) else: desc = ( desc - + """ - - An int or float in the interval [{min_val}, {max_val}]""".format( + + """\n + - An int or float in the interval [{min_val}, {max_val}]""".format( min_val=self.min_val, max_val=self.max_val ) ) @@ -739,8 +745,8 @@ def description(self): if self.array_ok: desc = ( desc - + """ - - A tuple, list, or one-dimensional numpy array of the above""" + + """\n + - A tuple, list, or one-dimensional numpy array of the above""" ) return desc @@ -853,7 +859,7 @@ def __init__( def description(self): desc = """\ - The '{plotly_name}' property is a integer and may be specified as:""".format( + The '{plotly_name}' property is a integer and may be specified as:\n""".format( plotly_name=self.plotly_name ) @@ -861,12 +867,12 @@ def description(self): desc = ( desc + """ - - An int (or float that will be cast to an int)""" + - An int (or float that will be cast to an int)""" ) else: desc = desc + ( """ - - An int (or float that will be cast to an int) + - An int (or float that will be cast to an int) in the interval [{min_val}, {max_val}]""".format( min_val=self.min_val, max_val=self.max_val ) @@ -1007,44 +1013,44 @@ def description(self): if self.no_blank: desc = ( desc - + """ - - A non-empty string""" + + """\n + - A non-empty string""" ) elif self.values: valid_str = "\n".join( textwrap.wrap( repr(self.values), - initial_indent=" " * 12, - subsequent_indent=" " * 12, + initial_indent=" " * INDENT, + subsequent_indent=" " * INDENT, break_on_hyphens=False, ) ) desc = ( desc - + """ - - One of the following strings: + + """\n + - One of the following strings: {valid_str}""".format(valid_str=valid_str) ) else: desc = ( desc - + """ - - A string""" + + """\n + - A string""" ) if not self.strict: desc = ( desc - + """ - - A number that will be converted to a string""" + + """\n + - A number that will be converted to a string""" ) if self.array_ok: desc = ( desc - + """ - - A tuple, list, or one-dimensional numpy array of the above""" + + """\n + - A tuple, list, or one-dimensional numpy array of the above""" ) return desc @@ -1311,11 +1317,12 @@ def numbers_allowed(self): def description(self): valid_color_description = """\ The '{plotly_name}' property is a color and may be specified as: - - A hex string (e.g. '#ff0000') - - An rgb/rgba string (e.g. 'rgb(255,0,0)') - - An hsl/hsla string (e.g. 'hsl(0,100%,50%)') - - An hsv/hsva string (e.g. 'hsv(0,100%,100%)') - - A named CSS color: see https://plotly.com/python/css-colors/ for a list""".format( + + - A hex string (e.g. '#ff0000') + - An rgb/rgba string (e.g. 'rgb(255,0,0)') + - An hsl/hsla string (e.g. 'hsl(0,100%,50%)') + - An hsv/hsva string (e.g. 'hsv(0,100%,100%)') + - A named CSS color: see https://plotly.com/python/css-colors/ for a list""".format( plotly_name=self.plotly_name ) @@ -1323,15 +1330,15 @@ def description(self): valid_color_description = ( valid_color_description + """ - - A number that will be interpreted as a color - according to {colorscale_path}""".format(colorscale_path=self.colorscale_path) - ) + - A number that will be interpreted as a color according to {colorscale_path}""".format( + colorscale_path=self.colorscale_path) + ) if self.array_ok: valid_color_description = ( valid_color_description + """ - - A list or array of any of the above""" + - A list or array of any of the above""" ) return valid_color_description @@ -1553,8 +1560,8 @@ def description(self): colorscales_str = "\n".join( textwrap.wrap( repr(sorted(list(self.named_colorscales))), - initial_indent=" " * 12, - subsequent_indent=" " * 13, + initial_indent=" " * INDENT, + subsequent_indent=" " * INDENT, break_on_hyphens=False, width=80, ) @@ -1562,17 +1569,17 @@ def description(self): desc = """\ The '{plotly_name}' property is a colorscale and may be - specified as: - - A list of colors that will be spaced evenly to create the colorscale. + specified as:\n + - A list of colors that will be spaced evenly to create the colorscale. Many predefined colorscale lists are included in the sequential, diverging, and cyclical modules in the plotly.colors package. - - A list of 2-element lists where the first element is the + - A list of 2-element lists 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. (e.g. [[0, 'green'], [0.5, 'red'], [1.0, 'rgb(0, 0, 255)']]) - - One of the following named colorscales: -{colorscales_str}. - Appending '_r' to a named colorscale reverses it. + - One of the following named colorscales:\n +{colorscales_str}.\n + Appending '_r' to a named colorscale reverses it. """.format(plotly_name=self.plotly_name, colorscales_str=colorscales_str) return desc @@ -1810,13 +1817,13 @@ def description(self): desc = ( """\ The '{plotly_name}' property is a flaglist and may be specified - as a string containing:""" + as a string containing:\n""" ).format(plotly_name=self.plotly_name) # Flags desc = desc + ( """ - - Any combination of {flags} joined with '+' characters + - Any combination of {flags} joined with '+' characters (e.g. '{eg_flag}')""" ).format(flags=self.flags, eg_flag="+".join(self.flags[:2])) @@ -1831,7 +1838,7 @@ def description(self): desc = ( desc + """ - - A list or array of the above""" + - A list or array of the above""" ) return desc @@ -1983,17 +1990,18 @@ def description(self): # ### Case 1 ### if self.dimensions in (1, "1-2"): upto = " up to" if self.free_length and self.dimensions == 1 else "" - desc += """ - + desc += """\n * a list or tuple of{upto} {N} elements where:\ """.format(upto=upto, N=len(self.item_validators)) for i, item_validator in enumerate(self.item_validators): el_desc = item_validator.description().strip() + lines = el_desc.splitlines() + el_desc_indented = '\n'.join([lines[0]] + [' ' + line for line in lines[1:]]) desc = ( desc - + """ -({i}) {el_desc}""".format(i=i, el_desc=el_desc) + + """\n + ({i}) {el_desc_indented}""".format(i=i, el_desc_indented=el_desc_indented) ) # ### Case 2 ### @@ -2006,15 +2014,15 @@ def description(self): for i, item_validator in enumerate(self.item_validators): # Update name for 2d orig_name = item_validator.plotly_name - item_validator.plotly_name = "{name}[i][{i}]".format( + item_validator.plotly_name = "{name}\\\\[i\\\\]\\\\[{i}\\\\]".format( name=self.plotly_name, i=i ) el_desc = item_validator.description().strip() desc = ( desc - + """ -({i}) {el_desc}""".format(i=i, el_desc=el_desc) + + """\n + ({i}) {el_desc}""".format(i=i, el_desc=el_desc) ) item_validator.plotly_name = orig_name else: @@ -2028,21 +2036,28 @@ def description(self): el_desc = item_validator.description().strip() - desc += """ - * a list of elements where: - {el_desc} -""".format(el_desc=el_desc) + # Adds an indentation of 4 spaces, especially when el_desc + # is a fully auto-generated docstring with nested lists. + lines = el_desc.splitlines() + el_desc_indented = '\n'.join([lines[0]] + [' ' + line for line in lines[1:]]) + + desc += """\n + * a list of elements where:\n + {el_desc_indented} +""".format(el_desc_indented=el_desc_indented) if self.dimensions in ("1-2", 2): - item_validator.plotly_name = "{name}[i][j]".format( + item_validator.plotly_name = "{name}\\\\[i\\\\]\\\\[j\\\\]".format( name=self.plotly_name ) el_desc = item_validator.description().strip() - desc += """ - * a 2D list where: - {el_desc} -""".format(el_desc=el_desc) + lines = el_desc.splitlines() + el_desc_indented = '\n'.join([lines[0]] + [' ' + line for line in lines[1:]]) + desc += """\n + * a 2D list where:\n + {el_desc_indented} +""".format(el_desc_indented=el_desc_indented) item_validator.plotly_name = orig_name @@ -2273,8 +2288,8 @@ def description(self): enum_vals_str = "\n".join( textwrap.wrap( repr(enum_vals), - initial_indent=" " * 12, - subsequent_indent=" " * 12, + initial_indent=" " * INDENT, + subsequent_indent=" " * INDENT, break_on_hyphens=False, width=80, ) @@ -2282,16 +2297,16 @@ def description(self): desc = ( desc - + """ - - One of the following dash styles: + + """\n + - One of the following dash styles:\n {enum_vals_str}""".format(enum_vals_str=enum_vals_str) ) desc = ( desc - + """ - - A string containing a dash length list in pixels or percentages - (e.g. '5px 10px 2px 2px', '5, 10, 2, 2', '10% 20% 40%', etc.) + + """\n + - A string containing a dash length list in pixels or percentages\n + (e.g. '5px 10px 2px 2px', '5, 10, 2, 2', '10% 20% 40%', etc.) """ ) return desc @@ -2370,26 +2385,26 @@ def __init__(self, plotly_name, parent_name, data_class_str, data_docs, **kwargs @staticmethod def compute_graph_obj_module_str(data_class_str, parent_name): if parent_name == "frame" and data_class_str in ["Data", "Layout"]: - # Special case. There are no graph_objs.frame.Data or - # graph_objs.frame.Layout classes. These are remapped to - # graph_objs.Data and graph_objs.Layout + # Special case. There are no graph_objects.frame.Data or + # graph_objects.frame.Layout classes. These are remapped to + # graph_objects.Data and graph_objects.Layout parent_parts = parent_name.split(".") - module_str = ".".join(["plotly.graph_objs"] + parent_parts[1:]) + module_str = ".".join(["plotly.graph_objects"] + parent_parts[1:]) elif parent_name == "layout.template" and data_class_str == "Layout": # Remap template's layout to regular layout - module_str = "plotly.graph_objs" + module_str = "plotly.graph_objects" elif "layout.template.data" in parent_name: # Remap template's traces to regular traces parent_name = parent_name.replace("layout.template.data.", "") if parent_name: - module_str = "plotly.graph_objs." + parent_name + module_str = "plotly.graph_objects." + parent_name else: - module_str = "plotly.graph_objs" + module_str = "plotly.graph_objects" elif parent_name: - module_str = "plotly.graph_objs." + parent_name + module_str = "plotly.graph_objects." + parent_name else: - module_str = "plotly.graph_objs" + module_str = "plotly.graph_objects" return module_str @@ -2405,10 +2420,9 @@ def description(self): desc = ( """\ The '{plotly_name}' property is an instance of {class_str} - that may be specified as: - - An instance of :class:`{module_str}.{class_str}` - - A dict of string/value properties that will be passed - to the {class_str} constructor""" + that may be specified as:\n + - An instance of :class:`{module_str}.{class_str}` + - A dict of string/value properties that will be passed to the {class_str} constructor""" ).format( plotly_name=self.plotly_name, class_str=self.data_class_str, @@ -2477,9 +2491,9 @@ def description(self): desc = ( """\ The '{plotly_name}' property is a tuple of instances of - {class_str} that may be specified as: - - A list or tuple of instances of {module_str}.{class_str} - - A list or tuple of dicts of string/value properties that + {class_str} that may be specified as:\n + - A list or tuple of instances of {module_str}.{class_str} + - A list or tuple of dicts of string/value properties that will be passed to the {class_str} constructor""" ).format( plotly_name=self.plotly_name, @@ -2560,17 +2574,17 @@ def description(self): desc = ( """\ The '{plotly_name}' property is a tuple of trace instances - that may be specified as: - - A list or tuple of trace instances + that may be specified as:\n + - A list or tuple of trace instances (e.g. [Scatter(...), Bar(...)]) - - A single trace instance + - A single trace instance (e.g. Scatter(...), Bar(...), etc.) - - A list or tuple of dicts of string/value properties where: - - The 'type' property specifies the trace type + - A list or tuple of dicts of string/value properties where: + - The 'type' property specifies the trace type\n {trace_types} - - All remaining properties are passed to the constructor of - the specified trace type + - All remaining properties are passed to the constructor of + the specified trace type (e.g. [{{'type': 'scatter', ...}}, {{'type': 'bar, ...}}])""" ).format(plotly_name=self.plotly_name, trace_types=trace_types_wrapped) @@ -2580,7 +2594,7 @@ def description(self): def get_trace_class(self, trace_name): # Import trace classes if trace_name not in self._class_map: - trace_module = import_module("plotly.graph_objs") + trace_module = import_module("plotly.graph_objects") trace_class_name = self.class_strs_map[trace_name] self._class_map[trace_name] = getattr(trace_module, trace_class_name) @@ -2591,7 +2605,7 @@ def validate_coerce(self, v, skip_invalid=False, _validate=True): # Import Histogram2dcontour, this is the deprecated name of the # Histogram2dContour trace. - from plotly.graph_objs import Histogram2dcontour + from plotly.graph_objects import Histogram2dcontour if v is None: v = [] diff --git a/bin/build_example_toc.py b/bin/build_example_toc.py new file mode 100644 index 00000000000..dbfeea9f5b2 --- /dev/null +++ b/bin/build_example_toc.py @@ -0,0 +1,36 @@ +from collections import defaultdict +from pathlib import Path +import sys +import yaml + + +SKIPS = {"getting-started.md"} + + +def main(): + """Main driver.""" + sources = [Path(a) for a in sys.argv[1:]] + sources = [src for src in sources if str(src.name) not in SKIPS] + + sections = defaultdict(list) + for src in sources: + try: + content = src.read_text() + header = content.split("---")[1].strip() + data = yaml.safe_load(header) + data = data["jupyter"]["plotly"] + display = data["display_as"] + order = float(data["order"]) + sections[display].append((order, data, src.name)) + except Exception as exc: + print(f"failed to load from {src}: {exc}", file=sys.stderr) + + for key, values in sorted(sections.items()): + values.sort(key=lambda x: float(x[0])) + print(f"- {key}") + for (order, data, src) in values: + print(f' - {src}: "{data["name"]}"') + + +if __name__ == "__main__": + main() diff --git a/codegen/__init__.py b/bin/codegen/__init__.py similarity index 75% rename from codegen/__init__.py rename to bin/codegen/__init__.py index b299fa36045..8d1e187ab5b 100644 --- a/codegen/__init__.py +++ b/bin/codegen/__init__.py @@ -1,14 +1,13 @@ import json import os -import os.path as opath +from pathlib import Path import shutil -import subprocess import sys from codegen.datatypes import build_datatype_py, write_datatype_py # noqa: F401 from codegen.compatibility import ( write_deprecated_datatypes, - write_graph_objs_graph_objs, + write_graph_objects_graph_objects, DEPRECATED_DATATYPES, ) from codegen.figure import write_figure_classes @@ -29,6 +28,11 @@ ) +PROJECT_ROOT = Path(__file__).parent.parent.parent +PLOT_SCHEMA_RELATIVE = Path("resources") / "plot-schema.json" +PLOT_SCHEMA = PROJECT_ROOT / PLOT_SCHEMA_RELATIVE + + # Import notes # ------------ # Nothing from the plotly/ package should be imported during code @@ -62,7 +66,7 @@ def preprocess_schema(plotly_schema): matching the structure of `figure.layout` and `traceTemplate` is a dict matching the structure of the trace with type `trace_type` (e.g. 'scatter'). Alternatively, this may be specified as an instance of -plotly.graph_objs.layout.Template. +plotly.graph_objects.layout.Template. Trace templates are applied cyclically to traces of each type. Container arrays (eg `annotations`) have special @@ -87,46 +91,30 @@ def preprocess_schema(plotly_schema): items["colorscale"] = items.pop("concentrationscales") -def make_paths(outdir): - """Make various paths needed for formatting and linting.""" - - validators_dir = opath.join(outdir, "validators") - graph_objs_dir = opath.join(outdir, "graph_objs") - graph_objects_path = opath.join(outdir, "graph_objects", "__init__.py") - return validators_dir, graph_objs_dir, graph_objects_path - - -def lint_code(outdir): - """Check Python code using settings in pyproject.toml.""" - - subprocess.call(["ruff", "check", *make_paths(outdir)]) +def make_paths(codedir): + """Make various paths needed for code generation.""" + validators_dir = codedir / "validators" + graph_objects_dir = codedir / "graph_objects" + graph_objs_path = codedir / "graph_objs" / "__init__.py" + return validators_dir, graph_objects_dir, graph_objs_path -def reformat_code(outdir): - """Reformat Python code using settings in pyproject.toml.""" - subprocess.call(["ruff", "format", *make_paths(outdir)]) - - -def perform_codegen(outdir, noformat=False): - """Generate code (and possibly reformat).""" +def perform_codegen(codedir, noformat=False, schema=PLOT_SCHEMA): + """Generate code.""" # Get paths - validators_dir, graph_objs_dir, graph_objects_path = make_paths(outdir) + validators_dir, graph_objects_dir, graph_objs_path = make_paths(codedir) # Delete prior codegen output - if opath.exists(validators_dir): + if validators_dir.exists(): shutil.rmtree(validators_dir) - if opath.exists(graph_objs_dir): - shutil.rmtree(graph_objs_dir) + if graph_objects_dir.exists(): + shutil.rmtree(graph_objects_dir) # Load plotly schema - project_root = opath.dirname(outdir) - plot_schema_path = opath.join( - project_root, "codegen", "resources", "plot-schema.json" - ) - - with open(plot_schema_path, "r") as f: + project_root = codedir.parent + with open(schema, "r") as f: plotly_schema = json.load(f) # Preprocess Schema @@ -193,26 +181,26 @@ def perform_codegen(outdir, noformat=False): # Write out the JSON data for the validators os.makedirs(validators_dir, exist_ok=True) - write_validator_json(outdir, validator_params) + write_validator_json(codedir, validator_params) # Alls alls = {} # Write out datatypes for node in all_compound_nodes: - write_datatype_py(outdir, node) + write_datatype_py(codedir, node) # Deprecated - # These are deprecated legacy datatypes like graph_objs.Marker - write_deprecated_datatypes(outdir) + # These are deprecated legacy datatypes like graph_objects.Marker + write_deprecated_datatypes(codedir) - # Write figure class to graph_objs + # Write figure class to graph_objects data_validator = get_data_validator_instance(base_traces_node) layout_validator = layout_node.get_validator_instance() frame_validator = frame_node.get_validator_instance() write_figure_classes( - outdir, + codedir, base_traces_node, data_validator, layout_validator, @@ -239,10 +227,10 @@ def perform_codegen(outdir, noformat=False): f".{node.name_undercase}" ) - # Write plotly/graph_objs/graph_objs.py + # Write plotly/graph_objects/graph_objects.py # This is for backward compatibility. It just imports everything from - # graph_objs/__init__.py - write_graph_objs_graph_objs(outdir) + # graph_objects/__init__.py + write_graph_objects_graph_objects(codedir) # Add Figure and FigureWidget root_datatype_imports = datatype_rel_class_imports[()] @@ -258,7 +246,7 @@ def perform_codegen(outdir, noformat=False): import ipywidgets as _ipywidgets from packaging.version import Version as _Version if _Version(_ipywidgets.__version__) >= _Version("7.0.0"): - from ..graph_objs._figurewidget import FigureWidget + from ..graph_objects._figurewidget import FigureWidget else: raise ImportError() except Exception: @@ -272,7 +260,7 @@ def __getattr__(import_name): import ipywidgets from packaging.version import Version if Version(ipywidgets.__version__) >= Version("7.0.0"): - from ..graph_objs._figurewidget import FigureWidget + from ..graph_objects._figurewidget import FigureWidget return FigureWidget else: raise ImportError() @@ -287,12 +275,13 @@ def __getattr__(import_name): # __all__ for path_parts, class_names in alls.items(): if path_parts and class_names: - filepath = opath.join(outdir, "graph_objs", *path_parts, "__init__.py") + filepath = codedir / "graph_objects" + filepath = filepath.joinpath(*path_parts) / "__init__.py" with open(filepath, "at") as f: f.write(f"\n__all__ = {class_names}") # Output datatype __init__.py files - graph_objs_pkg = opath.join(outdir, "graph_objs") + graph_objects_pkg = codedir / "graph_objects" for path_parts in datatype_rel_class_imports: rel_classes = sorted(datatype_rel_class_imports[path_parts]) rel_modules = sorted(datatype_rel_module_imports.get(path_parts, [])) @@ -300,34 +289,31 @@ def __getattr__(import_name): init_extra = optional_figure_widget_import else: init_extra = "" - write_init_py(graph_objs_pkg, path_parts, rel_modules, rel_classes, init_extra) + write_init_py( + graph_objects_pkg, path_parts, rel_modules, rel_classes, init_extra + ) - # Output graph_objects.py alias - graph_objects_rel_classes = [ - "..graph_objs." + rel_path.split(".")[-1] + # Output graph_objs.py alias + graph_objs_rel_classes = [ + "..graph_objects." + rel_path.split(".")[-1] for rel_path in datatype_rel_class_imports[()] ] - graph_objects_rel_modules = [ - "..graph_objs." + rel_module.split(".")[-1] + graph_objs_rel_modules = [ + "..graph_objects." + rel_module.split(".")[-1] for rel_module in datatype_rel_module_imports[()] ] - graph_objects_init_source = build_from_imports_py( - graph_objects_rel_modules, - graph_objects_rel_classes, + graph_objs_init_source = build_from_imports_py( + graph_objs_rel_modules, + graph_objs_rel_classes, init_extra=optional_figure_widget_import, ) - graph_objects_path = opath.join(outdir, "graph_objects", "__init__.py") - os.makedirs(opath.join(outdir, "graph_objects"), exist_ok=True) - with open(graph_objects_path, "wt") as f: + graph_objs_path = codedir / "graph_objs" + graph_objs_path.mkdir(parents=True, exist_ok=True) + graph_objs_path /= "__init__.py" + with open(graph_objs_path, "wt") as f: f.write("# ruff: noqa: F401\n") - f.write(graph_objects_init_source) - - # Run code formatter on output directories - if noformat: - print("skipping reformatting") - else: - reformat_code(outdir) + f.write(graph_objs_init_source) if __name__ == "__main__": diff --git a/codegen/compatibility.py b/bin/codegen/compatibility.py similarity index 82% rename from codegen/compatibility.py rename to bin/codegen/compatibility.py index 2b57685ff2e..43dd3b4b75c 100644 --- a/codegen/compatibility.py +++ b/bin/codegen/compatibility.py @@ -1,5 +1,4 @@ from io import StringIO -from os import path as opath from codegen.utils import write_source_py @@ -43,7 +42,7 @@ def build_deprecated_datatypes_py(): """ - Build datatype (graph_objs) class source code string for deprecated + Build datatype (graph_objects) class source code string for deprecated datatypes Returns @@ -58,7 +57,7 @@ def build_deprecated_datatypes_py(): buffer.write( r""" warnings.filterwarnings("default", - r"plotly\.graph_objs\.\w+ is deprecated", + r"plotly\.graph_objects\.\w+ is deprecated", DeprecationWarning) @@ -101,15 +100,15 @@ def build_deprecation_message(class_name, base_type, new): new: list of str List of replacements that users should use instead. Replacements may be: - - A package string relative to plotly.graph_objs. In this case the + - A package string relative to plotly.graph_objects. In this case the replacement class is assumed to be named `class_name`. e.g. `new` == ['layout`] and `class_name` == 'XAxis` corresponds - to the 'plotly.graph_objs.layout.XAxis' class + to the 'plotly.graph_objects.layout.XAxis' class - String containing the package and class. The string is identified as containing a class name if the final name in the package string begins with an uppercase letter. e.g. `new` == ['Scatter'] corresponds to the - ['plotly.graph_objs.Scatter'] class. + ['plotly.graph_objects.Scatter'] class. - The literal string 'etc.'. This string is not interpreted as a package or class and is displayed to the user as-is to indicate that the list of replacement classes is not complete. @@ -130,35 +129,35 @@ def build_deprecation_message(class_name, base_type, new): if not repl_is_class: repl_parts.append(class_name) - # Add plotly.graph_objs prefix - full_class_str = ".".join(["plotly", "graph_objs"] + repl_parts) + # Add plotly.graph_objects prefix + full_class_str = ".".join(["plotly", "graph_objects"] + repl_parts) replacements.append(full_class_str) replacemens_str = "\n - ".join(replacements) if base_type is list: return f"""\ -plotly.graph_objs.{class_name} is deprecated. +plotly.graph_objects.{class_name} is deprecated. Please replace it with a list or tuple of instances of the following types - {replacemens_str} """ else: return f"""\ -plotly.graph_objs.{class_name} is deprecated. +plotly.graph_objects.{class_name} is deprecated. Please replace it with one of the following more specific types - {replacemens_str} """ -def write_deprecated_datatypes(outdir): +def write_deprecated_datatypes(codedir): """ Build source code for deprecated datatype class definitions and write them to a file Parameters ---------- - outdir : - Root outdir in which the graph_objs package should reside + codedir : + Root directory in which the graph_objects package should reside Returns ------- @@ -166,34 +165,34 @@ def write_deprecated_datatypes(outdir): """ # Generate source code datatype_source = build_deprecated_datatypes_py() - filepath = opath.join(outdir, "graph_objs", "_deprecations.py") + filepath = codedir / "graph_objects" / "_deprecations.py" # Write file write_source_py(datatype_source, filepath) -def write_graph_objs_graph_objs(outdir): +def write_graph_objects_graph_objects(codedir): """ - Write the plotly/graph_objs/graph_objs.py file + Write the plotly/graph_objects/graph_objects.py file - This module just imports everything from the plotly.graph_objs package. + This module just imports everything from the plotly.graph_objects package. We write it for backward compatibility with legacy imports like: - from plotly.graph_objs import graph_objs + from plotly.graph_objects import graph_objects Parameters ---------- - outdir : str - Root outdir in which the graph_objs package should reside + codedir : str + Root directory in which the graph_objects package should reside Returns ------- None """ - filepath = opath.join(outdir, "graph_objs", "graph_objs.py") + filepath = codedir / "graph_objects" / "graph_objects.py" with open(filepath, "wt") as f: f.write( """\ -from plotly.graph_objs import * +from plotly.graph_objects import * """ ) diff --git a/codegen/datatypes.py b/bin/codegen/datatypes.py similarity index 94% rename from codegen/datatypes.py rename to bin/codegen/datatypes.py index af7ec1a2a5c..4dd2471fa40 100644 --- a/codegen/datatypes.py +++ b/bin/codegen/datatypes.py @@ -1,6 +1,5 @@ -import os.path as opath -import textwrap from io import StringIO +import textwrap from codegen.utils import CAVEAT, write_source_py @@ -58,7 +57,7 @@ def get_typing_type(plotly_type, array_ok=False): def build_datatype_py(node): """ - Build datatype (graph_objs) class source code string for a datatype + Build datatype (graph_objects) class source code string for a datatype PlotlyNode Parameters @@ -78,14 +77,14 @@ def build_datatype_py(node): # Handle template traces # # We want template trace/layout classes like - # plotly.graph_objs.layout.template.data.Scatter to map to the - # corresponding trace/layout class (e.g. plotly.graph_objs.Scatter). + # plotly.graph_objects.layout.template.data.Scatter to map to the + # corresponding trace/layout class (e.g. plotly.graph_objects.Scatter). # So rather than generate a class definition, we just import the # corresponding trace/layout class if node.parent_path_str == "layout.template.data": - return f"from plotly.graph_objs import {node.name_datatype_class}" + return f"from plotly.graph_objects import {node.name_datatype_class}" elif node.path_str == "layout.template.layout": - return "from plotly.graph_objs import Layout" + return "from plotly.graph_objects import Layout" # Extract node properties datatype_class = node.name_datatype_class @@ -181,13 +180,13 @@ def _subplot_re_match(self, prop): for subtype_node in subtype_nodes: if subtype_node.is_array_element: prop_type = ( - f"tuple[plotly.graph_objs{node.dotpath_str}." + f"tuple[plotly.graph_objects{node.dotpath_str}." + f"{subtype_node.name_datatype_class}]" ) elif subtype_node.is_compound: prop_type = ( - f"plotly.graph_objs{node.dotpath_str}." + f"plotly.graph_objects{node.dotpath_str}." + f"{subtype_node.name_datatype_class}" ) @@ -224,6 +223,9 @@ def _subplot_re_match(self, prop): else: property_docstring = property_description + # FIXME: replace '][' with ']\[' to avoid confusion with Markdown reference links + # property_docstring = property_docstring.replace("][", "]\\[") + # Write get property buffer.write( f'''\ @@ -294,7 +296,7 @@ def __init__(self""" # Constructor Docstring header = f"Construct a new {datatype_class} object" class_name = ( - f"plotly.graph_objs{node.parent_dotpath_str}.{node.name_datatype_class}" + f"plotly.graph_objects{node.parent_dotpath_str}.{node.name_datatype_class}" ) extras = [ @@ -606,12 +608,12 @@ def add_docstring( def write_datatype_py(outdir, node): """ - Build datatype (graph_objs) class source code and write to a file + Build datatype (graph_objects) class source code and write to a file Parameters ---------- outdir : - Root outdir in which the graph_objs package should reside + Root outdir in which the graph_objects package should reside node : The datatype node (node.is_datatype must evaluate to true) for which to build the datatype class @@ -621,14 +623,6 @@ def write_datatype_py(outdir, node): None """ - # Build file path - # filepath = opath.join(outdir, "graph_objs", *node.parent_path_parts, "__init__.py") - filepath = opath.join( - outdir, "graph_objs", *node.parent_path_parts, "_" + node.name_undercase + ".py" - ) - - # Generate source code + filepath = (outdir / "graph_objects").joinpath(*node.parent_path_parts) / f"_{node.name_undercase}.py" datatype_source = build_datatype_py(node) - - # Write file write_source_py(datatype_source, filepath, leading_newlines=2) diff --git a/codegen/figure.py b/bin/codegen/figure.py similarity index 97% rename from codegen/figure.py rename to bin/codegen/figure.py index a15d806937c..cba0294d55f 100644 --- a/codegen/figure.py +++ b/bin/codegen/figure.py @@ -1,5 +1,4 @@ from io import StringIO -from os import path as opath from codegen.datatypes import ( reindent_validator_description, @@ -256,7 +255,7 @@ def add_{trace_node.plotly_name}(self""" # Function body buffer.write( f""" - from plotly.graph_objs import {trace_node.name_datatype_class} + from plotly.graph_objects import {trace_node.name_datatype_class} new_trace = {trace_node.name_datatype_class}( """ ) @@ -425,7 +424,7 @@ def update_{plural_name}( **kwargs Additional property updates to apply to each selected {singular_name} object. If a property is specified in - both patch and in **kwargs then the one in **kwargs + both patch and in \\\\*\\\\*kwargs then the one in \\\\*\\\\*kwargs takes precedence. Returns ------- @@ -605,8 +604,8 @@ def update_{method_prefix}{plural_name}( creating subplots with secondary y-axes. **kwargs Additional property updates to apply to each selected {singular_name}. If - a property is specified in both patch and in **kwargs then the - one in **kwargs takes precedence. + a property is specified in both patch and in \\\\\\\\*\\\\\\\\*kwargs then the + one in \\\\\\\\*\\\\\\\\*kwargs takes precedence. Returns ------- @@ -672,7 +671,7 @@ def add_{method_prefix}{singular_name}(self""" # Function body buffer.write( f""" - from plotly.graph_objs import layout as _layout + from plotly.graph_objects import layout as _layout new_obj = _layout.{node.name_datatype_class}(arg, """ ) @@ -705,7 +704,7 @@ def add_{method_prefix}{singular_name}(self""" def write_figure_classes( - outdir, + codedir, trace_node, data_validator, layout_validator, @@ -715,13 +714,13 @@ def write_figure_classes( ): """ Construct source code for the Figure and FigureWidget classes and - write to graph_objs/_figure.py and graph_objs/_figurewidget.py + write to graph_objects/_figure.py and graph_objects/_figurewidget.py respectively Parameters ---------- - outdir : str - Root outdir in which the graph_objs package should reside + codedir : str + Root directory in which the graph_objects package should reside trace_node : PlotlyNode Root trace node (the node that is the parent of all of the individual trace nodes like bar, scatter, etc.) @@ -768,5 +767,5 @@ def write_figure_classes( ) # Format and write to file - filepath = opath.join(outdir, "graph_objs", f"_{fig_classname.lower()}.py") + filepath = codedir / "graph_objects" / f"_{fig_classname.lower()}.py" write_source_py(figure_source, filepath) diff --git a/bin/codegen/utils.py b/bin/codegen/utils.py new file mode 100644 index 00000000000..c002574ada7 --- /dev/null +++ b/bin/codegen/utils.py @@ -0,0 +1,1315 @@ +from collections import ChainMap +from importlib import import_module +from io import StringIO +import re +import textwrap +from typing import List + +CAVEAT = """ + +# --- THIS FILE IS AUTO-GENERATED --- +# Modifications will be overwitten the next time code generation run. + +""" + + +# Source code utilities +# ===================== +def write_source_py(py_source, filepath, leading_newlines=0): + """ + Format Python source code and write to a file, creating parent + directories as needed. + + Parameters + ---------- + py_source : str + String containing valid Python source code. If string is empty, + no file will be written. + filepath : str + Full path to the file to be written + Returns + ------- + None + """ + if py_source: + # Make dir if needed + filepath.parent.mkdir(exist_ok=True) + + # Write file + py_source = "\n" * leading_newlines + py_source + with open(filepath, "at") as f: + f.write(py_source) + + +def build_from_imports_py(rel_modules=(), rel_classes=(), init_extra=""): + """ + Build a string containing a series of `from X import Y` lines + + Parameters + ---------- + rel_modules: list of str + list of submodules to import, of the form .submodule + rel_classes: list of str + list of submodule classes/variables to import, of the form ._submodule.Foo + init_extra: str + Extra code snippet to append to end of __init__.py file + Returns + ------- + str + String containing a series of imports + """ + + rel_modules = list(rel_modules) + rel_classes = list(rel_classes) + + import_lines = [] + for rel in rel_classes + rel_modules: + rel_parts = rel.split(".") + parent_module = ".".join(rel_parts[:-1]) or "." + import_target = rel_parts[-1] + import_line = f"from {parent_module} import {import_target}" + import_lines.append(import_line) + + imports_str = "\n ".join(import_lines) + + result = f"""\ +import sys +from typing import TYPE_CHECKING +if TYPE_CHECKING: + {imports_str} +else: + from _plotly_utils.importers import relative_import + __all__, __getattr__, __dir__ = relative_import( + __name__, + {repr(rel_modules)}, + {repr(rel_classes)} + ) + +{init_extra} +""" + return result + + +def write_init_py(pkg_root, path_parts, rel_modules=(), rel_classes=(), init_extra=""): + """ + Build __init__.py source code and write to a file + + Parameters + ---------- + pkg_root : str + Root package in which the top-level an __init__.py file with empty + path_parts should reside + path_parts : tuple of str + Tuple of sub-packages under pkg_root where the __init__.py + file should be written + rel_modules: list of str + list of submodules to import, of the form .submodule + rel_classes: list of str + list of submodule classes/variables to import, of the form ._submodule.Foo + init_extra: str + Extra code snippet to append to end of __init__.py file + Returns + ------- + None + """ + # Generate source code + init_source = build_from_imports_py(rel_modules, rel_classes, init_extra) + + # Write file + filepath = pkg_root.joinpath(*path_parts) / "__init__.py" + write_source_py(init_source, filepath) + + +def format_description(desc): + # Remove surrounding *s from numbers + desc = re.sub(r"(^|[\s(,.:])\*([\d.]+)\*([\s),.:]|$)", r"\1\2\3", desc) + + # replace *true* with True + desc = desc.replace("*true*", "True") + desc = desc.replace("*false*", "False") + + # Replace *word* with "word" + desc = re.sub(r"(^|[\s(,.:])\*(\S+)\*([\s),.:]|$)", r'\1"\2"\3', desc) + + # Special case strings that don't satisfy regex above + other_strings = [ + "", + "Courier New", + "Droid Sans", + "Droid Serif", + "Droid Sans Mono", + "Gravitas One", + "Old Standard TT", + "Open Sans", + "PT Sans Narrow", + "Times New Roman", + "bottom plot", + "top plot", + ] + + for s in other_strings: + desc = desc.replace(f"*{s}*", f'"{s}"') + + # Replace {array} with list + desc = desc.replace("an {array}", "a list") + desc = desc.replace("{array}", "list") + + # Replace {arrays} with lists + desc = desc.replace("{arrays}", "lists") + + # replace {2D array} with 2D list + desc = desc.replace("{2D array}", "2D list") + + # replace {2D arrays} with 2D lists + desc = desc.replace("{2D arrays}", "2D lists") + + # FIXME: replace '][' with ']\[' to avoid confusion with Markdown reference links + # desc = desc.replace("][", r"]\\[") + + return desc + + +# Constants +# ========= +# Mapping from full property paths to custom validator classes +CUSTOM_VALIDATOR_DATATYPES = { + "layout.image.source": "_plotly_utils.basevalidators.ImageUriValidator", + "layout.template": "_plotly_utils.basevalidators.BaseTemplateValidator", + "frame.data": "plotly.validators.DataValidator", + "frame.layout": "plotly.validators.LayoutValidator", +} + + +# Mapping from property string (as found in plot-schema.json) to a custom +# class name. If not included here, names are converted to TitleCase and +# underscores are removed. +OBJECT_NAME_TO_CLASS_NAME = { + "angularaxis": "AngularAxis", + "colorbar": "ColorBar", + "error_x": "ErrorX", + "error_y": "ErrorY", + "error_z": "ErrorZ", + "histogram2d": "Histogram2d", + "histogram2dcontour": "Histogram2dContour", + "mesh3d": "Mesh3d", + "radialaxis": "RadialAxis", + "scatter3d": "Scatter3d", + "xaxis": "XAxis", + "xbins": "XBins", + "yaxis": "YAxis", + "ybins": "YBins", + "zaxis": "ZAxis", +} + +# Tuple of types to be considered dicts by PlotlyNode logic +dict_like = (dict, ChainMap) + + +# PlotlyNode classes +# ================== +class PlotlyNode: + """ + Base class that represents a node in the plot-schema.json file + """ + + # Constructor + def __init__(self, plotly_schema, node_path=(), parent=None): + """ + Superclass constructor for all node types + + Parameters + ---------- + plotly_schema : dict + JSON-parsed version of the default-schema.xml file + node_path : str or tuple + Path of from the 'root' node for the current trace type to the + particular node that this instance represents + parent : PlotlyNode + Reference to the node's parent + """ + # Save params + self.plotly_schema = plotly_schema + self._parent = parent + + # Process node path + if isinstance(node_path, str): + node_path = (node_path,) + self.node_path = node_path + + # Compute children + # Note the node_data is a property that must be computed by the + # subclass based on plotly_schema and node_path + if isinstance(self.node_data, dict_like): + childs_parent = ( + parent if self.node_path and self.node_path[-1] == "items" else self + ) + + self._children = [ + self.__class__( + self.plotly_schema, + node_path=self.node_path + (c,), + parent=childs_parent, + ) + for c in self.node_data + if c and c[0] != "_" + ] + + # Sort by plotly name + self._children = sorted(self._children, key=lambda node: node.plotly_name) + else: + self._children = [] + + # Magic methods + def __repr__(self): + return self.path_str + + # Abstract methods + @property + def node_data(self): + """ + Dictionary of the subtree of the plotly_schema that this node + represents + + Returns + ------- + dict + """ + raise NotImplementedError() + + @property + def description(self): + """ + Description of the node + + Returns + ------- + str or None + """ + raise NotImplementedError() + + @property + def name_base_datatype(self): + """ + Superclass to use when generating a datatype class for this node + + Returns + ------- + str + """ + raise NotImplementedError + + # Names + @property + def root_name(self): + """ + Name of the node with empty node_path + + Returns + ------- + str + """ + raise NotImplementedError() + + @property + def plotly_name(self): + """ + Name of the node. Either the base_name or the name directly out of + the plotly_schema + + Returns + ------- + str + """ + if len(self.node_path) == 0: + return self.root_name + else: + return self.node_path[-1] + + @property + def name_datatype_class(self): + """ + Name of the Python datatype class representing this node + + Returns + ------- + str + """ + if self.plotly_name in OBJECT_NAME_TO_CLASS_NAME: + return OBJECT_NAME_TO_CLASS_NAME[self.plotly_name] + else: + return self.plotly_name.title().replace("_", "") + + @property + def name_undercase(self): + """ + Name of node converted to undercase (all lowercase with underscores + separating words) + + Returns + ------- + str + """ + if not self.plotly_name: + # Empty plotly_name + return self.plotly_name + + # Lowercase leading char + name1 = self.plotly_name[0].lower() + self.plotly_name[1:] + + # Replace capital chars by underscore-lower + name2 = "".join([("" if not c.isupper() else "_") + c.lower() for c in name1]) + + return name2 + + @property + def name_property(self): + """ + Name of the Python property corresponding to this node. This is the + same as `name_undercase` for compound nodes, but an 's' is appended + to the name for array nodes + + Returns + ------- + str + """ + + return self.plotly_name + ( + "s" + if self.is_array_element + and + # Don't add 's' to layout.template.data.scatter etc. + not ( + self.parent + and self.parent.parent + and self.parent.parent.parent + and self.parent.parent.parent.name_property == "template" + ) + else "" + ) + + @property + def name_validator_class(self) -> str: + """ + Name of the Python validator class representing this node + + Returns + ------- + str + """ + return self.name_property.title() + "Validator" + + @property + def name_base_validator(self) -> str: + """ + Superclass to use when generating a validator class for this node + + Returns + ------- + str + """ + if self.path_str in CUSTOM_VALIDATOR_DATATYPES: + validator_base = CUSTOM_VALIDATOR_DATATYPES[self.path_str] + elif self.plotly_name.endswith("src") and self.datatype == "string": + validator_base = "_plotly_utils.basevalidators.SrcValidator" + elif self.plotly_name.endswith("dash") and self.datatype == "string": + validator_base = "_plotly_utils.basevalidators.DashValidator" + elif self.plotly_name == "title" and self.datatype == "compound": + validator_base = "_plotly_utils.basevalidators.TitleValidator" + else: + datatype_title_case = self.datatype.title().replace("_", "") + validator_base = ( + f"_plotly_utils.basevalidators.{datatype_title_case}Validator" + ) + + return validator_base + + # Validators + def get_validator_params(self): + """ + Get kwargs to pass to the constructor of this node's validator + superclass. + + Returns + ------- + dict + The keys are strings matching the names of the constructor + params of this node's validator superclass. The values are + repr-strings of the values to be passed to the constructor. + These values are ready to be used to code generate calls to the + constructor. The values should be evald before being passed to + the constructor directly. + + """ + params = { + "plotly_name": repr(self.name_property), + "parent_name": repr(self.parent_path_str), + } + + if self.is_compound: + params["data_class_str"] = repr(self.name_datatype_class) + params["data_docs"] = '"""\n"""' + else: + assert self.is_simple + + # Exclude general properties + excluded_props = ["valType", "description", "dflt"] + if self.datatype == "subplotid": + # Default is required for subplotid validator + excluded_props.remove("dflt") + + attr_nodes = [ + n for n in self.simple_attrs if n.plotly_name not in excluded_props + ] + + for node in attr_nodes: + params[node.name_undercase] = repr(node.node_data) + + # Add extra properties + if self.datatype == "color" and self.parent: + # Check for colorscale sibling. We use the presence of a + # colorscale sibling to determine whether numeric color + # values are permissible + colorscale_node_list = [ + node + for node in self.parent.child_datatypes + if node.datatype == "colorscale" + ] + if colorscale_node_list: + colorscale_path = colorscale_node_list[0].path_str + params["colorscale_path"] = repr(colorscale_path) + elif self.datatype == "literal": + params["val"] = self.node_data + + return params + + def get_validator_instance(self): + """ + Return a constructed validator for this node + + Returns + ------- + BaseValidator + """ + + # Evaluate validator params to convert repr strings into values + # e.g. '2' -> 2 + params = { + prop: eval(repr_val) + for prop, repr_val in self.get_validator_params().items() + } + + validator_parts = self.name_base_validator.split(".") + if validator_parts[0] != "_plotly_utils": + return None + else: + validator_class_str = validator_parts[-1] + validator_module = ".".join(validator_parts[:-1]) + + validator_class = getattr( + import_module(validator_module), validator_class_str + ) + + return validator_class(**params) + + # Datatypes + @property + def datatype(self) -> str: + """ + Datatype string for this node. One of 'compound_array', 'compound', + 'literal', or the value of the 'valType' attribute + + Returns + ------- + str + """ + if self.is_array_element: + return "compound_array" + elif self.is_compound: + return "compound" + elif self.is_simple: + return self.node_data.get("valType") + else: + return "literal" + + @property + def is_array_ok(self) -> bool: + """ + Return true if arrays of datatype are acceptable + + Returns + ------- + bool + """ + return self.node_data.get("arrayOk", False) + + @property + def is_compound(self) -> bool: + """ + Node has a compound (in contrast to simple) datatype. + Note: All array and array_element types are also considered compound + + Returns + ------- + bool + """ + return ( + isinstance(self.node_data, dict_like) + and not self.is_simple + and not self.is_mapped + and self.plotly_name not in ("items", "impliedEdits", "transforms") + ) + + @property + def is_literal(self) -> bool: + """ + Node has a particular literal value (e.g. 'foo', or 23) + + Returns + ------- + bool + """ + return isinstance(self.node_data, (str, int, float)) + + @property + def is_simple(self) -> bool: + """ + Node has a simple datatype (e.g. boolean, color, colorscale, etc.) + + Returns + ------- + bool + """ + return ( + isinstance(self.node_data, dict_like) + and "valType" in self.node_data + and self.plotly_name != "items" + ) + + @property + def is_array(self) -> bool: + """ + Node has an array datatype + + Returns + ------- + bool + """ + return ( + isinstance(self.node_data, dict_like) + and self.node_data.get("role", "") == "object" + and "items" in self.node_data + and self.name_property != "transforms" + ) + + @property + def is_array_element(self): + """ + Node has an array-element datatype + + Returns + ------- + bool + """ + if self.parent: + return self.parent.is_array + else: + return False + + @property + def is_datatype(self) -> bool: + """ + Node represents any kind of datatype + + Returns + ------- + bool + """ + return self.is_simple or self.is_compound or self.is_array or self.is_mapped + + @property + def is_mapped(self) -> bool: + """ + Node represents a mapping from a deprecated property to a + normal property + + Returns + ------- + bool + """ + return False + + # Node path + def tidy_path_part(self, p): + """ + Return a tidy version of raw path entry. This allows subclasses to + adjust the raw property names in the plotly_schema + + Parameters + ---------- + p : str + Path element string + + Returns + ------- + str + """ + return p + + @property + def path_parts(self): + """ + Tuple of strings locating this node in the plotly_schema + e.g. ('layout', 'images', 'opacity') + + Returns + ------- + tuple of str + """ + res = [self.root_name] if self.root_name else [] + for i, p in enumerate(self.node_path): + # Handle array datatypes + if p == "items" or ( + i < len(self.node_path) - 1 and self.node_path[i + 1] == "items" + ): + # e.g. [parcoords, dimensions, items, dimension] -> + # [parcoords, dimension] + pass + else: + res.append(self.tidy_path_part(p)) + return tuple(res) + + # Node path strings + @property + def path_str(self): + """ + String containing path_parts joined on periods + e.g. 'layout.images.opacity' + + Returns + ------- + str + """ + return ".".join(self.path_parts) + + @property + def dotpath_str(self): + """ + path_str prefixed by a period if path_str is not empty, otherwise empty + + Returns + ------- + str + """ + path_str = "" + for p in self.path_parts: + path_str += "." + p + return path_str + + @property + def parent_path_parts(self): + """ + Tuple of strings locating this node's parent in the plotly_schema + + Returns + ------- + tuple of str + """ + return self.path_parts[:-1] + + @property + def parent_path_str(self): + """ + String containing parent_path_parts joined on periods + + Returns + ------- + str + """ + return ".".join(self.path_parts[:-1]) + + @property + def parent_dotpath_str(self): + """ + parent_path_str prefixed by a period if parent_path_str is not empty, + otherwise empty + + Returns + ------- + str + """ + path_str = "" + for p in self.parent_path_parts: + path_str += "." + p + return path_str + + # Children + @property + def parent(self): + """ + Parent node + + Returns + ------- + PlotlyNode + """ + return self._parent + + @property + def children(self): + """ + List of all child nodes + + Returns + ------- + list of PlotlyNode + """ + return self._children + + @property + def simple_attrs(self): + """ + List of simple attribute child nodes + (only valid when is_simple == True) + + Returns + ------- + list of PlotlyNode + """ + if not self.is_simple: + raise ValueError( + f"Cannot get simple attributes of the simple object '{self.path_str}'" + ) + + return [ + n for n in self.children if n.plotly_name not in ["valType", "description"] + ] + + @property + def child_datatypes(self): + """ + List of all datatype child nodes + + Returns + ------- + list of PlotlyNode + """ + nodes = [] + for n in self.children: + if n.is_array: + # Add array element node + nodes.append(n.children[0].children[0]) + + # Add elementdefaults node. Require parent_path_parts not + # empty to avoid creating defaults classes for traces + if n.parent_path_parts and n.parent_path_parts != ( + "layout", + "template", + "data", + ): + nodes.append(ElementDefaultsNode(n, self.plotly_schema)) + elif n.is_compound and n.plotly_name == "title": + nodes.append(n) + + # Remap deprecated title properties + deprecated_data = n.parent.node_data.get("_deprecated", {}) + deprecated_title_prop_names = [ + p for p in deprecated_data if p.startswith("title") and p != "title" + ] + for prop_name in deprecated_title_prop_names: + mapped_prop_name = prop_name.replace("title", "") + + mapped_prop_node = [ + title_prop + for title_prop in n.child_datatypes + if title_prop.plotly_name == mapped_prop_name + ][0] + + prop_parent = n.parent + + legacy_node = MappedPropNode( + mapped_prop_node, prop_parent, prop_name, self.plotly_schema + ) + + nodes.append(legacy_node) + + elif n.is_datatype: + nodes.append(n) + + return nodes + + @property + def child_compound_datatypes(self): + """ + List of all compound datatype child nodes + + Returns + ------- + list of PlotlyNode + """ + return [n for n in self.child_datatypes if n.is_compound] + + @property + def child_simple_datatypes(self) -> List["PlotlyNode"]: + """ + List of all simple datatype child nodes + + Returns + ------- + list of PlotlyNode + """ + return [n for n in self.child_datatypes if n.is_simple] + + @property + def child_literals(self) -> List["PlotlyNode"]: + """ + List of all literal child nodes + + Returns + ------- + list of PlotlyNode + """ + return [n for n in self.children if n.is_literal] + + def has_child(self, name) -> bool: + """ + Check whether node has child of the specified name + """ + return bool([n for n in self.children if n.plotly_name == name]) + + def get_constructor_params_docstring(self, indent=12): + """ + Return a docstring-style string containing the names and + descriptions of all of the node's child datatypes + + Parameters + ---------- + indent : int + Leading indent of the string + + Returns + ------- + str + """ + assert self.is_compound + + buffer = StringIO() + + subtype_nodes = self.child_datatypes + for subtype_node in subtype_nodes: + raw_description = subtype_node.description + if raw_description: + subtype_description = raw_description + elif subtype_node.is_array_element: + if ( + self.name_datatype_class == "Data" + and self.parent + and self.parent.name_datatype_class == "Template" + ): + class_name = ( + f"plotly.graph_objects.{subtype_node.name_datatype_class}" + ) + else: + class_name = ( + f"plotly.graph_objects" + f"{subtype_node.parent_dotpath_str}." + f"{subtype_node.name_datatype_class}" + ) + subtype_description = ( + f"A tuple of :class:`{class_name}` instances or " + "dicts with compatible properties" + ) + elif subtype_node.is_compound: + if ( + subtype_node.name_datatype_class == "Layout" + and self.name_datatype_class == "Template" + ): + class_name = "plotly.graph_objects.Layout" + else: + class_name = ( + f"plotly.graph_objects" + f"{subtype_node.parent_dotpath_str}." + f"{subtype_node.name_datatype_class}" + ) + + subtype_description = ( + f":class:`{class_name}` instance or dict with compatible properties" + ) + else: + subtype_description = "" + + subtype_description = "\n".join( + textwrap.wrap( + subtype_description, + initial_indent=" " * (indent + 4), + subsequent_indent=" " * (indent + 4), + width=79 - (indent + 4), + ) + ) + + buffer.write("\n" + " " * indent + subtype_node.name_property) + buffer.write("\n" + subtype_description) + + return buffer.getvalue() + + # Static helpers + @staticmethod + def get_all_compound_datatype_nodes(plotly_schema, node_class): + """ + Build a list of the entire hierarchy of compound datatype nodes for + a given PlotlyNode subclass + + Parameters + ---------- + plotly_schema : dict + JSON-parsed version of the default-schema.xml file + node_class + PlotlyNode subclass + + Returns + ------- + list of PlotlyNode + """ + nodes = [] + nodes_to_process = [node_class(plotly_schema)] + + while nodes_to_process: + node = nodes_to_process.pop() + + if node.plotly_name and not node.is_array: + nodes.append(node) + + non_defaults_compound_children = [ + node + for node in node.child_compound_datatypes + if not isinstance(node, ElementDefaultsNode) + ] + + nodes_to_process.extend(non_defaults_compound_children) + + return nodes + + @staticmethod + def get_all_datatype_nodes(plotly_schema, node_class): + """ + Build a list of the entire hierarchy of datatype nodes for a given + PlotlyNode subclass + + Parameters + ---------- + plotly_schema : dict + JSON-parsed version of the default-schema.xml file + node_class + PlotlyNode subclass + + Returns + ------- + list of PlotlyNode + """ + nodes = [] + nodes_to_process = [node_class(plotly_schema)] + + while nodes_to_process: + node = nodes_to_process.pop() + + if node.plotly_name and not node.is_array: + nodes.append(node) + + nodes_to_process.extend(node.child_datatypes) + + return nodes + + +class TraceNode(PlotlyNode): + """ + Class representing datatypes in the trace hierarchy + """ + + # Constructor + def __init__(self, plotly_schema, node_path=(), parent=None): + super().__init__(plotly_schema, node_path, parent) + + @property + def name_base_datatype(self): + if len(self.node_path) <= 1: + return "BaseTraceType" + else: + return "BaseTraceHierarchyType" + + @property + def root_name(self): + return "" + + # Raw data + @property + def node_data(self) -> dict: + if not self.node_path: + node_data = self.plotly_schema["traces"] + else: + trace_name = self.node_path[0] + node_data = self.plotly_schema["traces"][trace_name]["attributes"] + for prop_name in self.node_path[1:]: + node_data = node_data[prop_name] + + return node_data + + # Description + @property + def description(self) -> str: + if len(self.node_path) == 0: + desc = "" + elif len(self.node_path) == 1: + # Get trace descriptions + trace_name = self.node_path[0] + desc = self.plotly_schema["traces"][trace_name]["meta"].get( + "description", "" + ) + else: + # Get datatype description + desc = self.node_data.get("description", "") + + if isinstance(desc, list): + desc = "".join(desc) + + return format_description(desc) + + +class LayoutNode(PlotlyNode): + """ + Class representing datatypes in the layout hierarchy + """ + + # Constructor + def __init__(self, plotly_schema, node_path=(), parent=None): + # Get main layout properties + layout = plotly_schema["layout"]["layoutAttributes"] + + # Get list of additional layout properties for each trace + trace_layouts = [ + plotly_schema["traces"][trace].get("layoutAttributes", {}) + for trace in plotly_schema["traces"] + if trace != "barpolar" + ] + + extra_polar_nodes = plotly_schema["traces"]["barpolar"].get( + "layoutAttributes", {} + ) + layout["polar"].update(extra_polar_nodes) + + # Chain together into layout_data + self.layout_data = ChainMap(layout, *trace_layouts) + + # Call superclass constructor + super().__init__(plotly_schema, node_path, parent) + + @property + def name_base_datatype(self): + if len(self.node_path) == 0: + return "BaseLayoutType" + else: + return "BaseLayoutHierarchyType" + + @property + def root_name(self): + return "layout" + + @property + def plotly_name(self) -> str: + if len(self.node_path) == 0: + return self.root_name + else: + return self.node_path[-1] + + # Description + @property + def description(self) -> str: + desc = self.node_data.get("description", "") + if isinstance(desc, list): + desc = "".join(desc) + return format_description(desc) + + # Raw data + @property + def node_data(self) -> dict: + node_data = self.layout_data + for prop_name in self.node_path: + node_data = node_data[prop_name] + + return node_data + + +class FrameNode(PlotlyNode): + """ + Class representing datatypes in the frames hierarchy + """ + + # Constructor + def __init__(self, plotly_schema, node_path=(), parent=None): + super().__init__(plotly_schema, node_path, parent) + + @property + def name_base_datatype(self): + return "BaseFrameHierarchyType" + + @property + def root_name(self): + return "" + + @property + def plotly_name(self) -> str: + if len(self.node_path) < 2: + return self.root_name + elif len(self.node_path) == 2: + return "frame" # override frames_entry + else: + return self.node_path[-1] + + def tidy_path_part(self, p): + return "frame" if p == "frames_entry" else p + + # Description + @property + def description(self) -> str: + desc = self.node_data.get("description", "") + if isinstance(desc, list): + desc = "".join(desc) + return format_description(desc) + + # Raw data + @property + def node_data(self) -> dict: + node_data = self.plotly_schema["frames"] + for prop_name in self.node_path: + node_data = node_data[prop_name] + + return node_data + + +class ElementDefaultsNode(PlotlyNode): + def __init__(self, array_node, plotly_schema): + """ + Create node that represents element defaults properties + (e.g. layout.annotationdefaults). Construct as a wrapper around the + corresponding array property node (e.g. layout.annotations) + + Parameters + ---------- + array_node: PlotlyNode + """ + super().__init__( + plotly_schema, node_path=array_node.node_path, parent=array_node.parent + ) + + assert array_node.is_array + self.array_node = array_node + self.element_node = array_node.children[0].children[0] + + @property + def node_data(self): + return {} + + @property + def description(self): + array_property_path = self.parent_path_str + "." + self.array_node.name_property + + if isinstance(self.array_node, TraceNode): + data_path = "data." + else: + data_path = "" + + defaults_property_path = ( + "layout.template." + + data_path + + self.parent_path_str + + "." + + self.plotly_name + ) + return f"""\ +When used in a template +(as {defaults_property_path}), +sets the default property values to use for elements +of {array_property_path}""" + + @property + def name_base_datatype(self): + return self.element_node.name_base_datatype + + @property + def root_name(self): + return self.array_node.root_name + + @property + def plotly_name(self): + return self.element_node.plotly_name + "defaults" + + @property + def name_datatype_class(self): + return self.element_node.name_datatype_class + + +class MappedPropNode(PlotlyNode): + def __init__(self, mapped_prop_node, parent, prop_name, plotly_schema): + """ + Create node that represents a legacy title property. + e.g. layout.title_font. These properties are now subproperties under + the sibling `title` property. e.g. layout.title.font. + + Parameters + ---------- + title_node: PlotlyNode + prop_name: str + The name of the propery (without the title prefix) + e.g. 'font' to represent the layout.title_font property. + """ + node_path = parent.node_path + (prop_name,) + super().__init__(plotly_schema, node_path=node_path, parent=parent) + + self.mapped_prop_node = mapped_prop_node + self.prop_name = prop_name + + @property + def node_data(self): + return {} + + @property + def description(self): + res = ( + f"""\ +Deprecated: Please use {self.mapped_prop_node.path_str} instead. +""" + + self.mapped_prop_node.description + ) + return res + + @property + def name_base_datatype(self): + return self.mapped_prop_node.description + + @property + def root_name(self): + return self.parent.root_name + + @property + def plotly_name(self): + return self.prop_name + + @property + def name_datatype_class(self): + return self.mapped_prop_node.name_datatype_class + + @property + def is_mapped(self): + return True + + @property + def datatype(self): + return self.mapped_prop_node.datatype + + def get_validator_instance(self): + return self.mapped_prop_node.get_validator_instance() + + @property + def relative_path(self): + return ( + self.mapped_prop_node.parent.plotly_name, + self.mapped_prop_node.plotly_name, + ) diff --git a/codegen/validators.py b/bin/codegen/validators.py similarity index 94% rename from codegen/validators.py rename to bin/codegen/validators.py index 4cef19fa29b..04ea65d2f8a 100644 --- a/codegen/validators.py +++ b/bin/codegen/validators.py @@ -1,4 +1,3 @@ -import os.path as opath import json import _plotly_utils.basevalidators @@ -54,7 +53,7 @@ def get_data_validator_params(base_trace_node: TraceNode, store: dict): } -def write_validator_json(outdir, params: dict): +def write_validator_json(codedir, params: dict): """ Write out a JSON serialization of the validator arguments for all validators (keyed by f"{parent_name}.{plotly_name}) @@ -64,8 +63,8 @@ def write_validator_json(outdir, params: dict): Parameters ---------- - outdir : str - Root outdir in which the validators package should reside + codedir : str + Root directory in which the validators package should reside params : dict Dictionary to store the JSON data for the validator Returns @@ -78,7 +77,7 @@ def write_validator_json(outdir, params: dict): raise ValueError("Expected params to be a dictionary") # Write file - filepath = opath.join(outdir, "validators", "_validators.json") + filepath = codedir / "validators" / "_validators.json" with open(filepath, "w") as f: f.write(json.dumps(params, indent=4)) diff --git a/bin/generate_code.py b/bin/generate_code.py new file mode 100644 index 00000000000..0a5ccc3a2ac --- /dev/null +++ b/bin/generate_code.py @@ -0,0 +1,33 @@ +"""Generate code.""" + +import argparse +from pathlib import Path + +import utils + + +def main(): + """Main driver.""" + + args = parse_args() + codedir = utils.select_code_directory(args) + utils.perform_codegen(codedir, noformat=args.noformat, schema=args.schema) + + +def parse_args(): + """Parse command-line arguments.""" + + parser = argparse.ArgumentParser() + parser.add_argument("--codedir", type=Path, help="code directory") + parser.add_argument("--noformat", action="store_true", help="prevent reformatting") + parser.add_argument( + "--schema", + type=Path, + default=utils.PLOT_SCHEMA, + help=f"schema file (default {utils.PLOT_SCHEMA})", + ) + return parser.parse_args() + + +if __name__ == "__main__": + main() diff --git a/bin/generate_reference_pages.py b/bin/generate_reference_pages.py new file mode 100644 index 00000000000..a08b96fe3ec --- /dev/null +++ b/bin/generate_reference_pages.py @@ -0,0 +1,112 @@ +"""Generate the code reference pages and navigation.""" + +import os +from pathlib import Path + +import mkdocs_gen_files + +OUTPUT_ROOT = Path("reference") +SUMMARY_FILE = Path("SUMMARY.md") +INDEX_FILE = "index.md" + +SKIP_DIR = "graph_objects" + +CONTENT = """ +# {title} + +::: {ident} +""" + + +def main(): + """Main driver.""" + + # Setup. + temp_dir = _get_temp_dir() + nav = mkdocs_gen_files.Nav() + + # Process each Python file. + for path in sorted(Path("plotly").rglob("*.py")): + if _skip_file(path): + continue + + # Paths. + module_path = path.relative_to(".").with_suffix("") + doc_path = path.relative_to(".").with_suffix(".md") + full_doc_path = OUTPUT_ROOT / doc_path + + # Dunder special cases. + parts = tuple(module_path.parts) + if parts[-1] == "__main__": + continue + if parts[-1] == "__init__": + parts = parts[:-1] + doc_path = doc_path.with_name(INDEX_FILE) + full_doc_path = full_doc_path.with_name(INDEX_FILE) + + # Save constructed data. + nav[parts] = doc_path.as_posix() + mkdocs_gen_files.set_edit_path(full_doc_path, path) + content = _make_content(parts) + _save_in_memory(full_doc_path, content) + _save_in_temp_dir(temp_dir, doc_path, content) + + # Generate navigation summary. + _generate_nav_summary(temp_dir, nav) + + +def _generate_nav_summary(temp_dir, nav): + """Create navigation summary (saving if requested).""" + lines = nav.build_literate_nav() + + with mkdocs_gen_files.open(OUTPUT_ROOT / SUMMARY_FILE, "w") as writer: + writer.writelines(lines) + + if temp_dir is not None: + with open(temp_dir / SUMMARY_FILE, "w") as writer: + writer.writelines(lines) + + +def _get_temp_dir(): + """Get temporary directory for on-disk files if requested.""" + temp_dir = os.getenv("MKDOCS_TEMP_DIR", None) + if temp_dir is not None: + temp_dir = Path(temp_dir) + return temp_dir + + +def _make_content(parts): + """Generate text to put in files.""" + ident = parts + if (len(parts) == 3) and (parts[1] == SKIP_DIR) and (parts[2] != SKIP_DIR): + ident = [*parts[:-1], f"_{parts[2]}"] + return CONTENT.format(title=".".join(parts), ident=".".join(ident)) + + +def _save_in_memory(output_path, content): + """Save in-memory file.""" + with mkdocs_gen_files.open(output_path, "w") as writer: + writer.write(content) + + +def _save_in_temp_dir(temp_dir, doc_path, content): + """Save on-disk file.""" + if temp_dir is None: + return + + temp_path = temp_dir / doc_path + temp_path.parent.mkdir(exist_ok=True, parents=True) + with open(temp_path, "w") as writer: + writer.write(content) + + +def _skip_file(path): + """Don't include files like 'graph_objects/_bar.py'.""" + return ( + path.is_file() and (path.parent.name == SKIP_DIR) and str(path.name).startswith("_") + ) + + +# Do NOT protect this with `if __name__ == "__main__"` because this is +# run as a plugin by MkDocs rather than as a top-level script. +main() diff --git a/bin/run_markdown.py b/bin/run_markdown.py new file mode 100644 index 00000000000..1cb6db2b3a1 --- /dev/null +++ b/bin/run_markdown.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python3 +""" +Process Markdown files with embedded Python code blocks, saving +the output and images. +""" + +import argparse +from contextlib import redirect_stdout, redirect_stderr +import io +from pathlib import Path +import plotly.graph_objects as go +import sys +import traceback +from PIL import Image + + +def main(): + args = _parse_args() + if args.block is None: + for filename in args.inputs: + _do_file(args, Path(filename)) + else: + _do_file(args, Path(args.inputs[0]), block_number=args.block) + + +def _do_file(args, input_file, block_number=None): + """Process a single file.""" + + # Validate input file + if not input_file.exists(): + print(f"Error: '{input_file}' not found", file=sys.stderr) + sys.exit(1) + + # Determine output file path etc. + stem = input_file.stem + output_file = args.outdir / f"{input_file.stem}{input_file.suffix}" + if input_file.resolve() == output_file.resolve(): + print(f"Error: output would overwrite input '{input_file}'", file=sys.stderr) + sys.exit(1) + + # Read input + try: + with open(input_file, "r", encoding="utf-8") as f: + content = f.read() + except Exception as e: + print(f"Error reading input file: {e}", file=sys.stderr) + sys.exit(1) + + # Parse markdown and extract code blocks + _report(args.verbose > 0, f"Processing {input_file}...") + code_blocks = _parse_md(content) + _report(args.verbose > 1, f"- Found {len(code_blocks)} code blocks") + + # Execute code blocks and collect results + execution_results = _run_all_blocks(args, code_blocks, stem, block_number) + if block_number is not None: + return + + # Generate and save output + content = _generate_markdown(args, content, code_blocks, execution_results, args.outdir) + try: + with open(output_file, "w", encoding="utf-8") as f: + f.write(content) + _report(args.verbose > 1, f"- Output written to {output_file}") + _report(args.verbose > 1 and any(result["images"] for result in execution_results), f"- Images saved to {args.outdir}") + except Exception as e: + print(f"Error writing output file: {e}", file=sys.stderr) + sys.exit(1) + + +def _capture_plotly_show(fig, counter, result, output_dir, stem): + """Saves figures instead of displaying them.""" + # Save PNG + png_filename = f"{stem}_{counter}.png" + png_path = output_dir / png_filename + fig.write_image(png_path, width=800, height=600) + result["images"].append(png_filename) + + # Save HTML and get the content for embedding + html_filename = f"{stem}_{counter}.html" + html_path = output_dir / html_filename + fig.write_html(html_path, include_plotlyjs="cdn") + html_content = fig.to_html(include_plotlyjs="cdn", div_id=f"plotly-div-{counter}", full_html=False) + result["html_files"].append(html_filename) + result.setdefault("html_content", []).append(html_content) + +def _capture_Image_show(img, counter, result, output_dir, stem): + """Saves Images instead of displaying them.""" + png_filename = f"{stem}_image_{counter}.png" + png_path = output_dir / png_filename + img.save(png_path, "PNG") + result["images"].append(png_filename) + +def _generate_markdown(args, content, code_blocks, execution_results, output_dir): + """Generate the output markdown with embedded results.""" + lines = content.split("\n") + + # Sort code blocks by start line in reverse order for safe insertion + sorted_blocks = sorted( + enumerate(code_blocks), key=lambda x: x[1]["start_line"], reverse=True + ) + + # Process each code block and insert results + for block_idx, block in sorted_blocks: + result = execution_results[block_idx] + insert_lines = [] + + # Add output if there's stdout + if result["stdout"].strip(): + insert_lines.append("") + insert_lines.append("**Output:**") + insert_lines.append("```") + insert_lines.extend(result["stdout"].rstrip().split("\n")) + insert_lines.append("```") + + # Add error if there was one + if result["error"]: + insert_lines.append("") + insert_lines.append("**Error:**") + insert_lines.append("```") + insert_lines.extend(result["error"].rstrip().split("\n")) + insert_lines.append("```") + + # Add stderr if there's content + if result["stderr"].strip(): + insert_lines.append("") + insert_lines.append("**Warnings/Messages:**") + insert_lines.append("```") + insert_lines.extend(result["stderr"].rstrip().split("\n")) + insert_lines.append("```") + + # Add images + for image in result["images"]: + insert_lines.append("") + insert_lines.append(f"![Generated Plot](./{image})") + + # Embed HTML content for plotly figures + if args.inline: + for html_content in result.get("html_content", []): + insert_lines.append("") + insert_lines.append("**Interactive Plot:**") + insert_lines.append("") + insert_lines.extend(html_content.split("\n")) + + # Insert the results after the code block + if insert_lines: + # Insert after the closing ``` of the code block + insertion_point = block["end_line"] + 1 + lines[insertion_point:insertion_point] = insert_lines + + return "\n".join(lines) + + +def _parse_args(): + """Parse command-line arguments.""" + parser = argparse.ArgumentParser(description="Process Markdown files with code blocks") + parser.add_argument("inputs", nargs="+", help="Input .md files") + parser.add_argument("--block", type=int, help="Single block to run") + parser.add_argument("--inline", action="store_true", help="Inline HTML in .md") + parser.add_argument("--outdir", type=Path, help="Output directory") + parser.add_argument("--verbose", type=int, default=0, help="Integer verbosity level") + return parser.parse_args() + + +def _parse_md(content): + """Parse Markdown and extract Python code blocks.""" + lines = content.split("\n") + blocks = [] + current_block = None + in_code_block = False + in_region_block = False + + for i, line in enumerate(lines): + # Check for region start/end markers + if " @@ -155,7 +155,7 @@ fig.show() ## Box plot with go.Box -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Box` class from `plotly.graph_objects`](/python/graph-objects/). All available options for `go.Box` are described in the reference page https://plotly.com/python/reference/box/. +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Box` class from `plotly.graph_objects`](graph-objects.md). All available options for `go.Box` are described in the reference page https://plotly.com/python/reference/box/. ### Basic Box Plot @@ -510,7 +510,7 @@ fig.show() ### Box Plot With Only Points -A [strip chart](/python/strip-charts/) is like a box plot with points showing, and no box: +A [strip chart](strip-charts.md) is like a box plot with points showing, and no box: ```python import plotly.express as px diff --git a/doc/python/bubble-charts.md b/doc/python/bubble-charts.md index ad574b2a1ef..aebe97cd9fe 100644 --- a/doc/python/bubble-charts.md +++ b/doc/python/bubble-charts.md @@ -38,7 +38,7 @@ jupyter: A [bubble chart](https://en.wikipedia.org/wiki/Bubble_chart) is a scatter plot in which a third dimension of the data is shown through the size of markers. For other types of scatter plot, see the [scatter plot documentation](https://plotly.com/python/line-and-scatter/). -We first show a bubble chart example using Plotly Express. [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). The size of markers is set from the dataframe column given as the `size` parameter. +We first show a bubble chart example using Plotly Express. [Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). The size of markers is set from the dataframe column given as the `size` parameter. ```python import plotly.express as px @@ -52,7 +52,7 @@ fig.show() ## Bubble Chart with plotly.graph_objects -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](/python/graph-objects/), and define the size of markers to create a bubble chart. All of the available options are described in the scatter section of the reference page: https://plotly.com/python/reference#scatter. +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](graph-objects.md), and define the size of markers to create a bubble chart. All of the available options are described in the scatter section of the reference page: https://plotly.com/python/reference#scatter. ### Simple Bubble Chart diff --git a/doc/python/bubble-maps.md b/doc/python/bubble-maps.md index 3315e934d90..21c249f332f 100644 --- a/doc/python/bubble-maps.md +++ b/doc/python/bubble-maps.md @@ -35,11 +35,11 @@ jupyter: #### Base Map Configuration -Plotly figures made with [Plotly Express](/python/plotly-express/) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](/python/graph-objects/) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](/python/map-configuration/) onto which data is plotted. +Plotly figures made with [Plotly Express](plotly-express.md) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](graph-objects.md) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](map-configuration.md) onto which data is plotted. ### Bubble map with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.scatter_geo`, each line of the dataframe is represented as a marker point. The column set as the `size` argument gives the size of markers. +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.scatter_geo`, each line of the dataframe is represented as a marker point. The column set as the `size` argument gives the size of markers. ```python import plotly.express as px diff --git a/doc/python/builtin-colorscales.md b/doc/python/builtin-colorscales.md index a9eb672c3fe..e59f4fd312f 100644 --- a/doc/python/builtin-colorscales.md +++ b/doc/python/builtin-colorscales.md @@ -47,11 +47,11 @@ e.g. `"Viridis_r"` or `plotly.colors.sequential.Viridis_r`. The `plotly.colours` module is also available under `plotly.express.colors` so you can refer to it as `px.colors`. -When using continuous color scales, you will often want to [configure various aspects of its range and colorbar](/python/colorscales/). +When using continuous color scales, you will often want to [configure various aspects of its range and colorbar](colorscales.md). ### Discrete Color Sequences -Plotly also comes with some built-in [discrete color sequences](/python/discrete-color/) which are _not intended_ to be used with the `color_continuous_scale` argument as they are not designed for interpolation to occur between adjacent colors. +Plotly also comes with some built-in [discrete color sequences](discrete-color.md) which are _not intended_ to be used with the `color_continuous_scale` argument as they are not designed for interpolation to occur between adjacent colors. ### Named Built-In Continuous Color Scales @@ -112,7 +112,7 @@ It is intentionally left in for backwards-compatibility reasons. A collection of predefined diverging color scales is provided in the `plotly.colors.diverging` module. Diverging color scales are appropriate for continuous data that has a natural midpoint other otherwise informative special value, such as 0 altitude, or the boiling point -of a liquid. These scales are intended to be used when [explicitly setting the midpoint of the scale](/python/colorscales/#setting-the-midpoint-of-a-color-range-for-a-diverging-color-scale). +of a liquid. These scales are intended to be used when [explicitly setting the midpoint of the scale](colorscales.md#setting-the-midpoint-of-a-color-range-for-a-diverging-color-scale). Here are all the built-in scales in the `plotly.colors.diverging` module: diff --git a/doc/python/categorical-axes.md b/doc/python/categorical-axes.md index ec59627904e..97a4c6d1e99 100644 --- a/doc/python/categorical-axes.md +++ b/doc/python/categorical-axes.md @@ -34,19 +34,19 @@ jupyter: --- -This page shows examples of how to configure [2-dimensional Cartesian axes](/python/figure-structure/#2d-cartesian-trace-types-and-subplots) to visualize categorical (i.e. qualitative, nominal or ordinal data as opposed to continuous numerical data). Such axes are a natural fit for bar charts, waterfall charts, funnel charts, heatmaps, violin charts and box plots, but can also be used with scatter plots and line charts. [Configuring gridlines, ticks, tick labels and axis titles](/python/axes/) on logarithmic axes is done the same was as with [linear axes](/python/axes/). +This page shows examples of how to configure [2-dimensional Cartesian axes](figure-structure.md#2d-cartesian-trace-types-and-subplots) to visualize categorical (i.e. qualitative, nominal or ordinal data as opposed to continuous numerical data). Such axes are a natural fit for bar charts, waterfall charts, funnel charts, heatmaps, violin charts and box plots, but can also be used with scatter plots and line charts. [Configuring gridlines, ticks, tick labels and axis titles](axes.md) on logarithmic axes is done the same was as with [linear axes](axes.md). ### 2-D Cartesian Axis Type and Auto-Detection The different types of Cartesian axes are configured via the `xaxis.type` or `yaxis.type` attribute, which can take on the following values: -- `'linear'` (see the [linear axes tutorial](/python/axes/)) -- `'log'` (see the [log plot tutorial](/python/log-plot/)) -- `'date'` (see the [tutorial on timeseries](/python/time-series/)) +- `'linear'` (see the [linear axes tutorial](axes.md)) +- `'log'` (see the [log plot tutorial](log-plot.md)) +- `'date'` (see the [tutorial on timeseries](time-series.md)) - `'category'` see below - `'multicategory'` see below -The axis type is auto-detected by looking at data from the first [trace](/python/figure-structure/) linked to this axis: +The axis type is auto-detected by looking at data from the first [trace](figure-structure.md) linked to this axis: * First check for `multicategory`, then `date`, then `category`, else default to `linear` (`log` is never automatically selected) * `multicategory` is just a shape test: is the array nested? @@ -99,9 +99,9 @@ fig.show() ### Controlling the Category Order with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). -By default, Plotly Express lays out categorical data in the order in which it appears in the underlying data. Every 2-d cartesian Plotly Express function also includes a `category_orders` keyword argument which can be used to control the order in which categorical axes are drawn, but beyond that can also control [the order in which discrete colors appear in the legend](/python/discrete-color/), and [the order in which facets are laid out](/python/facet-plots/). +By default, Plotly Express lays out categorical data in the order in which it appears in the underlying data. Every 2-d cartesian Plotly Express function also includes a `category_orders` keyword argument which can be used to control the order in which categorical axes are drawn, but beyond that can also control [the order in which discrete colors appear in the legend](discrete-color.md), and [the order in which facets are laid out](facet-plots.md). ```python import plotly.express as px @@ -190,7 +190,7 @@ fig.show() A two-level categorical axis (also known as grouped or hierarchical categories, or sub-categories) can be created by specifying a trace's `x` or `y` property as a 2-dimensional lists. The first sublist represents the outer categorical value while the second sublist represents the inner categorical value. This is only possible with `plotly.graph_objects` at the moment, and not Plotly Express. -Passing in a two-dimensional list as the `x` or `y` value of a trace causes [the `type` of the corresponding axis](/python/axes/) to be set to `multicategory`. +Passing in a two-dimensional list as the `x` or `y` value of a trace causes [the `type` of the corresponding axis](axes.md) to be set to `multicategory`. Here is an example that creates a figure with 2 `bar` traces with a 2-level categorical x-axis. diff --git a/doc/python/choropleth-maps.md b/doc/python/choropleth-maps.md index 7f9984478fc..5afb9423fe8 100644 --- a/doc/python/choropleth-maps.md +++ b/doc/python/choropleth-maps.md @@ -33,13 +33,13 @@ jupyter: thumbnail: thumbnail/choropleth.jpg --- -A [Choropleth Map](https://en.wikipedia.org/wiki/Choropleth_map) is a map composed of colored polygons. It is used to represent spatial variations of a quantity. This page documents how to build **outline** choropleth maps, but you can also build [choropleth **tile maps**](/python/tile-county-choropleth). +A [Choropleth Map](https://en.wikipedia.org/wiki/Choropleth_map) is a map composed of colored polygons. It is used to represent spatial variations of a quantity. This page documents how to build **outline** choropleth maps, but you can also build [choropleth **tile maps**](tile-county-choropleth.md). Below we show how to create Choropleth Maps using either Plotly Express' `px.choropleth` function or the lower-level `go.Choropleth` graph object. #### Base Map Configuration -Plotly figures made with [Plotly Express](/python/plotly-express/) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](/python/graph-objects/) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](/python/map-configuration/) onto which data is plotted. +Plotly figures made with [Plotly Express](plotly-express.md) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](graph-objects.md) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](map-configuration.md) onto which data is plotted. ### Introduction: main parameters for choropleth outline maps @@ -56,7 +56,7 @@ The GeoJSON data is passed to the `geojson` argument, and the data is passed int ### Choropleth Map with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). #### GeoJSON with `feature.id` @@ -84,7 +84,7 @@ df.head() ### Choropleth map using GeoJSON -**Note** In this example we set `layout.geo.scope` to `usa` to automatically configure the map to display USA-centric data in an appropriate projection. See the [Geo map configuration documentation](/python/map-configuration/) for more information on scopes. +**Note** In this example we set `layout.geo.scope` to `usa` to automatically configure the map to display USA-centric data in an appropriate projection. See the [Geo map configuration documentation](map-configuration.md) for more information on scopes. ```python from urllib.request import urlopen @@ -126,7 +126,7 @@ print(geojson["features"][0]["properties"]) To use them together, we set `locations` to `district` and `featureidkey` to `"properties.district"`. The `color` is set to the number of votes by the candidate named Bergeron. -**Note** In this example we set `layout.geo.visible` to `False` to hide the base map and frame, and we set `layout.geo.fitbounds` to `'locations'` to automatically zoom the map to show just the area of interest. See the [Geo map configuration documentation](/python/map-configuration/) for more information on projections and bounds. +**Note** In this example we set `layout.geo.visible` to `False` to hide the base map and frame, and we set `layout.geo.fitbounds` to `'locations'` to automatically zoom the map to show just the area of interest. See the [Geo map configuration documentation](map-configuration.md) for more information on projections and bounds. ```python import plotly.express as px @@ -161,9 +161,9 @@ IFrame(snippet_url + 'choropleth-maps', width='100%', height=1200) ### Discrete Colors -In addition to [continuous colors](/python/colorscales/), we can [discretely-color](/python/discrete-color/) our choropleth maps by setting `color` to a non-numerical column, like the name of the winner of an election. +In addition to [continuous colors](colorscales.md), we can [discretely-color](discrete-color.md) our choropleth maps by setting `color` to a non-numerical column, like the name of the winner of an election. -**Note** In this example we set `layout.geo.visible` to `False` to hide the base map and frame, and we set `layout.geo.fitbounds` to `'locations'` to automatically zoom the map to show just the area of interest. See the [Geo map configuration documentation](/python/map-configuration/) for more information on projections and bounds. +**Note** In this example we set `layout.geo.visible` to `False` to hide the base map and frame, and we set `layout.geo.fitbounds` to `'locations'` to automatically zoom the map to show just the area of interest. See the [Geo map configuration documentation](map-configuration.md) for more information on projections and bounds. ```python import plotly.express as px @@ -351,7 +351,7 @@ fig.show() #### County Choropleth Figure Factory -Plotly also includes a [legacy "figure factory" for creating US county-level choropleth maps](/python/county-choropleth/). +Plotly also includes a [legacy "figure factory" for creating US county-level choropleth maps](county-choropleth.md). ```python import plotly.figure_factory as ff diff --git a/doc/python/colorscales.md b/doc/python/colorscales.md index 61e84314d4d..dc518a7b250 100644 --- a/doc/python/colorscales.md +++ b/doc/python/colorscales.md @@ -39,20 +39,20 @@ jupyter: ### Continuous vs Discrete Color -In the same way as the X or Y position of a mark in cartesian coordinates can be used to represent continuous values (i.e. amounts or moments in time) or categories (i.e. labels), color can be used to represent continuous or categorical data. This page is about using color to represent **continuous** data, but Plotly can also [represent categorical values with color](/python/discrete-color/). +In the same way as the X or Y position of a mark in cartesian coordinates can be used to represent continuous values (i.e. amounts or moments in time) or categories (i.e. labels), color can be used to represent continuous or categorical data. This page is about using color to represent **continuous** data, but Plotly can also [represent categorical values with color](discrete-color.md). ### Continuous Color Concepts This document explains the following four continuous-color-related concepts: -- **color scales** represent a mapping between the range 0 to 1 and some color domain within which colors are to be interpolated (unlike [discrete color sequences](/python/discrete-color/) which are never interpolated). Color scale defaults depend on the `layout.colorscales` attributes of the active [template](/python/templates/), and can be explicitly specified using the `color_continuous_scale` argument for many [Plotly Express](/python/plotly-express/) functions or the `colorscale` argument in various `graph_objects` such as `layout.coloraxis` or `marker.colorscale` in `go.Scatter` traces or `colorscale` in `go.Heatmap` traces. For example `[(0,"blue"), (1,"red")]` is a simple color scale that interpolated between blue and red via purple, which can also be implicitly represented as `["blue", "red"]` and happens to be one of the [built-in color scales](/python/builtin-colorscales) and therefore referred to as `"bluered"` or `plotly.colors.sequential.Bluered`. +- **color scales** represent a mapping between the range 0 to 1 and some color domain within which colors are to be interpolated (unlike [discrete color sequences](discrete-color.md) which are never interpolated). Color scale defaults depend on the `layout.colorscales` attributes of the active [template](templates.md), and can be explicitly specified using the `color_continuous_scale` argument for many [Plotly Express](plotly-express.md) functions or the `colorscale` argument in various `graph_objects` such as `layout.coloraxis` or `marker.colorscale` in `go.Scatter` traces or `colorscale` in `go.Heatmap` traces. For example `[(0,"blue"), (1,"red")]` is a simple color scale that interpolated between blue and red via purple, which can also be implicitly represented as `["blue", "red"]` and happens to be one of the [built-in color scales](builtin-colorscales.md) and therefore referred to as `"bluered"` or `plotly.colors.sequential.Bluered`. - **color ranges** represent the minimum to maximum range of data to be mapped onto the 0 to 1 input range of the color scale. Color ranges default to the range of the input data and can be explicitly specified using either the `range_color` or `color_continuous_midpoint` arguments for many Plotly Express functions, or `cmin`/`cmid`/`cmax` or `zmin`/`zmid`/`zmax` for various `graph_objects` such as `layout.coloraxis.cmin` or `marker.cmin` in `go.Scatter` traces or `cmin` in `go.Heatmap` traces. For example, if a color range of `[100, 200]` is used with the color scale above, then any mark with a color value of 100 or less will be blue, and 200 or more will be red. Marks with values in between will be various shades of purple. - **color bars** are legend-like visible representations of the color range and color scale with optional tick labels and tick marks. Color bars can be configured with attributes inside `layout.coloraxis.colorbar` or in places like `marker.colorbar` in `go.Scatter` traces or `colorbar` in `go.Heatmap` traces. - **color axes** connect color scales, color ranges and color bars to a trace's data. By default, any colorable attribute in a trace is attached to its own local color axis, but color axes may also be shared across attributes and traces by setting e.g. `marker.coloraxis` in `go.Scatter` traces or `coloraxis` in `go.Heatmap` traces. Local color axis attributes are configured within traces e.g. `marker.showscale` whereas shared color axis attributes are configured within the Layout e.g. `layout.coloraxis.showscale`. ### Continuous Color with Plotly Express -Most [Plotly Express](/python/plotly-express/) functions accept a `color` argument which automatically assigns data values to continuous color **if the data is numeric**. If the data contains strings, the color will automatically be considered [discrete (also known as categorical or qualitative)](/python/discrete-color/). This means that numeric strings must be parsed to be used for continuous color, and conversely, numbers used as category codes must be converted to strings. +Most [Plotly Express](plotly-express.md) functions accept a `color` argument which automatically assigns data values to continuous color **if the data is numeric**. If the data contains strings, the color will automatically be considered [discrete (also known as categorical or qualitative)](discrete-color.md). This means that numeric strings must be parsed to be used for continuous color, and conversely, numbers used as category codes must be converted to strings. For example, in the `tips` dataset, the `size` column contains numbers: @@ -109,7 +109,7 @@ IFrame(snippet_url + 'colorscales', width='100%', height=1200) ### Color Scales in Plotly Express -By default, [Plotly Express](/python/plotly-express/) will use the color scale from the active [template](/python/templates/)'s `layout.colorscales.sequential` attribute, and the default active template is `plotly` which uses the `Plasma` color scale. You can choose any of the [built-in color scales](/python/builtin-colorscales/), however, or define your own. +By default, [Plotly Express](plotly-express.md) will use the color scale from the active [template](templates.md)'s `layout.colorscales.sequential` attribute, and the default active template is `plotly` which uses the `Plasma` color scale. You can choose any of the [built-in color scales](builtin-colorscales.md), however, or define your own. Here is an example that creates a scatter plot using Plotly Express, with points colored using the Viridis color scale. @@ -135,7 +135,7 @@ fig.show() ### Reversing a built-in color scale -You can reverse a [built-in color scale](/python/builtin-colorscales/) by appending `_r` to its name, for color scales given either as a string or a `plotly` object. +You can reverse a [built-in color scale](builtin-colorscales.md) by appending `_r` to its name, for color scales given either as a string or a `plotly` object. ```python import plotly.express as px @@ -181,7 +181,7 @@ fig.show() ### Constructing a Discrete or Discontinuous Color Scale -You can create a discrete color scale, with discontinuous color, by setting the same reference point twice in a row. This is useful for example with chart types that don't support discrete colors, like [Parallel Coordinates plots](/python/parallel-coordinates-plot/). See below for how to customize tick text. +You can create a discrete color scale, with discontinuous color, by setting the same reference point twice in a row. This is useful for example with chart types that don't support discrete colors, like [Parallel Coordinates plots](parallel-coordinates-plot.md). See below for how to customize tick text. ```python import plotly.express as px @@ -226,7 +226,7 @@ fig.show() ### Hiding or Customizing the Plotly Express Color Bar -Plotly Express binds all traces to [`layout.coloraxis`](/python/reference/layout/coloraxis/), rather than using trace-specific color axes. This means that the color bar can configured there, for example it can be hidden: +Plotly Express binds all traces to [`layout.coloraxis`](../reference/plotly/graph_objects/layout/_coloraxis.md), rather than using trace-specific color axes. This means that the color bar can configured there, for example it can be hidden: ```python import plotly.express as px @@ -640,7 +640,7 @@ fig.show() Colorbars can be positioned by specifying x and y coordinates. By default, the x and y values are "paper" coordinates, which refer to the plot area. You can also use coordinates based on the "container" by setting `xref="container"` or `yref="container"`. The following example uses a container reference for the x position. -See the positioning section of [the figure data structure page](/python/figure-structure/#positioning-with-paper-container-coordinates-or-axis-domain-coordinates) for more details on "paper" vs "container" coordinates. +See the positioning section of [the figure data structure page](figure-structure.md#positioning-with-paper-container-coordinates-or-axis-domain-coordinates) for more details on "paper" vs "container" coordinates. ```python import plotly.graph_objects as go diff --git a/doc/python/cone-plot.md b/doc/python/cone-plot.md index 90eafd5407a..0c952cb82b4 100644 --- a/doc/python/cone-plot.md +++ b/doc/python/cone-plot.md @@ -34,7 +34,7 @@ jupyter: thumbnail: thumbnail/3dcone.png --- -A cone plot is the 3D equivalent of a 2D [quiver plot](/python/quiver-plots/), i.e., it represents a 3D vector field using cones to represent the direction and norm of the vectors. 3-D coordinates are given by `x`, `y` and `z`, and the coordinates of the vector field by `u`, `v` and `w`. +A cone plot is the 3D equivalent of a 2D [quiver plot](quiver-plots.md), i.e., it represents a 3D vector field using cones to represent the direction and norm of the vectors. 3-D coordinates are given by `x`, `y` and `z`, and the coordinates of the vector field by `u`, `v` and `w`. ### Basic 3D Cone diff --git a/doc/python/configuration-options.md b/doc/python/configuration-options.md index 7e16dc4e623..1aa4586b9f5 100644 --- a/doc/python/configuration-options.md +++ b/doc/python/configuration-options.md @@ -252,7 +252,7 @@ fig.show() *New in v4.7* -Some modebar buttons of Cartesian plots are optional and have to be added explicitly, using the `modeBarButtonsToAdd` config attribute. These buttons are used for drawing or erasing shapes. See [the tutorial on shapes and shape drawing](/python/shapes#drawing-shapes-with-a-mouse-on-cartesian-plots) for more details. +Some modebar buttons of Cartesian plots are optional and have to be added explicitly, using the `modeBarButtonsToAdd` config attribute. These buttons are used for drawing or erasing shapes. See [the tutorial on shapes and shape drawing](shapes.md#drawing-shapes-with-a-mouse-on-cartesian-plots) for more details. ```python import plotly.express as px diff --git a/doc/python/continuous-error-bars.md b/doc/python/continuous-error-bars.md index 529033bb63d..8ee9ab3ee84 100644 --- a/doc/python/continuous-error-bars.md +++ b/doc/python/continuous-error-bars.md @@ -33,7 +33,7 @@ jupyter: thumbnail: thumbnail/error-cont.jpg --- -Continuous error bands are a graphical representation of error or uncertainty as a shaded region around a main trace, rather than as discrete whisker-like error bars. They can be implemented in a manner similar to [filled area plots](/python/filled-area-plots/) using `scatter` traces with the `fill` attribute. +Continuous error bands are a graphical representation of error or uncertainty as a shaded region around a main trace, rather than as discrete whisker-like error bars. They can be implemented in a manner similar to [filled area plots](filled-area-plots.md) using `scatter` traces with the `fill` attribute. #### Filling within a single trace diff --git a/doc/python/county-choropleth.md b/doc/python/county-choropleth.md index 1e4410db37f..fd71caf5ac4 100644 --- a/doc/python/county-choropleth.md +++ b/doc/python/county-choropleth.md @@ -37,7 +37,7 @@ jupyter: ### Deprecation warning -This page describes a [legacy "figure factory" method](/python/figure-factories/) for creating map-like figures using [self-filled scatter traces](/python/shapes). **This is no longer the recommended way to make county-level choropleth maps**, instead we recommend using a [GeoJSON-based approach to making outline choropleth maps](/python/choropleth-maps/) or the alternative [tile-based choropleth maps](/python/tile-county-choropleth). +This page describes a [legacy "figure factory" method](figure-factories.md) for creating map-like figures using [self-filled scatter traces](shapes.md). **This is no longer the recommended way to make county-level choropleth maps**, instead we recommend using a [GeoJSON-based approach to making outline choropleth maps](choropleth-maps.md) or the alternative [tile-based choropleth maps](tile-county-choropleth.md). #### Required Packages @@ -45,11 +45,11 @@ This page describes a [legacy "figure factory" method](/python/figure-factories/ Run the following commands to install the correct versions of the following modules: -```python -!pip install plotly-geo==1.0.0 -!pip install geopandas==0.8.1 -!pip install pyshp==2.1.2 -!pip install shapely==1.7.1 +``` +$ pip install plotly-geo==1.0.0 +$ pip install geopandas==1.1.1 +$ pip install pyshp==2.3.1 +$ pip install shapely==2.1.1 ``` If you are using Windows, follow this post to properly install geopandas and dependencies: http://geoffboeing.com/2014/09/using-geopandas-windows/. If you are using Anaconda, do not use PIP to install the packages above. Instead use conda to install them: diff --git a/doc/python/creating-and-updating-figures.md b/doc/python/creating-and-updating-figures.md index b23d69e41be..29d93e04ac3 100644 --- a/doc/python/creating-and-updating-figures.md +++ b/doc/python/creating-and-updating-figures.md @@ -37,9 +37,9 @@ jupyter: v4upgrade: true --- -The `plotly` Python package exists to create, manipulate and [render](/python/renderers/) graphical figures (i.e. charts, plots, maps and diagrams) represented by [data structures also referred to as figures](/python/figure-structure/). The rendering process uses the [Plotly.js JavaScript library](https://plotly.com/javascript/) under the hood although Python developers using this module very rarely need to interact with the Javascript library directly, if ever. Figures can be represented in Python either as dicts or as instances of the `plotly.graph_objects.Figure` class, and are serialized as text in [JavaScript Object Notation (JSON)](https://json.org/) before being passed to Plotly.js. +The `plotly` Python package exists to create, manipulate and [render](renderers.md) graphical figures (i.e. charts, plots, maps and diagrams) represented by [data structures also referred to as figures](figure-structure.md). The rendering process uses the [Plotly.js JavaScript library](https://plotly.com/javascript/) under the hood although Python developers using this module very rarely need to interact with the Javascript library directly, if ever. Figures can be represented in Python either as dicts or as instances of the `plotly.graph_objects.Figure` class, and are serialized as text in [JavaScript Object Notation (JSON)](https://json.org/) before being passed to Plotly.js. -> Note: the recommended entry-point into the plotly package is the [high-level plotly.express module, also known as Plotly Express](/python/plotly-express/), which consists of Python functions which return fully-populated `plotly.graph_objects.Figure` objects. This page exists to document the structure of the data structure that these objects represent for users who wish to understand more about how to customize them, or assemble them from other `plotly.graph_objects` components. +> Note: the recommended entry-point into the plotly package is the [high-level plotly.express module, also known as Plotly Express](plotly-express.md), which consists of Python functions which return fully-populated `plotly.graph_objects.Figure` objects. This page exists to document the structure of the data structure that these objects represent for users who wish to understand more about how to customize them, or assemble them from other `plotly.graph_objects` components. ### Figures As Dictionaries @@ -61,14 +61,14 @@ pio.show(fig) ### Figures as Graph Objects -The [`plotly.graph_objects` module provides an automatically-generated hierarchy of classes](https://plotly.com/python-api-reference/plotly.graph_objects.html) called ["graph objects"](/python/graph-objects/) that may be used to represent figures, with a top-level class `plotly.graph_objects.Figure`. +The [`plotly.graph_objects` module provides an automatically-generated hierarchy of classes](https://plotly.com/python-api-reference/plotly.graph_objects.html) called ["graph objects"](graph-objects.md) that may be used to represent figures, with a top-level class `plotly.graph_objects.Figure`. -> Note that the *recommended alternative* to working with Python dictionaries is to [create entire figures at once using Plotly Express](/python/plotly-express/) and to manipulate the resulting `plotly.graph_objects.Figure` objects as described in this page, wherever possible, rather than to assemble figures bottom-up from underlying graph objects. See ["When to use Graph Objects"](/python/graph-objects/). +> Note that the *recommended alternative* to working with Python dictionaries is to [create entire figures at once using Plotly Express](plotly-express.md) and to manipulate the resulting `plotly.graph_objects.Figure` objects as described in this page, wherever possible, rather than to assemble figures bottom-up from underlying graph objects. See ["When to use Graph Objects"](graph-objects.md). Graph objects have several benefits compared to plain Python dictionaries. 1. Graph objects provide precise data validation. If you provide an invalid property name or an invalid property value as the key to a graph object, an exception will be raised with a helpful error message describing the problem. This is not the case if you use plain Python dictionaries and lists to build your figures. -2. Graph objects contain descriptions of each valid property as Python docstrings, with a [full API reference available](https://plotly.com/python-api-reference/). You can use these docstrings in the development environment of your choice to learn about the available properties as an alternative to consulting the online [Full Reference](/python/reference/index/). +2. Graph objects contain descriptions of each valid property as Python docstrings, with a [full API reference available](https://plotly.com/python-api-reference/). You can use these docstrings in the development environment of your choice to learn about the available properties as an alternative to consulting the online [Full Reference](/reference/). 3. Properties of graph objects can be accessed using both dictionary-style key lookup (e.g. `fig["layout"]`) or class-style property access (e.g. `fig.layout`). 4. Graph objects support higher-level convenience functions for making updates to already constructed figures (`.update_layout()`, `.add_trace()` etc) as described below. 5. Graph object constructors and update methods accept "magic underscores" (e.g. `go.Figure(layout_title_text="The Title")` rather than `dict(layout=dict(title=dict(text="The Title")))`) for more compact code, as described below. @@ -148,7 +148,7 @@ IFrame(snippet_url + 'figure-structure', width='100%', height=1200) This section summarizes several ways to create new graph object figures with the `plotly.py` graphing library. -> The *recommended way* to create figures and populate them is to use [Plotly Express](/python/plotly-express/) but this page documents various other options for completeness +> The *recommended way* to create figures and populate them is to use [Plotly Express](plotly-express.md) but this page documents various other options for completeness #### Plotly Express @@ -186,7 +186,7 @@ fig.show() #### Figure Factories -[Figure factories](/python/figure-factories) (included in `plotly.py` in the `plotly.figure_factory` module) are functions that produce graph object figures, often to satisfy the needs of specialized domains. Here's an example of using the `create_quiver()` figure factory to construct a graph object figure that displays a 2D quiver plot. +[Figure factories](figure-factories.md) (included in `plotly.py` in the `plotly.figure_factory` module) are functions that produce graph object figures, often to satisfy the needs of specialized domains. Here's an example of using the `create_quiver()` figure factory to construct a graph object figure that displays a 2D quiver plot. ```python import numpy as np @@ -239,6 +239,7 @@ You can also add traces to a figure produced by a figure factory or Plotly Expre ```python import plotly.express as px +import plotly.graph_objects as go df = px.data.iris() @@ -618,9 +619,9 @@ There are also `for_each_xaxis()` and `for_each_yaxis()` methods that are analog Figures created with the plotly.py graphing library also support: - - the `update_layout_images()` method in order to [update background layout images](/python/images/), - - `update_annotations()` in order to [update annotations](/python/text-and-annotations/#multiple-annotations), - - and `update_shapes()` in order to [update shapes](/python/shapes/). + - the `update_layout_images()` method in order to [update background layout images](images.md), + - `update_annotations()` in order to [update annotations](text-and-annotations.md#multiple-annotations), + - and `update_shapes()` in order to [update shapes](shapes.md). #### Chaining Figure Operations diff --git a/doc/python/dendrogram.md b/doc/python/dendrogram.md index 0fe8968f202..722f1a07484 100644 --- a/doc/python/dendrogram.md +++ b/doc/python/dendrogram.md @@ -35,7 +35,7 @@ jupyter: #### Basic Dendrogram -A [dendrogram](https://en.wikipedia.org/wiki/Dendrogram) is a diagram representing a tree. The [figure factory](/python/figure-factories/) called `create_dendrogram` performs [hierarchical clustering](https://en.wikipedia.org/wiki/Hierarchical_clustering) on data and represents the resulting tree. Values on the tree depth axis correspond to distances between clusters. +A [dendrogram](https://en.wikipedia.org/wiki/Dendrogram) is a diagram representing a tree. The [figure factory](figure-factories.md) called `create_dendrogram` performs [hierarchical clustering](https://en.wikipedia.org/wiki/Hierarchical_clustering) on data and represents the resulting tree. Values on the tree depth axis correspond to distances between clusters. Dendrogram plots are commonly used in computational biology to show the clustering of genes or samples, sometimes in the margin of heatmaps. diff --git a/doc/python/density-heatmaps.md b/doc/python/density-heatmaps.md index e694c699437..6a5c888a8ed 100644 --- a/doc/python/density-heatmaps.md +++ b/doc/python/density-heatmaps.md @@ -36,7 +36,7 @@ jupyter: ### Density map with `plotly.express` -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.density_map`, each row of the DataFrame is represented as a point smoothed with a given radius of influence. @@ -53,7 +53,7 @@ fig.show() ### Density map with `plotly.graph_objects` -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Densitymap` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Densitymap` class from `plotly.graph_objects`](graph-objects.md). ```python import pandas as pd @@ -74,7 +74,7 @@ fig.show() The earlier examples using `px.density_map` and `go.Densitymap` use [Maplibre](https://maplibre.org/maplibre-gl-js/docs/) for rendering. These traces were introduced in Plotly.py 5.24. These trace types are now the recommended way to make tile-based density heatmaps. There are also traces that use [Mapbox](https://docs.mapbox.com): `density_mapbox` and `go.Densitymapbox`. -To use these trace types, in some cases you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](/python/mapbox-layers/) documentation for more information. +To use these trace types, in some cases you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](mapbox-layers.md) documentation for more information. Here's one of the earlier examples rewritten to use `px.density_mapbox`. diff --git a/doc/python/discrete-color.md b/doc/python/discrete-color.md index 39d676bff34..b408efcf470 100644 --- a/doc/python/discrete-color.md +++ b/doc/python/discrete-color.md @@ -38,18 +38,18 @@ jupyter: ### Discrete vs Continuous Color -In the same way as the X or Y position of a mark in cartesian coordinates can be used to represent continuous values (i.e. amounts or moments in time) or categories (i.e. labels), color can be used to represent continuous or discrete data. This page is about using color to represent **categorical** data using discrete colors, but Plotly can also [represent continuous values with color](/python/colorscales/). +In the same way as the X or Y position of a mark in cartesian coordinates can be used to represent continuous values (i.e. amounts or moments in time) or categories (i.e. labels), color can be used to represent continuous or discrete data. This page is about using color to represent **categorical** data using discrete colors, but Plotly can also [represent continuous values with color](colorscales.md). ### Discrete Color Concepts This document explains the following discrete-color-related concepts: -- **color sequences** are lists of colors to be mapped onto discrete data values. No interpolation occurs when using color sequences, unlike with [continuous color scales](/python/colorscales/), and each color is used as-is. Color sequence defaults depend on the `layout.colorway` attribute of the active [template](/python/templates/), and can be explicitly specified using the `color_discrete_sequence` argument for many [Plotly Express](/python/plotly-express/) functions. -- **legends** are visible representations of the mapping between colors and data values. Legend markers also change shape when used with various kinds of traces, such as symbols or lines for scatter-like traces. [Legends are configurable](/python/legend/) under the `layout.legend` attribute. Legends are the discrete equivalent of [continuous color bars](/python/colorscales/) +- **color sequences** are lists of colors to be mapped onto discrete data values. No interpolation occurs when using color sequences, unlike with [continuous color scales](colorscales.md), and each color is used as-is. Color sequence defaults depend on the `layout.colorway` attribute of the active [template](templates.md), and can be explicitly specified using the `color_discrete_sequence` argument for many [Plotly Express](plotly-express.md) functions. +- **legends** are visible representations of the mapping between colors and data values. Legend markers also change shape when used with various kinds of traces, such as symbols or lines for scatter-like traces. [Legends are configurable](legend.md) under the `layout.legend` attribute. Legends are the discrete equivalent of [continuous color bars](colorscales.md) ### Discrete Color with Plotly Express -Most Plotly Express functions accept a `color` argument which automatically assigns data values to discrete colors **if the data is non-numeric**. If the data is numeric, the color will automatically be considered [continuous](/python/colorscales/). This means that numeric strings must be parsed to be used for continuous color, and conversely, numbers used as category codes must be converted to strings. +Most Plotly Express functions accept a `color` argument which automatically assigns data values to discrete colors **if the data is non-numeric**. If the data is numeric, the color will automatically be considered [continuous](colorscales.md). This means that numeric strings must be parsed to be used for continuous color, and conversely, numbers used as category codes must be converted to strings. For example, in the `tips` dataset, the `smoker` column contains strings: @@ -117,7 +117,7 @@ IFrame(snippet_url + 'discrete-color', width='100%', height=1200) ### Color Sequences in Plotly Express -By default, Plotly Express will use the color sequence from the active [template](/python/templates/)'s `layout.colorway` attribute, and the default active template is `plotly` which uses the `plotly` color sequence. You can choose any of the following built-in qualitative color sequences from the `px.colors.qualitative` module, however, or define your own. +By default, Plotly Express will use the color sequence from the active [template](templates.md)'s `layout.colorway` attribute, and the default active template is `plotly` which uses the `plotly` color sequence. You can choose any of the following built-in qualitative color sequences from the `px.colors.qualitative` module, however, or define your own. ```python import plotly.express as px @@ -205,7 +205,7 @@ fig.show() ### Controlling Discrete Color Order -Plotly Express lets you specify an ordering over categorical variables with `category_orders`, which will apply to colors and legends as well as symbols, [axes](/python/axes/) and [facets](/python/facet-plots/). This can be used with either `color_discrete_sequence` or `color_discrete_map`. +Plotly Express lets you specify an ordering over categorical variables with `category_orders`, which will apply to colors and legends as well as symbols, [axes](axes.md) and [facets](facet-plots.md). This can be used with either `color_discrete_sequence` or `color_discrete_map`. ```python import plotly.express as px @@ -238,7 +238,7 @@ fig.show() ### Using Sequential Scales as Discrete Sequences -In most cases, discrete/qualitative/categorical data values have no meaningful natural ordering, such as in the continents example used above. In some cases, however, there is a meaningful order, and in this case it can be helpful and appealing to use part of a continuous scale as a discrete sequence, as in the following [wind rose chart](/python/wind-rose-charts/): +In most cases, discrete/qualitative/categorical data values have no meaningful natural ordering, such as in the continents example used above. In some cases, however, there is a meaningful order, and in this case it can be helpful and appealing to use part of a continuous scale as a discrete sequence, as in the following [wind rose chart](wind-rose-charts.md): ```python import plotly.express as px @@ -250,7 +250,7 @@ fig = px.bar_polar(df, r="frequency", theta="direction", color="strength", fig.show() ``` -This works because just like in `px.colors.qualitative`, all [built-in continuous color scales](/python/builtin-colorscales/) are stored as lists of CSS colors: +This works because just like in `px.colors.qualitative`, all [built-in continuous color scales](builtin-colorscales.md) are stored as lists of CSS colors: ```python import plotly.express as px diff --git a/doc/python/distplot.md b/doc/python/distplot.md index 2d322e939df..4514b32bde2 100644 --- a/doc/python/distplot.md +++ b/doc/python/distplot.md @@ -37,7 +37,7 @@ jupyter: Several representations of statistical distributions are available in plotly, such as [histograms](https://plotly.com/python/histograms/), [violin plots](https://plotly.com/python/violin/), [box plots](https://plotly.com/python/box-plots/) (see [the complete list here](https://plotly.com/python/statistical-charts/)). It is also possible to combine several representations in the same plot. -For example, the `plotly.express` function `px.histogram` can add a subplot with a different statistical representation than the histogram, given by the parameter `marginal`. [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +For example, the `plotly.express` function `px.histogram` can add a subplot with a different statistical representation than the histogram, given by the parameter `marginal`. [Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px @@ -75,7 +75,7 @@ IFrame(snippet_url + 'distplot', width='100%', height=1200) ## Combined statistical representations with distplot figure factory -The distplot [figure factory](/python/figure-factories/) displays a combination of statistical representations of numerical data, such as histogram, kernel density estimation or normal curve, and rug plot. +The distplot [figure factory](figure-factories.md) displays a combination of statistical representations of numerical data, such as histogram, kernel density estimation or normal curve, and rug plot. #### Basic Distplot diff --git a/doc/python/dot-plots.md b/doc/python/dot-plots.md index 5d42411865d..d959516ea12 100644 --- a/doc/python/dot-plots.md +++ b/doc/python/dot-plots.md @@ -35,11 +35,11 @@ jupyter: #### Basic Dot Plot -Dot plots (also known as [Cleveland dot plots]()) are [scatter plots](https://plotly.com/python/line-and-scatter/) with one categorical axis and one continuous axis. They can be used to show changes between two (or more) points in time or between two (or more) conditions. Compared to a [bar chart](/python/bar-charts/), dot plots can be less cluttered and allow for an easier comparison between conditions. +Dot plots (also known as [Cleveland dot plots]()) are [scatter plots](https://plotly.com/python/line-and-scatter/) with one categorical axis and one continuous axis. They can be used to show changes between two (or more) points in time or between two (or more) conditions. Compared to a [bar chart](bar-charts.md), dot plots can be less cluttered and allow for an easier comparison between conditions. For the same data, we show below how to create a dot plot using either `px.scatter` or `go.Scatter`. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px diff --git a/doc/python/ecdf-plots.md b/doc/python/ecdf-plots.md index acc9a532b40..4b12134a1e5 100644 --- a/doc/python/ecdf-plots.md +++ b/doc/python/ecdf-plots.md @@ -35,7 +35,7 @@ jupyter: ### Overview -[Empirical cumulative distribution function plots](https://en.wikipedia.org/wiki/Empirical_distribution_function) are a way to visualize the distribution of a variable, and Plotly Express has a built-in function, `px.ecdf()` to generate such plots. [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Empirical cumulative distribution function plots](https://en.wikipedia.org/wiki/Empirical_distribution_function) are a way to visualize the distribution of a variable, and Plotly Express has a built-in function, `px.ecdf()` to generate such plots. [Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). Alternatives to ECDF plots for visualizing distributions include [histograms](https://plotly.com/python/histograms/), [violin plots](https://plotly.com/python/violin/), [box plots](https://plotly.com/python/box-plots/) and [strip charts](https://plotly.com/python/strip-charts/). diff --git a/doc/python/error-bars.md b/doc/python/error-bars.md index 3752f0cc539..8cd8212ed15 100644 --- a/doc/python/error-bars.md +++ b/doc/python/error-bars.md @@ -35,7 +35,7 @@ jupyter: ### Error Bars with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). For functions representing 2D data points such as [`px.scatter`](https://plotly.com/python/line-and-scatter/), [`px.line`](https://plotly.com/python/line-charts/), [`px.bar`](https://plotly.com/python/bar-charts/) etc., error bars are given as a column name which is the value of the `error_x` (for the error on x position) and `error_y` (for the error on y position). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). For functions representing 2D data points such as [`px.scatter`](https://plotly.com/python/line-and-scatter/), [`px.line`](https://plotly.com/python/line-charts/), [`px.bar`](https://plotly.com/python/bar-charts/) etc., error bars are given as a column name which is the value of the `error_x` (for the error on x position) and `error_y` (for the error on y position). ```python import plotly.express as px diff --git a/doc/python/facet-plots.md b/doc/python/facet-plots.md index 7a79ea06c2d..37f6b905b25 100644 --- a/doc/python/facet-plots.md +++ b/doc/python/facet-plots.md @@ -39,9 +39,9 @@ jupyter: ### Facet and Trellis Plots Facet plots, also known as trellis plots or small multiples, are figures made up of multiple subplots which have the same set of axes, where each subplot shows a subset of the data. While it is straightforward to use `plotly`'s -[subplot capabilities](/python/subplots/) to make such figures, it's far easier to use the built-in `facet_row` and `facet_col` arguments in the various Plotly Express functions. +[subplot capabilities](subplots.md) to make such figures, it's far easier to use the built-in `facet_row` and `facet_col` arguments in the various Plotly Express functions. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ### Scatter Plot Column Facets @@ -54,7 +54,7 @@ fig.show() ### Bar Chart Row Facets -There is a more presentation-ready horizontal, faceted bar chart in the [horizontal bar documentation](/python/horizontal-bar-charts/#Small-multiple-horizontal-bar-charts-show-each-component's-size-more-clearly-than-a-stacked-bar) +There is a more presentation-ready horizontal, faceted bar chart in the [horizontal bar documentation](horizontal-bar-charts.md#Small-multiple-horizontal-bar-charts-show-each-component's-size-more-clearly-than-a-stacked-bar) ```python import plotly.express as px @@ -109,7 +109,7 @@ fig.show() *introduced in plotly 4.12* -It is possible to add [labelled horizontal and vertical lines and rectangles](/python/horizontal-vertical-shapes/) to facet plots using `.add_hline()`, `.add_vline()`, `.add_hrect()` or `.add_vrect()`. The default `row` and `col` values are `"all"` but this can be overridden, as with the rectangle below, which only appears in the first column. +It is possible to add [labelled horizontal and vertical lines and rectangles](horizontal-vertical-shapes.md) to facet plots using `.add_hline()`, `.add_vline()`, `.add_hrect()` or `.add_vrect()`. The default `row` and `col` values are `"all"` but this can be overridden, as with the rectangle below, which only appears in the first column. ```python import plotly.express as px @@ -196,7 +196,7 @@ fig.show() ### Controlling Facet Ordering -By default, Plotly Express lays out categorical data in the order in which it appears in the underlying data. Every 2-d cartesian Plotly Express function also includes a `category_orders` keyword argument which can be used to control [the order in which categorical axes are drawn](/python/categorical-axes/), but beyond that can also control [the order in which discrete colors appear in the legend](/python/discrete-color/), and the order in which facets are laid out. +By default, Plotly Express lays out categorical data in the order in which it appears in the underlying data. Every 2-d cartesian Plotly Express function also includes a `category_orders` keyword argument which can be used to control [the order in which categorical axes are drawn](categorical-axes.md), but beyond that can also control [the order in which discrete colors appear in the legend](discrete-color.md), and the order in which facets are laid out. ```python import plotly.express as px diff --git a/doc/python/figure-factories.md b/doc/python/figure-factories.md index 20fadd7c818..0d3cbb413da 100644 --- a/doc/python/figure-factories.md +++ b/doc/python/figure-factories.md @@ -35,24 +35,24 @@ jupyter: #### `plotly.figure_factory` -The `plotly.figure_factory` module contains dedicated functions for creating very specific types of plots that were at the time of their creation difficult to create with [graph objects](/python/graph-objects/) and prior to the existence of [Plotly Express](/python/plotly-express/). As new functionality gets added to [Plotly.js](https://plotly.com/javascript/) and to Plotly Express, certain Figure Factories become unnecessary and are therefore deprecated as "legacy", but remain in the module for backwards-compatibility reasons. +The `plotly.figure_factory` module contains dedicated functions for creating very specific types of plots that were at the time of their creation difficult to create with [graph objects](graph-objects.md) and prior to the existence of [Plotly Express](plotly-express.md). As new functionality gets added to [Plotly.js](https://plotly.com/javascript/) and to Plotly Express, certain Figure Factories become unnecessary and are therefore deprecated as "legacy", but remain in the module for backwards-compatibility reasons. The following types of plots are still difficult to create with Graph Objects or Plotly Express and therefore the corresponding Figure Factories are *not* deprecated: - * [Dendrograms](/python/dendrogram/) - * [Hexagonal Binning Tile Map](/python/hexbin-mapbox/) - * [Quiver Plots](/python/quiver-plots/) - * [Streamline Plots](/python/streamline-plots/) - * [Tables](/python/figure-factory-table/) - * [Ternary Contour Plots](/python/ternary-contour/) - * [Triangulated Surface Plots](/python/trisurf/) + * [Dendrograms](dendrogram.md) + * [Hexagonal Binning Tile Map](hexbin-mapbox.md) + * [Quiver Plots](quiver-plots.md) + * [Streamline Plots](streamline-plots.md) + * [Tables](figure-factory-table.md) + * [Ternary Contour Plots](ternary-contour.md) + * [Triangulated Surface Plots](trisurf.md) Deprecated "legacy" Figure Factories include: - * [Annotated Heatmaps](/python/annotated-heatmap/), deprecated by [heatmaps with `px.imshow()`](/python/heatmaps/) - * [County Choropleth Maps](/python/county-choropleth/), deprecated by regular [Choropleth maps with GeoJSON input](/python/choropleth-maps/) - * [Distplots](/python/distplot/), mostly deprecated by [`px.histogram`](/python/histograms/) except for KDE plots, which `px.histogram` doesn't support yet - * [Gantt Charts](/python/gantt/), deprecated by [`px.timeline`](/python/gantt/) + * [Annotated Heatmaps](annotated-heatmap.md), deprecated by [heatmaps with `px.imshow()`](heatmaps.md) + * [County Choropleth Maps](county-choropleth.md), deprecated by regular [Choropleth maps with GeoJSON input](choropleth-maps.md) + * [Distplots](distplot.md), mostly deprecated by [`px.histogram`](histograms.md) except for KDE plots, which `px.histogram` doesn't support yet + * [Gantt Charts](gantt.md), deprecated by [`px.timeline`](gantt.md) #### Reference diff --git a/doc/python/figure-factory-subplots.md b/doc/python/figure-factory-subplots.md index 3a6c837692d..02cbeba6579 100644 --- a/doc/python/figure-factory-subplots.md +++ b/doc/python/figure-factory-subplots.md @@ -35,7 +35,7 @@ jupyter: #### Plotly's Figure Factory Module -Plotly's Python API contains a [figure factory module](/python/figure-factories/) which includes many wrapper functions that create unique chart types that are not yet included in [plotly.js](https://github.com/plotly/plotly.js), Plotly's open-source graphing library. The figure factory functions create a full figure, so some Plotly features, such as subplotting, should be implemented slightly differently with these charts. +Plotly's Python API contains a [figure factory module](figure-factories.md) which includes many wrapper functions that create unique chart types that are not yet included in [plotly.js](https://github.com/plotly/plotly.js), Plotly's open-source graphing library. The figure factory functions create a full figure, so some Plotly features, such as subplotting, should be implemented slightly differently with these charts. #### Vertical Figure Factory Charts diff --git a/doc/python/figure-factory-table.md b/doc/python/figure-factory-table.md index 5b4dbfa60c9..22b594c1f2b 100644 --- a/doc/python/figure-factory-table.md +++ b/doc/python/figure-factory-table.md @@ -35,7 +35,7 @@ jupyter: thumbnail: thumbnail/table.gif --- -Tables can be created using a [`table` trace type](/python/table/), or by using a [figure factory](/python/figure-factories/) as detailed in this page. +Tables can be created using a [`table` trace type](table.md), or by using a [figure factory](figure-factories.md) as detailed in this page. #### Simple Table diff --git a/doc/python/figure-introspection.md b/doc/python/figure-introspection.md index 3e85bc85f20..e7d7630e540 100644 --- a/doc/python/figure-introspection.md +++ b/doc/python/figure-introspection.md @@ -35,14 +35,14 @@ jupyter: ### The Figure Lifecycle -As explained in the [Figure Data Structure documentation](/python/figure-structure/), when building a figure object with Plotly.py, it is not necessary to populate every possible attribute. At render-time, figure objects (whether generated via [Plotly Express](/python/plotly-express/) or [Graph Objects](/python/graph-objects/)) are passed from Plotly.py to [Plotly.js](/javascript/), which is the Javascript library responsible for turning JSON descriptions of figures into graphical representations. +As explained in the [Figure Data Structure documentation](figure-structure.md), when building a figure object with Plotly.py, it is not necessary to populate every possible attribute. At render-time, figure objects (whether generated via [Plotly Express](plotly-express.md) or [Graph Objects](graph-objects.md)) are passed from Plotly.py to [Plotly.js](/javascript/), which is the Javascript library responsible for turning JSON descriptions of figures into graphical representations. As part of this rendering process, Plotly.js will determine, based on the attributes that have been set, which other attributes require values in order to draw the figure. Plotly.js will then apply either static or dynamic defaults to all of the remaining required attributes and render the figure. A good example of a static default would be the text font size: if unspecified, the default value is always the same. A good example of a dynamic default would be the range of an axis: if unspecified, the default will be computed based on the range of the data in traces associated with that axis. ### Introspecting Plotly Express Figures -Figure objects created by [Plotly Express](/python/plotly-express/) have a number of attributes automatically set, and these can be introspected using the Python `print()` function, or in JupyterLab, the special `fig.show("json")` renderer, which gives an interactive drilldown interface with search: +Figure objects created by [Plotly Express](plotly-express.md) have a number of attributes automatically set, and these can be introspected using the Python `print()` function, or in JupyterLab, the special `fig.show("json")` renderer, which gives an interactive drilldown interface with search: ```python import plotly.express as px @@ -62,9 +62,9 @@ help(fig.data[0].__class__.mode) _new in 4.10_ -The `.full_figure_for_development()` method provides Python-level access to the default values computed by Plotly.js. This method requires [the Kaleido package](/python/static-image-export/), which is easy to install and also used for [static image export](/python/static-image-export/). +The `.full_figure_for_development()` method provides Python-level access to the default values computed by Plotly.js. This method requires [the Kaleido package](static-image-export.md), which is easy to install and also used for [static image export](static-image-export.md). -By way of example, here is an extremely simple figure created with [Graph Objects](/python/graph-objects/) (although it could have been made with [Plotly Express](/python/plotly-express/) as well just like above) where we have disabled the default template for maximum readability. Note how in this figure the text labels on the markers are clipped, and sit on top of the markers. +By way of example, here is an extremely simple figure created with [Graph Objects](graph-objects.md) (although it could have been made with [Plotly Express](plotly-express.md) as well just like above) where we have disabled the default template for maximum readability. Note how in this figure the text labels on the markers are clipped, and sit on top of the markers. ```python import plotly.graph_objects as go @@ -135,9 +135,9 @@ help(go.layout.XAxis.autorange) ### More about Layout -In the figure we introspected above, we had added [a `scatter` trace](/python/line-and-scatter/), and Plotly.js automatically filled in for us the `xaxis` and `yaxis` values of that trace object to be `x` and `y`, and then also filled out the corresponding `layout.xaxis` and `layout.yaxis` objects for us, complete with their [extensive set of defaults for gridlines, tick labels and so on](/python/axes/). +In the figure we introspected above, we had added [a `scatter` trace](line-and-scatter.md), and Plotly.js automatically filled in for us the `xaxis` and `yaxis` values of that trace object to be `x` and `y`, and then also filled out the corresponding `layout.xaxis` and `layout.yaxis` objects for us, complete with their [extensive set of defaults for gridlines, tick labels and so on](axes.md). -If we create a figure with [a `scattergeo` trace](/python/scatter-plots-on-maps/) instead, however, Plotly.js will fill in a totally different set of objects in `layout`, corresponding to [a `geo` subplot, with all of its defaults for whether or not to show rivers, lakes, country borders, coastlines etc](https://plotly.com/python/map-configuration/). +If we create a figure with [a `scattergeo` trace](scatter-plots-on-maps.md) instead, however, Plotly.js will fill in a totally different set of objects in `layout`, corresponding to [a `geo` subplot, with all of its defaults for whether or not to show rivers, lakes, country borders, coastlines etc](https://plotly.com/python/map-configuration/). ```python import plotly.graph_objects as go @@ -168,7 +168,7 @@ print(full_fig.layout.geo) ### Reference -You can learn more about [all the available attributes in the plotly figure schema](/python/reference/) (and read about its [high-level structure](/python/figure-structure/)) or about [all the classes and functions in the `plotly` module](/python-api-reference/). +You can learn more about [all the available attributes in the plotly figure schema](/reference/) (and read about its [high-level structure](figure-structure.md)) or about [all the classes and functions in the `plotly` module](/python-api-reference/). ```python diff --git a/doc/python/figure-labels.md b/doc/python/figure-labels.md index ffd652c3cbe..a23cbc304bb 100644 --- a/doc/python/figure-labels.md +++ b/doc/python/figure-labels.md @@ -36,7 +36,7 @@ jupyter: ### Automatic Labelling with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). When using Plotly Express, your axes and legend are automatically labelled, and it's easy to override the automation for a customized figure using the `labels` keyword argument. The title of your figure is up to you though! @@ -124,7 +124,7 @@ IFrame(snippet_url + 'figure-labels', width='100%', height=1200) ### Manual Labelling with Graph Objects -When using [graph objects](/python/graph-objects/) rather than [Plotly Express](/python/plotly-express/), you will need to explicitly label traces and axes: +When using [graph objects](graph-objects.md) rather than [Plotly Express](plotly-express.md), you will need to explicitly label traces and axes: ```python import plotly.graph_objects as go @@ -241,7 +241,7 @@ fig = go.Figure( fig.show() ``` -The configuration of the legend is discussed in detail in the [Legends](/python/legend/) page. +The configuration of the legend is discussed in detail in the [Legends](legend.md) page. ### Align Plot Title The following example shows how to align the plot title in [layout.title](https://plotly.com/python/reference/layout/#layout-title). `x` sets the x position with respect to `xref` from "0" (left) to "1" (right), and `y` sets the y position with respect to `yref` from "0" (bottom) to "1" (top). Moreover, you can define `xanchor` to `left`,`right`, or `center` for setting the title's horizontal alignment with respect to its x position, and/or `yanchor` to `top`, `bottom`, or `middle` for setting the title's vertical alignment with respect to its y position. diff --git a/doc/python/figure-structure.md b/doc/python/figure-structure.md index f55abad91b5..24e85f7387d 100644 --- a/doc/python/figure-structure.md +++ b/doc/python/figure-structure.md @@ -35,9 +35,9 @@ jupyter: ### Overview -The `plotly` Python package exists to [create, manipulate](/python/creating-and-updating-figures/) and [render](/python/renderers/) graphical figures (i.e. charts, plots, maps and diagrams) represented by data structures also referred to as figures. The rendering process uses the [Plotly.js JavaScript library](https://plotly.com/javascript/) under the hood although Python developers using this module very rarely need to interact with the Javascript library directly, if ever. Figures can be represented in Python either as dicts or as instances of the `plotly.graph_objects.Figure` class, and are serialized as text in [JavaScript Object Notation (JSON)](https://json.org/) before being passed to Plotly.js. +The `plotly` Python package exists to [create, manipulate](creating-and-updating-figures.md) and [render](renderers.md) graphical figures (i.e. charts, plots, maps and diagrams) represented by data structures also referred to as figures. The rendering process uses the [Plotly.js JavaScript library](https://plotly.com/javascript/) under the hood although Python developers using this module very rarely need to interact with the Javascript library directly, if ever. Figures can be represented in Python either as dicts or as instances of the `plotly.graph_objects.Figure` class, and are serialized as text in [JavaScript Object Notation (JSON)](https://json.org/) before being passed to Plotly.js. -> Note: the recommended entry-point into the plotly package is the [high-level plotly.express module, also known as Plotly Express](/python/plotly-express/), which consists of Python functions which return fully-populated `plotly.graph_objects.Figure` objects. This page exists to document the architecture of the data structure that these objects represent, for users who wish to understand more about how to customize them, or assemble them from [other `plotly.graph_objects` components](/python/graph-objects/). +> Note: the recommended entry-point into the plotly package is the [high-level plotly.express module, also known as Plotly Express](plotly-express.md), which consists of Python functions which return fully-populated `plotly.graph_objects.Figure` objects. This page exists to document the architecture of the data structure that these objects represent, for users who wish to understand more about how to customize them, or assemble them from [other `plotly.graph_objects` components](graph-objects.md). Viewing the underlying data structure for any `plotly.graph_objects.Figure` object, including those returned by Plotly Express, can be done via `print(fig)` or, in JupyterLab, with the special `fig.show("json")` renderer. Figures also support `fig.to_dict()` and `fig.to_json()` methods. `print()`ing the figure will result in the often-verbose `layout.template` key being represented as ellipses `'...'` for brevity. @@ -68,22 +68,22 @@ IFrame(snippet_url + 'figure-structure', width='100%', height=1200) ### Figures as Trees of Attributes -Plotly.js supports inputs adhering to a well-defined schema, whose overall architecture is explained in this page and which is exhaustively documented in the [Figure Reference](/python/reference/index/) (which is itself generated from a [machine-readable JSON representation of the schema](https://raw.githubusercontent.com/plotly/plotly.js/master/dist/plot-schema.json)). Figures are represented as trees with named nodes called "attributes". The root node of the tree has three top-level attributes: `data`, `layout` and `frames` (see below). +Plotly.js supports inputs adhering to a well-defined schema, whose overall architecture is explained in this page and which is exhaustively documented in the [Figure Reference](reference/index.md) (which is itself generated from a [machine-readable JSON representation of the schema](https://raw.githubusercontent.com/plotly/plotly.js/master/dist/plot-schema.json)). Figures are represented as trees with named nodes called "attributes". The root node of the tree has three top-level attributes: `data`, `layout` and `frames` (see below). -Attributes are referred to in text and in the [Figure Reference](/python/reference/index/) by their full "path" i.e. the dot-delimited concatenation of their parents. For example `"layout.width"` refers to the attribute whose key is `"width"` inside a dict which is the value associated with a key `"layout"` at the root of the figure. If one of the parents is a list rather than a dict, a set of brackets is inserted in the path when referring to the attribute in the abstract, e.g. `"layout.annotations[].text"`. Finally, as explained below, the top-level "data" attribute defines a list of typed objects called "traces" with the schema dependent upon the type, and these attributes' paths are listed in the [Figure Reference](/python/reference/index/) as `"data[type=scatter].name"`. +Attributes are referred to in text and in the [Figure Reference](reference/index.md) by their full "path" i.e. the dot-delimited concatenation of their parents. For example `"layout.width"` refers to the attribute whose key is `"width"` inside a dict which is the value associated with a key `"layout"` at the root of the figure. If one of the parents is a list rather than a dict, a set of brackets is inserted in the path when referring to the attribute in the abstract, e.g. `"layout.annotations[].text"`. Finally, as explained below, the top-level "data" attribute defines a list of typed objects called "traces" with the schema dependent upon the type, and these attributes' paths are listed in the [Figure Reference](reference/index.md) as `"data[type=scatter].name"`. -The [`plotly.graph_objects` module contains an automatically-generated hierarchy of Python classes](/python/graph-objects/) which represent non-leaf attributes in the figure schema and provide a Pythonic API for them. When [manipulating a `plotly.graph_objects.Figure` object](/python/creating-and-updating-figures/), attributes can be set either directly using Python object attributes e.g. `fig.layout.title.font.family="Open Sans"` or using [update methods and "magic underscores"](/python/creating-and-updating-figures/#magic-underscore-notation) e.g. `fig.update_layout(title_font_family="Open Sans")` +The [`plotly.graph_objects` module contains an automatically-generated hierarchy of Python classes](graph-objects.md) which represent non-leaf attributes in the figure schema and provide a Pythonic API for them. When [manipulating a `plotly.graph_objects.Figure` object](creating-and-updating-figures.md), attributes can be set either directly using Python object attributes e.g. `fig.layout.title.font.family="Open Sans"` or using [update methods and "magic underscores"](../creating-and-updating-figures/#magic-underscore-notation) e.g. `fig.update_layout(title_font_family="Open Sans")` -When building a figure, it is *not necessary to populate every attribute* of every object. At render-time, [the JavaScript layer will compute default values](/python/figure-introspection/) for each required unspecified attribute, depending upon the ones that are specified, as documented in the [Figure Reference](/python/reference/index/). An example of this would be `layout.xaxis.range`, which may be specified explicitly, but if not will be computed based on the range of `x` values for every trace linked to that axis. The JavaScript layer will ignore unknown attributes or malformed values, although the `plotly.graph_objects` module provides Python-side validation for attribute values. Note also that if [the `layout.template` key is present (as it is by default)](/python/templates/) then default values will be drawn first from the contents of the template and only if missing from there will the JavaScript layer infer further defaults. The built-in template can be disabled by setting `layout.template="none"`. +When building a figure, it is *not necessary to populate every attribute* of every object. At render-time, [the JavaScript layer will compute default values](figure-introspection.md) for each required unspecified attribute, depending upon the ones that are specified, as documented in the [Figure Reference](reference/index.md). An example of this would be `layout.xaxis.range`, which may be specified explicitly, but if not will be computed based on the range of `x` values for every trace linked to that axis. The JavaScript layer will ignore unknown attributes or malformed values, although the `plotly.graph_objects` module provides Python-side validation for attribute values. Note also that if [the `layout.template` key is present (as it is by default)](templates.md) then default values will be drawn first from the contents of the template and only if missing from there will the JavaScript layer infer further defaults. The built-in template can be disabled by setting `layout.template="none"`. ### The Top-Level `data` Attribute The first of the three top-level attributes of a figure is `data`, whose value must be a list of dicts referred to as "traces". -* Each trace has one of more than 40 possible types (see below for a list organized by subplot type, including e.g. [`scatter`](/python/line-and-scatter/), [`bar`](/python/bar-charts/), [`pie`](/python/pie-charts/), [`surface`](/python/3d-surface-plots/), [`choropleth`](/python/choropleth-maps/) etc), and represents a set of related graphical marks in a figure. Each trace must have a `type` attribute which defines the other allowable attributes. -* Each trace is drawn on a single [subplot](/python/subplots/) whose type must be compatible with the trace's type, or is its own subplot (see below). -* Traces may have a single [legend](/python/legend/) entry, with the exception of pie and funnelarea traces (see below). -* Certain trace types support [continuous color, with an associated colorbar](/python/colorscales/), which can be controlled by attributes either within the trace, or within the layout when using the [coloraxis attribute](/python/colorscales/). +* Each trace has one of more than 40 possible types (see below for a list organized by subplot type, including e.g. [`scatter`](line-and-scatter.md), [`bar`](bar-charts.md), [`pie`](pie-charts.md), [`surface`](3d-surface-plots.md), [`choropleth`](choropleth-maps.md) etc), and represents a set of related graphical marks in a figure. Each trace must have a `type` attribute which defines the other allowable attributes. +* Each trace is drawn on a single [subplot](subplots.md) whose type must be compatible with the trace's type, or is its own subplot (see below). +* Traces may have a single [legend](legend.md) entry, with the exception of pie and funnelarea traces (see below). +* Certain trace types support [continuous color, with an associated colorbar](colorscales.md), which can be controlled by attributes either within the trace, or within the layout when using the [coloraxis attribute](colorscales.md). ### The Top-Level `layout` Attribute @@ -91,28 +91,28 @@ The first of the three top-level attributes of a figure is `data`, whose value m The second of the three top-level attributes of a figure is `layout`, whose value is referred to in text as "the layout" and must be a dict, containing attributes that control positioning and configuration of non-data-related parts of the figure such as: * Dimensions and margins, which define the bounds of "paper coordinates" (see below) - * Figure-wide defaults: [templates](/python/templates/), [fonts](/python/figure-labels/), colors, hover-label and modebar defaults - * [Title](/python/figure-labels/) and [legend](/python/legend/) (positionable in container and/or paper coordinates) - * [Color axes and associated color bars](/python/colorscales/) (positionable in paper coordinates) + * Figure-wide defaults: [templates](templates.md), [fonts](figure-labels.md), colors, hover-label and modebar defaults + * [Title](figure-labels.md) and [legend](legend.md) (positionable in container and/or paper coordinates) + * [Color axes and associated color bars](colorscales.md) (positionable in paper coordinates) * Subplots of various types on which can be drawn multiple traces and which are positioned in paper coordinates: * `xaxis`, `yaxis`, `xaxis2`, `yaxis3` etc: X and Y cartesian axes, the intersections of which are cartesian subplots * `scene`, `scene2`, `scene3` etc: 3d scene subplots * `ternary`, `ternary2`, `ternary3`, `polar`, `polar2`, `polar3`, `geo`, `geo2`, `geo3`, `map`, `map2`, `map3`, `smith`, `smith2` etc: ternary, polar, geo, map or smith subplots * Non-data marks which can be positioned in paper coordinates, or in data coordinates linked to 2d cartesian subplots: - * `annotations`: [textual annotations with or without arrows](/python/text-and-annotations/) - * `shapes`: [lines, rectangles, ellipses or open or closed paths](/python/shapes/) - * `images`: [background or decorative images](/python/images/) + * `annotations`: [textual annotations with or without arrows](text-and-annotations.md) + * `shapes`: [lines, rectangles, ellipses or open or closed paths](shapes.md) + * `images`: [background or decorative images](images.md) * Controls which can be positioned in paper coordinates and which can trigger Plotly.js functions when interacted with by a user: - * `updatemenus`: [single buttons, toggles](/python/custom-buttons/) and [dropdown menus](/python/dropdowns/) - * `sliders`: [slider controls](/python/sliders/) + * `updatemenus`: [single buttons, toggles](custom-buttons.md) and [dropdown menus](dropdowns.md) + * `sliders`: [slider controls](sliders.md) ### The Top-Level `frames` Attribute -The third of the three top-level attributes of a figure is `frames`, whose value must be a list of dicts that define sequential frames in an [animated plot](/python/animations/). Each frame contains its own data attribute as well as other parameters. Animations are usually triggered and controlled via controls defined in layout.sliders and/or layout.updatemenus +The third of the three top-level attributes of a figure is `frames`, whose value must be a list of dicts that define sequential frames in an [animated plot](animations.md). Each frame contains its own data attribute as well as other parameters. Animations are usually triggered and controlled via controls defined in layout.sliders and/or layout.updatemenus ### The `config` Object -At [render-time](/python/renderers/), it is also possible to control certain figure behaviors which are not considered part of the figure proper i.e. the behavior of the "modebar" and how the figure relates to mouse actions like scrolling etc. The object that contains these options is called the [`config`, and has its own documentation page](/python/configuration-options/). It is exposed in Python as the `config` keyword argument of the `.show()` method on `plotly.graph_objects.Figure` objects. +At [render-time](renderers.md), it is also possible to control certain figure behaviors which are not considered part of the figure proper i.e. the behavior of the "modebar" and how the figure relates to mouse actions like scrolling etc. The object that contains these options is called the [`config`, and has its own documentation page](configuration-options.md). It is exposed in Python as the `config` keyword argument of the `.show()` method on `plotly.graph_objects.Figure` objects. ### Positioning With Paper, Container Coordinates, or Axis Domain Coordinates @@ -139,60 +139,60 @@ and position of the axis named `y2`. ### 2D Cartesian Trace Types and Subplots -The most commonly-used kind of subplot is a [two-dimensional Cartesian subplot](/python/axes/). Traces compatible with these subplots support `xaxis` and `yaxis` attributes whose values must refer to corresponding objects in the layout portion of the figure. For example, if `xaxis="x"`, and `yaxis="y"` (which is the default) then this trace is drawn on the subplot at the intersection of the axes configured under `layout.xaxis` and `layout.yaxis`, but if `xaxis="x2"` and `yaxis="y3"` then the trace is drawn at the intersection of the axes configured under `layout.xaxis2` and `layout.yaxis3`. Note that attributes such as `layout.xaxis` and `layout.xaxis2` etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of different types can be drawn on the same subplot. +The most commonly-used kind of subplot is a [two-dimensional Cartesian subplot](axes.md). Traces compatible with these subplots support `xaxis` and `yaxis` attributes whose values must refer to corresponding objects in the layout portion of the figure. For example, if `xaxis="x"`, and `yaxis="y"` (which is the default) then this trace is drawn on the subplot at the intersection of the axes configured under `layout.xaxis` and `layout.yaxis`, but if `xaxis="x2"` and `yaxis="y3"` then the trace is drawn at the intersection of the axes configured under `layout.xaxis2` and `layout.yaxis3`. Note that attributes such as `layout.xaxis` and `layout.xaxis2` etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of different types can be drawn on the same subplot. -X- and Y-axes support the `type` attribute, which enables them to represent [continuous values (`type="linear"`, `type="log"`)](/python/axes/), [temporal values (`type="date"`)](/python/time-series/) or [categorical values (`type="category"`, `type="multicategory`)](/python/bar-charts/). Axes can also be overlaid on top of one another to create [dual-axis or multiple-axis charts](/python/multiple-axes/). 2-d cartesian subplots lend themselves very well to creating ["small multiples" figures, also known as facet or trellis plots](/python/facet-plots/). +X- and Y-axes support the `type` attribute, which enables them to represent [continuous values (`type="linear"`, `type="log"`)](axes.md), [temporal values (`type="date"`)](time-series.md) or [categorical values (`type="category"`, `type="multicategory`)](bar-charts.md). Axes can also be overlaid on top of one another to create [dual-axis or multiple-axis charts](multiple-axes.md). 2-d cartesian subplots lend themselves very well to creating ["small multiples" figures, also known as facet or trellis plots](facet-plots.md). The following trace types are compatible with 2d-cartesian subplots via the `xaxis` and `yaxis` attributes: -* scatter-like trace types: [`scatter`](/python/line-and-scatter/) and [`scattergl`](/python/webgl-vs-svg/), which can be used to draw [scatter plots](/python/line-and-scatter/), [line plots and curves](/python/line-charts/), [time-series plots](/python/time-series/), [bubble charts](/python/bubble-charts/), [dot plots](/python/dot-plots/) and [filled areas](/python/filled-area-plots/) and also support [error bars](/python/error-bars/) -* [`bar`](/python/bar-charts/), [`funnel`](/python/funnel-charts/), [`waterfall`](/python/waterfall-charts/): bar-like trace types which can also be used to draw [timelines and Gantt charts](/python/gantt/) -* [`histogram`](/python/histograms/): an *aggregating* bar-like trace type -* [`box`](/python/box-plots/) and [`violin`](/python/box-plots/): 1-dimensional distribution-like trace types -* [`histogram2d`](/python/2D-Histogram/) and [`histogram2dcontour`](/python/2d-histogram-contour/): 2-dimensional distribution-like density trace types -* [`image`](/python/imshow/), [`heatmap`](/python/heatmaps/) and [`contour`](/python/contour-plots/): matrix trace types -* [`ohlc`](/python/ohlc-charts/) and [`candlestick`](/python/candlestick-charts/): stock-like trace types -* [`carpet`](/python/carpet-plot/): a special trace type for building [carpet plots](/python/carpet-plot/), in that other traces can use as subplots (see below) -* [`splom`](/python/splom/): multi-dimensional scatter plots which implicitly refer to many 2-d cartesian subplots at once. +* scatter-like trace types: [`scatter`](line-and-scatter.md) and [`scattergl`](webgl-vs-svg.md), which can be used to draw [scatter plots](line-and-scatter.md), [line plots and curves](line-charts.md), [time-series plots](time-series.md), [bubble charts](bubble-charts.md), [dot plots](dot-plots.md) and [filled areas](filled-area-plots.md) and also support [error bars](error-bars.md) +* [`bar`](bar-charts.md), [`funnel`](funnel-charts.md), [`waterfall`](waterfall-charts.md): bar-like trace types which can also be used to draw [timelines and Gantt charts](gantt.md) +* [`histogram`](histograms.md): an *aggregating* bar-like trace type +* [`box`](box-plots.md) and [`violin`](box-plots.md): 1-dimensional distribution-like trace types +* [`histogram2d`](2D-Histogram.md) and [`histogram2dcontour`](2d-histogram-contour.md): 2-dimensional distribution-like density trace types +* [`image`](imshow.md), [`heatmap`](heatmaps.md) and [`contour`](contour-plots.md): matrix trace types +* [`ohlc`](ohlc-charts.md) and [`candlestick`](candlestick-charts.md): stock-like trace types +* [`carpet`](carpet-plot.md): a special trace type for building [carpet plots](carpet-plot.md), in that other traces can use as subplots (see below) +* [`splom`](splom.md): multi-dimensional scatter plots which implicitly refer to many 2-d cartesian subplots at once. ### 3D, Polar, Ternary and Smith Trace Types and Subplots -Beyond 2D cartesian subplots, figures can include [three-dimensional cartesian subplots](/python/3d-charts/), [polar subplots](/python/polar-chart/), [ternary subplots](/python/ternary-plots/) and [smith subplots](/python/smith-charts/). The following trace types support attributes named `scene`, `polar`, `smith` or `ternary`, whose values must refer to corresponding objects in the layout portion of the figure i.e. `ternary="ternary2"` etc. Note that attributes such as `layout.scene` and `layout.ternary2` etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of a compatible type can be placed on the same subplot. +Beyond 2D cartesian subplots, figures can include [three-dimensional cartesian subplots](3d-charts.md), [polar subplots](polar-chart.md), [ternary subplots](ternary-plots.md) and [smith subplots](smith-charts.md). The following trace types support attributes named `scene`, `polar`, `smith` or `ternary`, whose values must refer to corresponding objects in the layout portion of the figure i.e. `ternary="ternary2"` etc. Note that attributes such as `layout.scene` and `layout.ternary2` etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of a compatible type can be placed on the same subplot. -The following trace types are compatible with 3D subplots via the `scene` attribute, which contains special [camera controls](/python/3d-camera-controls/): +The following trace types are compatible with 3D subplots via the `scene` attribute, which contains special [camera controls](3d-camera-controls.md): -* [`scatter3d`](/python/3d-scatter-plots/), which can be used to draw [individual markers](/python/3d-scatter-plots/), [3d bubble charts](/python/3d-bubble-charts/) and [lines and curves](/python/3d-line-plots/) -* [`surface`](/python/3d-surface-plots/) and [`mesh`](/python/3d-mesh/): 3d surface trace types -* [`cone`](/python/cone-plot/) and [`streamtube`](/python/streamtube-plot/): 3d vector field trace types -* [`volume`](/python/3d-volume-plots/) and [`isosurface`](/python/3d-isosurface-plots/): 3d volume trace types +* [`scatter3d`](3d-scatter-plots.md), which can be used to draw [individual markers](3d-scatter-plots.md), [3d bubble charts](3d-bubble-charts.md) and [lines and curves](3d-line-plots.md) +* [`surface`](3d-surface-plots.md) and [`mesh`](3d-mesh.md): 3d surface trace types +* [`cone`](cone-plot.md) and [`streamtube`](streamtube-plot.md): 3d vector field trace types +* [`volume`](3d-volume-plots.md) and [`isosurface`](3d-isosurface-plots.md): 3d volume trace types The following trace types are compatible with polar subplots via the `polar` attribute: -* scatter-like trace types: [`scatterpolar` and `scatterpolargl`](/python/polar-chart/), which can be used to draw individual markers, [curves and filled areas (i.e. radar or spider charts)](/python/radar-chart/) -* [`barpolar`](/python/wind-rose-charts/): useful for [wind roses](/python/wind-rose-charts/) and other polar bar charts +* scatter-like trace types: [`scatterpolar` and `scatterpolargl`](polar-chart.md), which can be used to draw individual markers, [curves and filled areas (i.e. radar or spider charts)](radar-chart.md) +* [`barpolar`](wind-rose-charts.md): useful for [wind roses](wind-rose-charts.md) and other polar bar charts The following trace types are compatible with ternary subplots via the `ternary` attribute: -* [`scatterternary`](/python/ternary-plots/), which can be used to draw individual markers, [curves and filled areas](/python/ternary-contour/) +* [`scatterternary`](ternary-plots.md), which can be used to draw individual markers, [curves and filled areas](ternary-contour.md) The following trace types are compatible with smith subplots via the `smith` attribute: -* [`scattersmith`](/python/smith-charts/), which can be used to draw individual markers, curves and filled areas +* [`scattersmith`](smith-charts.md), which can be used to draw individual markers, curves and filled areas ### Map Trace Types and Subplots -Figures can include two different types of map subplots: [geo subplots for outline maps](/python/map-configuration/) and [tile-based maps](/python/tile-map-layers/). The following trace types support attributes named `geo` or `map`, whose values must refer to corresponding objects in the layout i.e. `geo="geo2"` etc. Note that attributes such as `layout.geo2` and `layout.map` etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of a compatible type can be placed on the same subplot. +Figures can include two different types of map subplots: [geo subplots for outline maps](map-configuration.md) and [tile-based maps](tile-map-layers.md). The following trace types support attributes named `geo` or `map`, whose values must refer to corresponding objects in the layout i.e. `geo="geo2"` etc. Note that attributes such as `layout.geo2` and `layout.map` etc do not have to be explicitly defined, in which case default values will be inferred. Multiple traces of a compatible type can be placed on the same subplot. The following trace types are compatible with geo subplots via the `geo` attribute: -* [`scattergeo`](/python/scatter-plots-on-maps/), which can be used to draw [individual markers](/python/scatter-plots-on-maps/), [line and curves](/python/lines-on-maps/) and filled areas on outline maps -* [`choropleth`](/python/choropleth-maps/): [colored polygons](/python/choropleth-maps/) on outline maps +* [`scattergeo`](scatter-plots-on-maps.md), which can be used to draw [individual markers](scatter-plots-on-maps.md), [line and curves](lines-on-maps.md) and filled areas on outline maps +* [`choropleth`](choropleth-maps.md): [colored polygons](choropleth-maps.md) on outline maps The following trace types are compatible with tile map subplots via the `map` attribute: -* [`scattermap`](/python/tile-scatter-maps/), which can be used to draw [individual markers](/python/tile-scatter-maps/), [lines and curves](/python/lines-on-tile-maps/) and [filled areas](/python/filled-area-tile-maps/) on tile maps -* [`choroplethmap`](/python/tile-county-choropleth/): colored polygons on tile maps -* [`densitymap`](/python/tile-density-heatmaps/): density heatmaps on tile maps +* [`scattermap`](tile-scatter-maps.md), which can be used to draw [individual markers](tile-scatter-maps.md), [lines and curves](lines-on-tile-maps.md) and [filled areas](filled-area-tile-maps.md) on tile maps +* [`choroplethmap`](tile-county-choropleth.md): colored polygons on tile maps +* [`densitymap`](tile-density-heatmaps.md): density heatmaps on tile maps ### Traces Which Are Their Own Subplots @@ -200,29 +200,29 @@ Certain trace types cannot share subplots, and hence have no attribute to map to The following trace types are their own subplots and support a domain attribute: -* [`pie`](/python/pie-charts/) and [`funnelarea`](/python/waterfall-charts/): one-level part-to-whole relationships with legend items -* [`sunburst`](/python/sunburst-charts/) and [`treemap`](/python/treemaps/): hierarchical multi-level part-to-whole relationships -* [`parcoords`](/python/parallel-coordinates-plot/) and [`parcats`](/python/parallel-categories-diagram/): continuous and categorical multidimensional figures with [parallel coordinates](/python/parallel-coordinates-plot/) and [parallel sets](/python/parallel-categories-diagram/) -* [`sankey`](/python/sankey-diagram/): [flow diagrams](/python/sankey-diagram/) -* [`table`](/python/table/): [text-based tables](/python/table/) -* [`indicator`](/python/indicator/): big numbers, [gauges](/python/gauge-charts/), and [bullet charts](/python/bullet-charts/) +* [`pie`](pie-charts.md) and [`funnelarea`](waterfall-charts.md): one-level part-to-whole relationships with legend items +* [`sunburst`](sunburst-charts.md) and [`treemap`](treemaps.md): hierarchical multi-level part-to-whole relationships +* [`parcoords`](parallel-coordinates-plot.md) and [`parcats`](parallel-categories-diagram.md): continuous and categorical multidimensional figures with [parallel coordinates](parallel-coordinates-plot.md) and [parallel sets](parallel-categories-diagram.md) +* [`sankey`](sankey-diagram.md): [flow diagrams](sankey-diagram.md) +* [`table`](table.md): [text-based tables](table.md) +* [`indicator`](indicator.md): big numbers, [gauges](gauge-charts.md), and [bullet charts](bullet-charts.md) ### Carpet Trace Types and Subplots -Certain trace types use [traces of type `carpet` as a subplot](/python/carpet-plot/). These support a `carpet` attribute whose value must match the value of the `carpet` attribute of the `carpet` trace they are to be drawn on. Multiple compatible traces can be placed on the same `carpet` trace. +Certain trace types use [traces of type `carpet` as a subplot](carpet-plot.md). These support a `carpet` attribute whose value must match the value of the `carpet` attribute of the `carpet` trace they are to be drawn on. Multiple compatible traces can be placed on the same `carpet` trace. The following trace types are compatible with `carpet` trace subplots via the `carpet` attribute: -* [`scattercarpet`](/python/carpet-scatter/), which can be used to draw individual markers, curves and filled areas -* [`contourcarpet`](/python/carpet-plot/) +* [`scattercarpet`](carpet-scatter.md), which can be used to draw individual markers, curves and filled areas +* [`contourcarpet`](carpet-plot.md) ### Trace Types, Legends and Color Bars -Traces of most types can be optionally associated with a single legend item in the [legend](/python/legend/). Whether or not a given trace appears in the legend is controlled via the `showlegend` attribute. Traces which are their own subplots (see above) do not support this, with the exception of traces of type `pie` and `funnelarea` for which every distinct color represented in the trace gets a separate legend item. Users may show or hide traces by clicking or double-clicking on their associated legend item. Traces that support legend items also support the `legendgroup` attribute, and all traces with the same legend group are treated the same way during click/double-click interactions. +Traces of most types can be optionally associated with a single legend item in the [legend](legend.md). Whether or not a given trace appears in the legend is controlled via the `showlegend` attribute. Traces which are their own subplots (see above) do not support this, with the exception of traces of type `pie` and `funnelarea` for which every distinct color represented in the trace gets a separate legend item. Users may show or hide traces by clicking or double-clicking on their associated legend item. Traces that support legend items also support the `legendgroup` attribute, and all traces with the same legend group are treated the same way during click/double-click interactions. -The fact that legend items are linked to traces means that when using [discrete color](/python/discrete-color/), a figure must have one trace per color in order to get a meaningful legend. [Plotly Express has robust support for discrete color](/python/discrete-color/) to make this easy. +The fact that legend items are linked to traces means that when using [discrete color](discrete-color.md), a figure must have one trace per color in order to get a meaningful legend. [Plotly Express has robust support for discrete color](discrete-color.md) to make this easy. -Traces which support [continuous color](/python/colorscales/) can also be associated with color axes in the layout via the `coloraxis` attribute. Multiple traces can be linked to the same color axis. Color axes have a legend-like component called color bars. Alternatively, color axes can be configured within the trace itself. +Traces which support [continuous color](colorscales.md) can also be associated with color axes in the layout via the `coloraxis` attribute. Multiple traces can be linked to the same color axis. Color axes have a legend-like component called color bars. Alternatively, color axes can be configured within the trace itself. ```python diff --git a/doc/python/figurewidget-app.md b/doc/python/figurewidget-app.md index 4a6baf9febe..3e6a412795c 100644 --- a/doc/python/figurewidget-app.md +++ b/doc/python/figurewidget-app.md @@ -154,9 +154,9 @@ widgets.VBox([container, g]) ``` -```html + -``` + #### Reference diff --git a/doc/python/figurewidget.md b/doc/python/figurewidget.md index 9482c29f767..47eca5df5d9 100644 --- a/doc/python/figurewidget.md +++ b/doc/python/figurewidget.md @@ -56,11 +56,11 @@ f Add traces or update the layout and then watch the output above update in real time. ```python -f.add_scatter(y=[2, 1, 4, 3]); +f.add_scatter(y=[2, 1, 4, 3]) ``` ```python -f.add_bar(y=[1, 4, 3, 2]); +f.add_bar(y=[1, 4, 3, 2]) ``` ```python diff --git a/doc/python/filled-area-plots.md b/doc/python/filled-area-plots.md index 33446f02932..7cf3e7ac1fd 100644 --- a/doc/python/filled-area-plots.md +++ b/doc/python/filled-area-plots.md @@ -37,7 +37,7 @@ This example shows how to fill the area enclosed by traces. ## Filled area plot with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). `px.area` creates a stacked area plot. Each filled area corresponds to one value of the column given by the `line_group` parameter. @@ -69,7 +69,7 @@ IFrame(snippet_url + 'filled-area-plots', width='100%', height=1200) *New in v5.7* -Area charts afford the use of [patterns (also known as hatching or texture)](/python/pattern-hatching-texture/) in addition to color: +Area charts afford the use of [patterns (also known as hatching or texture)](pattern-hatching-texture.md) in addition to color: ```python import plotly.express as px diff --git a/doc/python/filled-area-tile-maps.md b/doc/python/filled-area-tile-maps.md index 8e0af02484b..3366f686ade 100644 --- a/doc/python/filled-area-tile-maps.md +++ b/doc/python/filled-area-tile-maps.md @@ -141,7 +141,7 @@ fig.show() The earlier examples using `go.Scattermap` use [Maplibre](https://maplibre.org/maplibre-gl-js/docs/) for rendering. This trace was introduced in Plotly.py 5.24 and is now the recommended way to draw filled areas on tile-based maps. There is also a trace that uses [Mapbox](https://docs.mapbox.com), called `go.Scattermapbox`. -To use the `Scattermapbox` trace type, in some cases you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](/python/mapbox-layers/) documentation for more information. +To use the `Scattermapbox` trace type, in some cases you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](mapbox-layers.md) documentation for more information. Here's one of the earlier examples rewritten to use `Scattermapbox`. diff --git a/doc/python/funnel-charts.md b/doc/python/funnel-charts.md index f22067be3cf..91d87c36be2 100644 --- a/doc/python/funnel-charts.md +++ b/doc/python/funnel-charts.md @@ -30,7 +30,7 @@ Funnel charts are often used to represent data in different stages of a business ### Basic Funnel Plot with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.funnel`, each row of the DataFrame is represented as a stage of the funnel. @@ -60,7 +60,7 @@ fig.show() ### Basic Funnel Chart with graph_objects trace go.Funnel -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Funnel` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Funnel` class from `plotly.graph_objects`](graph-objects.md). ```python from plotly import graph_objects as go @@ -138,7 +138,7 @@ fig.show() ### Basic Area Funnel Plot with go.Funnelarea -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Funnelarea` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Funnelarea` class from `plotly.graph_objects`](graph-objects.md). ```python from plotly import graph_objects as go @@ -204,7 +204,7 @@ fig.show() *New in 5.15* -Funnel area charts support [patterns](/python/pattern-hatching-texture/) (also known as hatching or texture) in addition to color. In this example, we add a pattern to the second stage of the funnel. +Funnel area charts support [patterns](pattern-hatching-texture.md) (also known as hatching or texture) in addition to color. In this example, we add a pattern to the second stage of the funnel. ```python from plotly import graph_objects as go diff --git a/doc/python/gantt.md b/doc/python/gantt.md index 33908bf139a..e2bd6c9ba57 100644 --- a/doc/python/gantt.md +++ b/doc/python/gantt.md @@ -39,11 +39,11 @@ A [Gantt chart](https://en.wikipedia.org/wiki/Gantt_chart) is a type of bar char ### Gantt Charts and Timelines with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.timeline` (*introduced in version 4.9*) each data point is represented as a horizontal bar with a start and end point specified as dates. +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.timeline` (*introduced in version 4.9*) each data point is represented as a horizontal bar with a start and end point specified as dates. -The `px.timeline` function by default sets the X-axis to be of `type=date`, so it can be configured like any [time-series chart](/python/time-series/). +The `px.timeline` function by default sets the X-axis to be of `type=date`, so it can be configured like any [time-series chart](time-series.md). -Plotly Express also supports a [general-purpose `px.bar` function for bar charts](/python/bar-charts/). +Plotly Express also supports a [general-purpose `px.bar` function for bar charts](bar-charts.md). ```python import plotly.express as px @@ -60,7 +60,7 @@ fig.update_yaxes(autorange="reversed") # otherwise tasks are listed from the bot fig.show() ``` -`px.timeline` supports [discrete color](/python/discrete-color/) as above, or [continuous color](/python/colorscales/) as follows. +`px.timeline` supports [discrete color](discrete-color.md) as above, or [continuous color](colorscales.md) as follows. ```python import plotly.express as px @@ -112,7 +112,7 @@ fig.show() #### Deprecated Figure Factory -Prior to the introduction of `plotly.express.timeline()` in version 4.9, the recommended way to make Gantt charts was to use the now-deprecated `create_gantt()` [figure factory](/python/figure-factories/), as follows: +Prior to the introduction of `plotly.express.timeline()` in version 4.9, the recommended way to make Gantt charts was to use the now-deprecated `create_gantt()` [figure factory](figure-factories.md), as follows: ```python import plotly.figure_factory as ff @@ -129,7 +129,7 @@ fig.show() #### Group Tasks Together -The following example shows how to use the now-deprecated `create_gantt()` [figure factory](/python/figure-factories/) to color tasks by a numeric variable. +The following example shows how to use the now-deprecated `create_gantt()` [figure factory](figure-factories.md) to color tasks by a numeric variable. ```python @@ -155,7 +155,7 @@ fig.show() #### Color by Numeric Variable -The following example shows how to use the now-deprecated `create_gantt()` [figure factory](/python/figure-factories/) to color tasks by a numeric variable. +The following example shows how to use the now-deprecated `create_gantt()` [figure factory](figure-factories.md) to color tasks by a numeric variable. ```python import plotly.figure_factory as ff diff --git a/doc/python/getting-started.md b/doc/python/getting-started.md index 6b4b1686e02..912dacf2837 100644 --- a/doc/python/getting-started.md +++ b/doc/python/getting-started.md @@ -46,8 +46,8 @@ Thanks to deep integration with our [Kaleido](https://github.com/plotly/Kaleido) This Getting Started guide explains how to install `plotly` and related optional pages. Once you've installed, you can use our documentation in three main ways: 1. You jump right in to **examples** of how to make [basic charts](/python/basic-charts/), [statistical charts](/python/statistical-charts/), [scientific charts](/python/scientific-charts/), [financial charts](/python/financial-charts/), [maps](/python/maps/), and [3-dimensional charts](/python/3d-charts/). -2. If you prefer to learn about the **fundamentals** of the library first, you can read about [the structure of figures](/python/figure-structure/), [how to create and update figures](/python/creating-and-updating-figures/), [how to display figures](/python/renderers/), [how to theme figures with templates](/python/templates/), [how to export figures to various formats](/python/static-image-export/) and about [Plotly Express, the high-level API](/python/plotly-express/) for doing all of the above. -3. You can check out our exhaustive **reference** guides: the [Python API reference](/python-api-reference) or the [Figure Reference](/python/reference) +2. If you prefer to learn about the **fundamentals** of the library first, you can read about [the structure of figures](figure-structure.md), [how to create and update figures](creating-and-updating-figures.md), [how to display figures](renderers.md), [how to theme figures with templates](templates.md), [how to export figures to various formats](static-image-export.md) and about [Plotly Express, the high-level API](plotly-express.md) for doing all of the above. +3. You can check out our exhaustive **reference** guides: the [Python API reference](/python-api-reference/) or the [Figure Reference](/reference/). For information on using Python to build web applications containing plotly figures, see the [_Dash User Guide_](https://dash.plotly.com/). @@ -73,7 +73,7 @@ If you want to use Plotly Express, install its required dependencies with: pip install plotly[express] ``` -You'll also need to install a [supported dataframe library](/python/px-arguments#supported-dataFrame-types). +You'll also need to install a [supported dataframe library](px-arguments.md#supported-dataFrame-types). ### Plotly charts in Dash @@ -131,9 +131,9 @@ fig_widget = go.FigureWidget(fig) fig_widget ``` -See [_Displaying Figures in Python_](/python/renderers/) for more information on the renderers framework, and see [_Plotly FigureWidget Overview_](/python/figurewidget/) for more information on using `FigureWidget`. +See [_Displaying Figures in Python_](renderers.md) for more information on the renderers framework, and see [_Plotly FigureWidget Overview_](figurewidget.md) for more information on using `FigureWidget`. -See the [Troubleshooting guide](/python/troubleshooting/) if you run into any problems with JupyterLab, particularly if you are using multiple Python environments inside Jupyter. +See the [Troubleshooting guide](troubleshooting.md) if you run into any problems with JupyterLab, particularly if you are using multiple Python environments inside Jupyter. #### Jupyter Notebook Support @@ -177,7 +177,7 @@ fig_widget = go.FigureWidget(fig) fig_widget ``` -See [_Displaying Figures in Python_](/python/renderers/) for more information on the renderers framework, and see [_Plotly FigureWidget Overview_](/python/figurewidget/) for more information on using `FigureWidget`. +See [_Displaying Figures in Python_](renderers.md) for more information on the renderers framework, and see [_Plotly FigureWidget Overview_](figurewidget.md) for more information on using `FigureWidget`. ### Static Image Export @@ -216,15 +216,15 @@ or conda. $ conda install -c plotly plotly-geo=1.0.0 ``` -See [_USA County Choropleth Maps in Python_](/python/county-choropleth/) for more information on the county choropleth figure factory. +See [_USA County Choropleth Maps in Python_](county-choropleth.md) for more information on the county choropleth figure factory. ### Where to next? Once you've installed, you can use our documentation in three main ways: 1. You jump right in to **examples** of how to make [basic charts](/python/basic-charts/), [statistical charts](/python/statistical-charts/), [scientific charts](/python/scientific-charts/), [financial charts](/python/financial-charts/), [maps](/python/maps/), and [3-dimensional charts](/python/3d-charts/). -2. If you prefer to learn about the **fundamentals** of the library first, you can read about [the structure of figures](/python/figure-structure/), [how to create and update figures](/python/creating-and-updating-figures/), [how to display figures](/python/renderers/), [how to theme figures with templates](/python/templates/), [how to export figures to various formats](/python/static-image-export/) and about [Plotly Express, the high-level API](/python/plotly-express/) for doing all of the above. -3. You can check out our exhaustive **reference** guides: the [Python API reference](/python-api-reference) or the [Figure Reference](/python/reference) +2. If you prefer to learn about the **fundamentals** of the library first, you can read about [the structure of figures](figure-structure.md), [how to create and update figures](creating-and-updating-figures.md), [how to display figures](renderers.md), [how to theme figures with templates](templates.md), [how to export figures to various formats](static-image-export.md) and about [Plotly Express, the high-level API](plotly-express.md) for doing all of the above. +3. You can check out our exhaustive **reference** guides: the [Python API reference](/python-api-reference/) or the [Figure Reference](/reference/). For information on using Python to build web applications containing plotly figures, see the [_Dash User Guide_](https://dash.plotly.com/). diff --git a/doc/python/graph-objects.md b/doc/python/graph-objects.md index 878b36d6bfc..30216114f9d 100644 --- a/doc/python/graph-objects.md +++ b/doc/python/graph-objects.md @@ -35,22 +35,22 @@ jupyter: ### What Are Graph Objects? -The figures created, manipulated and rendered by the plotly Python library are [represented by tree-like data structures](/python/figure-structure/) which are automatically serialized to JSON for rendering by the Plotly.js JavaScript library. These trees are composed of named nodes called "attributes", with their structure defined by the Plotly.js figure schema, which is available in [machine-readable form](https://raw.githubusercontent.com/plotly/plotly.js/master/dist/plot-schema.json). **The `plotly.graph_objects` module (typically imported as `go`) contains an [automatically-generated hierarchy of Python classes](https://plotly.com/python-api-reference/plotly.graph_objects.html#graph-objects) which represent non-leaf nodes in this figure schema. The term "graph objects" refers to instances of these classes. ** +The figures created, manipulated and rendered by the plotly Python library are [represented by tree-like data structures](figure-structure.md) which are automatically serialized to JSON for rendering by the Plotly.js JavaScript library. These trees are composed of named nodes called "attributes", with their structure defined by the Plotly.js figure schema, which is available in [machine-readable form](https://raw.githubusercontent.com/plotly/plotly.js/master/dist/plot-schema.json). **The `plotly.graph_objects` module (typically imported as `go`) contains an [automatically-generated hierarchy of Python classes](https://plotly.com/python-api-reference/plotly.graph_objects.html#graph-objects) which represent non-leaf nodes in this figure schema. The term "graph objects" refers to instances of these classes. ** -The primary classes defined in the `plotly.graph_objects` module are [`Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html) and an [`ipywidgets`-compatible variant called `FigureWidget`](/python/figurewidget/), which both represent entire figures. Instances of these classes have many convenience methods for Pythonically [manipulating their attributes](/python/creating-and-updating-figures/) (e.g. `.update_layout()` or `.add_trace()`, which all accept ["magic underscore" notation](/python/creating-and-updating-figures/#magic-underscore-notation)) as well as [rendering them](/python/renderers/) (e.g. `.show()`) and [exporting them to various formats](/python/static-image-export/) (e.g. `.to_json()` or `.write_image()` or `.write_html()`). +The primary classes defined in the `plotly.graph_objects` module are [`Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html) and an [`ipywidgets`-compatible variant called `FigureWidget`](figurewidget.md), which both represent entire figures. Instances of these classes have many convenience methods for Pythonically [manipulating their attributes](creating-and-updating-figures.md) (e.g. `.update_layout()` or `.add_trace()`, which all accept ["magic underscore" notation](creating-and-updating-figures.md#magic-underscore-notation)) as well as [rendering them](renderers.md) (e.g. `.show()`) and [exporting them to various formats](static-image-export.md) (e.g. `.to_json()` or `.write_image()` or `.write_html()`). -> Note: the functions in [Plotly Express](/python/plotly-express/), which is the recommended entry-point into the `plotly` library, are all built on top of graph objects, and all return instances of `plotly.graph_objects.Figure`. +> Note: the functions in [Plotly Express](plotly-express.md), which is the recommended entry-point into the `plotly` library, are all built on top of graph objects, and all return instances of `plotly.graph_objects.Figure`. -Every non-leaf attribute of a figure is represented by an instance of a class in the `plotly.graph_objects` hierarchy. For example, a figure `fig` can have an attribute `layout.margin`, which contains attributes `t`, `l`, `b` and `r` which are leaves of the tree: they have no children. The field at `fig.layout` is an object of class [`plotly.graph_objects.Layout`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Layout.html) and `fig.layout.margin` is an object of class `plotly.graph_objects.layout.Margin` which represents the `margin` node, and it has fields `t`, `l`, `b` and `r`, containing the values of the respective leaf-nodes. Note that specifying all of these values can be done without creating intermediate objects using ["magic underscore" notation](/python/creating-and-updating-figures/#magic-underscore-notation): `go.Figure(layout_margin=dict(t=10, b=10, r=10, l=10))`. +Every non-leaf attribute of a figure is represented by an instance of a class in the `plotly.graph_objects` hierarchy. For example, a figure `fig` can have an attribute `layout.margin`, which contains attributes `t`, `l`, `b` and `r` which are leaves of the tree: they have no children. The field at `fig.layout` is an object of class [`plotly.graph_objects.Layout`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Layout.html) and `fig.layout.margin` is an object of class `plotly.graph_objects.layout.Margin` which represents the `margin` node, and it has fields `t`, `l`, `b` and `r`, containing the values of the respective leaf-nodes. Note that specifying all of these values can be done without creating intermediate objects using ["magic underscore" notation](creating-and-updating-figures.md#magic-underscore-notation): `go.Figure(layout_margin=dict(t=10, b=10, r=10, l=10))`. -The objects contained in the list which is the [value of the attribute `data` are called "traces"](/python/figure-structure/), and can be of one of more than 40 possible types, each of which has a corresponding class in `plotly.graph_objects`. For example, traces of type `scatter` are represented by instances of the class `plotly.graph_objects.Scatter`. This means that a figure constructed as `go.Figure(data=[go.Scatter(x=[1,2], y=[3,4)])` will have the JSON representation `{"data": [{"type": "scatter", "x": [1,2], "y": [3,4]}]}`. +The objects contained in the list which is the [value of the attribute `data` are called "traces"](figure-structure.md), and can be of one of more than 40 possible types, each of which has a corresponding class in `plotly.graph_objects`. For example, traces of type `scatter` are represented by instances of the class `plotly.graph_objects.Scatter`. This means that a figure constructed as `go.Figure(data=[go.Scatter(x=[1,2], y=[3,4)])` will have the JSON representation `{"data": [{"type": "scatter", "x": [1,2], "y": [3,4]}]}`. ### Graph Objects Compared to Dictionaries Graph objects have several benefits compared to plain Python dictionaries: 1. Graph objects provide precise data validation. If you provide an invalid property name or an invalid property value as the key to a graph object, an exception will be raised with a helpful error message describing the problem. This is not the case if you use plain Python dictionaries and lists to build your figures. -2. Graph objects contain descriptions of each valid property as Python docstrings, with a [full API reference available](https://plotly.com/python-api-reference/). You can use these docstrings in the development environment of your choice to learn about the available properties as an alternative to consulting the online [Full Reference](/python/reference/index/). +2. Graph objects contain descriptions of each valid property as Python docstrings, with a [full API reference available](https://plotly.com/python-api-reference/). You can use these docstrings in the development environment of your choice to learn about the available properties as an alternative to consulting the online [Full Reference](/reference/). 3. Properties of graph objects can be accessed using both dictionary-style key lookup (e.g. `fig["layout"]`) or class-style property access (e.g. `fig.layout`). 4. Graph objects support higher-level convenience functions for making updates to already constructed figures (`.update_layout()`, `.add_trace()` etc). 5. Graph object constructors and update methods accept "magic underscores" (e.g. `go.Figure(layout_title_text="The Title")` rather than `dict(layout=dict(title=dict(text="The Title")))`) for more compact code. @@ -58,19 +58,19 @@ Graph objects have several benefits compared to plain Python dictionaries: ### When to use Graph Objects vs Plotly Express -The recommended way to create figures is using the [functions in the plotly.express module](https://plotly.com/python-api-reference/), [collectively known as Plotly Express](/python/plotly-express/), which all return instances of `plotly.graph_objects.Figure`, so every figure produced with the `plotly` library actually uses graph objects under the hood, unless manually constructed out of dictionaries. +The recommended way to create figures is using the [functions in the plotly.express module](https://plotly.com/python-api-reference/), [collectively known as Plotly Express](plotly-express.md), which all return instances of `plotly.graph_objects.Figure`, so every figure produced with the `plotly` library actually uses graph objects under the hood, unless manually constructed out of dictionaries. -That said, certain kinds of figures are not yet possible to create with Plotly Express, such as figures that use certain 3D trace-types like [`mesh`](/python/3d-mesh/) or [`isosurface`](/python/3d-isosurface-plots/). In addition, certain figures are cumbersome to create by starting from a figure created with Plotly Express, for example figures with [subplots of different types](/python/mixed-subplots/), [dual-axis plots](/python/multiple-axes/), or [faceted plots](/python/facet-plots/) with multiple different types of traces. To construct such figures, it can be easier to start from an empty `plotly.graph_objects.Figure` object (or one configured with subplots via the [make_subplots() function](/python/subplots/)) and progressively add traces and update attributes as above. Every `plotly` documentation page lists the Plotly Express option at the top if a Plotly Express function exists to make the kind of chart in question, and then the graph objects version below. +That said, certain kinds of figures are not yet possible to create with Plotly Express, such as figures that use certain 3D trace-types like [`mesh`](3d-mesh.md) or [`isosurface`](3d-isosurface-plots.md). In addition, certain figures are cumbersome to create by starting from a figure created with Plotly Express, for example figures with [subplots of different types](mixed-subplots.md), [dual-axis plots](multiple-axes.md), or [faceted plots](facet-plots.md) with multiple different types of traces. To construct such figures, it can be easier to start from an empty `plotly.graph_objects.Figure` object (or one configured with subplots via the [make_subplots() function](subplots.md)) and progressively add traces and update attributes as above. Every `plotly` documentation page lists the Plotly Express option at the top if a Plotly Express function exists to make the kind of chart in question, and then the graph objects version below. -Note that the figures produced by Plotly Express **in a single function-call** are [easy to customize at creation-time](/python/styling-plotly-express/), and to [manipulate after creation](/python/creating-and-updating-figures/) using the `update_*` and `add_*` methods. +Note that the figures produced by Plotly Express **in a single function-call** are [easy to customize at creation-time](styling-plotly-express.md), and to [manipulate after creation](creating-and-updating-figures.md) using the `update_*` and `add_*` methods. ### Comparing Graph Objects and Plotly Express The figures produced by Plotly Express can always be built from the ground up using graph objects, but this approach typically takes **5-100 lines of code rather than 1**. -Here is a simple example of how to produce the same figure object from the same data, once with Plotly Express and once without. Note that [Plotly Express functions](/python-api-reference/plotly.express.html) like [`px.bar()`](/python/bar-charts/) can accept a DataFrame as their first argument with column names passed to the `x` and `y` arguments, while [Graph Objects functions](/python-api-reference/plotly.graph_objects.html) like [`go.Bar()`](/python/bar-charts/#basic-bar-charts-with-plotlygraphobjects) require the data values to be passed directly to the `x` and `y` arguments as a tuple, list, NumPy array, or Pandas Series. +Here is a simple example of how to produce the same figure object from the same data, once with Plotly Express and once without. Note that [Plotly Express functions](/python-api-reference/plotly.express.html) like [`px.bar()`](bar-charts.md) can accept a DataFrame as their first argument with column names passed to the `x` and `y` arguments, while [Graph Objects functions](/python-api-reference/plotly.graph_objects.html) like [`go.Bar()`](bar-charts.md#basic-bar-charts-with-plotlygraphobjects) require the data values to be passed directly to the `x` and `y` arguments as a tuple, list, NumPy array, or Pandas Series. -The data in this example is in "long form" but [Plotly Express also accepts data in "wide form"](/python/wide-form/) and the line-count savings from Plotly Express over graph objects are comparable. More complex figures such as [sunbursts](/python/sunburst-charts/), [parallel coordinates](/python/parallel-coordinates-plot/), [facet plots](/python/facet-plots/) or [animations](/python/animations/) require many more lines of figure-specific graph objects code, whereas switching from one representation to another with Plotly Express usually involves changing just a few characters. +The data in this example is in "long form" but [Plotly Express also accepts data in "wide form"](wide-form.md) and the line-count savings from Plotly Express over graph objects are comparable. More complex figures such as [sunbursts](sunburst-charts.md), [parallel coordinates](parallel-coordinates-plot.md), [facet plots](facet-plots.md) or [animations](animations.md) require many more lines of figure-specific graph objects code, whereas switching from one representation to another with Plotly Express usually involves changing just a few characters. ```python import pandas as pd diff --git a/doc/python/graphing-multiple-chart-types.md b/doc/python/graphing-multiple-chart-types.md index 371776a5613..bb0ca9881d6 100644 --- a/doc/python/graphing-multiple-chart-types.md +++ b/doc/python/graphing-multiple-chart-types.md @@ -35,16 +35,16 @@ jupyter: ### Chart Types versus Trace Types -Plotly's [figure data structure](/python/figure-structure/) supports defining [subplots](/python/subplots/) of [various types](/python/mixed-subplots/) (e.g. [cartesian](/python/axes/), [polar](/python/polar-chart/), [3-dimensional](/python/3d-charts/), [maps](/python/maps/) etc) with attached traces of [various compatible types](/python/figure-structure/) (e.g. scatter, bar, choropleth, surface etc). This means that **Plotly figures are not constrained to representing a fixed set of "chart types"** such as scatter plots only or bar charts only or line charts only: any subplot can contain multiple traces of different types. +Plotly's [figure data structure](figure-structure.md) supports defining [subplots](subplots.md) of [various types](mixed-subplots.md) (e.g. [cartesian](axes.md), [polar](polar-chart.md), [3-dimensional](/3d-charts/), [maps](/maps/) etc) with attached traces of [various compatible types](figure-structure.md) (e.g. scatter, bar, choropleth, surface etc). This means that **Plotly figures are not constrained to representing a fixed set of "chart types"** such as scatter plots only or bar charts only or line charts only: any subplot can contain multiple traces of different types. ### Multiple Trace Types with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). -Plotly Express exposes a number of functions such as `px.scatter()` and `px.choropleth()` which generally speaking only contain traces of the same type, with exceptions made for [trendlines](/python/linear-fits/) and [marginal distribution plots](/python/marginal-plots/). +Plotly Express exposes a number of functions such as `px.scatter()` and `px.choropleth()` which generally speaking only contain traces of the same type, with exceptions made for [trendlines](linear-fits.md) and [marginal distribution plots](marginal-plots.md). -Figures produced with Plotly Express functions support the `add_trace()` method documented below, just like figures created with [graph objects](/python/graph-objects/) so it is easy to start with a Plotly Express figure containing only traces of a given type, and add traces of another type. +Figures produced with Plotly Express functions support the `add_trace()` method documented below, just like figures created with [graph objects](graph-objects.md) so it is easy to start with a Plotly Express figure containing only traces of a given type, and add traces of another type. ```python import plotly.express as px diff --git a/doc/python/heatmaps.md b/doc/python/heatmaps.md index c4d74f4e3a8..e323037876c 100644 --- a/doc/python/heatmaps.md +++ b/doc/python/heatmaps.md @@ -34,24 +34,24 @@ jupyter: thumbnail: thumbnail/heatmap.jpg --- -The term "heatmap" usually refers to a Cartesian plot with data visualized as colored rectangular tiles, which is the subject of this page. It is also sometimes used to refer to [actual maps with density data displayed as color intensity](/python/tile-density-heatmaps/). +The term "heatmap" usually refers to a Cartesian plot with data visualized as colored rectangular tiles, which is the subject of this page. It is also sometimes used to refer to [actual maps with density data displayed as color intensity](tile-density-heatmaps.md). Plotly supports two different types of colored-tile heatmaps: 1. **Matrix Heatmaps** accept a 2-dimensional matrix or array of data and visualizes it directly. This type of heatmap is the subject of this page. -2. **Density Heatmaps** accept data as a list and visualizes aggregated quantities like counts or sums of this data. Please refer to the [2D Histogram documentation](/python/2D-Histogram/) for this kind of figure. +2. **Density Heatmaps** accept data as a list and visualizes aggregated quantities like counts or sums of this data. Please refer to the [2D Histogram documentation](2D-Histogram.md) for this kind of figure. ### Heatmaps with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.imshow`, each value of the input array or data frame is represented as a heatmap pixel. +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.imshow`, each value of the input array or data frame is represented as a heatmap pixel. -The `px.imshow()` function can be used to display heatmaps (as well as full-color images, as its name suggests). It accepts both array-like objects like lists of lists and `numpy` or `xarray` arrays, as well as supported [DataFrame objects](/python/px-arguments#supported-dataframes). +The `px.imshow()` function can be used to display heatmaps (as well as full-color images, as its name suggests). It accepts both array-like objects like lists of lists and `numpy` or `xarray` arrays, as well as supported [DataFrame objects](px-arguments.md#supported-dataframes). -> For more examples using `px.imshow`, including examples of faceting and animations, as well as full-color image display, see the [the `imshow` documentation page](/python/imshow). +> For more examples using `px.imshow`, including examples of faceting and animations, as well as full-color image display, see the [the `imshow` documentation page](imshow.md). ```python @@ -158,7 +158,7 @@ fig.show() ### Basic Heatmap with `plotly.graph_objects` -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Heatmap` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Heatmap` class from `plotly.graph_objects`](graph-objects.md). ```python import plotly.graph_objects as go @@ -290,7 +290,7 @@ fig.show() ### Heatmap and datashader Arrays of rasterized values build by datashader can be visualized using -plotly's heatmaps, as shown in the [plotly and datashader tutorial](/python/datashader/). +plotly's heatmaps, as shown in the [plotly and datashader tutorial](datashader.md). #### Reference See [function reference for `px.(imshow)`](https://plotly.com/python-api-reference/generated/plotly.express.imshow) or https://plotly.com/python/reference/heatmap/ for more information and chart attribute options! diff --git a/doc/python/hexbin-mapbox.md b/doc/python/hexbin-mapbox.md index ed30f329774..04a680b910d 100644 --- a/doc/python/hexbin-mapbox.md +++ b/doc/python/hexbin-mapbox.md @@ -35,9 +35,9 @@ jupyter: #### Simple Count Hexbin -This page details the use of a [figure factory](/python/figure-factories/). For more examples with Choropleth maps, see [this page](/python/choropleth-maps/). +This page details the use of a [figure factory](figure-factories.md). For more examples with Choropleth maps, see [this page](choropleth-maps.md). -In order to use mapbox styles that require a mapbox token, set the token with `plotly.express`. You can also use styles that do not require a mapbox token. See more information on [this page](/python/mapbox-layers/). +In order to use mapbox styles that require a mapbox token, set the token with `plotly.express`. You can also use styles that do not require a mapbox token. See more information on [this page](mapbox-layers.md). ```python import plotly.figure_factory as ff diff --git a/doc/python/histograms.md b/doc/python/histograms.md index aca2c25b3d5..8100ce8567f 100644 --- a/doc/python/histograms.md +++ b/doc/python/histograms.md @@ -43,11 +43,11 @@ In statistics, a [histogram](https://en.wikipedia.org/wiki/Histogram) is represe Alternatives to histogram plots for visualizing distributions include [violin plots](https://plotly.com/python/violin/), [box plots](https://plotly.com/python/box-plots/), [ECDF plots](https://plotly.com/python/ecdf-plots/) and [strip charts](https://plotly.com/python/strip-charts/). > If you're looking instead for bar charts, i.e. representing *raw, unaggregated* data with rectangular -bar, go to the [Bar Chart tutorial](/python/bar-charts/). +bar, go to the [Bar Chart tutorial](bar-charts.md). ## Histograms with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python @@ -190,7 +190,7 @@ fig.show() ``` *New in v5.0* -Histograms afford the use of [patterns (also known as hatching or texture)](/python/pattern-hatching-texture/) in addition to color: +Histograms afford the use of [patterns (also known as hatching or texture)](pattern-hatching-texture.md) in addition to color: ```python import plotly.express as px @@ -227,7 +227,7 @@ fig.show() ## Histograms with go.Histogram -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Histogram` class from `plotly.graph_objects`](/python/graph-objects/). All of the available histogram options are described in the histogram section of the reference page: https://plotly.com/python/reference#histogram. +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Histogram` class from `plotly.graph_objects`](graph-objects.md). All of the available histogram options are described in the histogram section of the reference page: https://plotly.com/python/reference#histogram. ### Basic Histogram @@ -450,7 +450,7 @@ fig.show() ### See also: Bar Charts -If you want to display information about the individual items within each histogram bar, then create a stacked bar chart with hover information as shown below. Note that this is not technically the histogram chart type, but it will have a similar effect as shown below by comparing the output of `px.histogram` and `px.bar`. For more information, see the [tutorial on bar charts](/python/bar-charts/). +If you want to display information about the individual items within each histogram bar, then create a stacked bar chart with hover information as shown below. Note that this is not technically the histogram chart type, but it will have a similar effect as shown below by comparing the output of `px.histogram` and `px.bar`. For more information, see the [tutorial on bar charts](bar-charts.md). ```python import plotly.express as px diff --git a/doc/python/horizontal-bar-charts.md b/doc/python/horizontal-bar-charts.md index 60a6a286865..072d09cd205 100644 --- a/doc/python/horizontal-bar-charts.md +++ b/doc/python/horizontal-bar-charts.md @@ -37,7 +37,7 @@ See more examples of bar charts (including vertical bar charts) and styling opti ### Horizontal Bar Chart with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). For a horizontal bar char, use the `px.bar` function with `orientation='h'`. +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). For a horizontal bar char, use the `px.bar` function with `orientation='h'`. #### Basic Horizontal Bar Chart with Plotly Express @@ -64,7 +64,7 @@ fig.show() ### Horizontal Bar Chart with go.Bar -You can also use [the more generic `go.Bar` class from `plotly.graph_objects`](/python/graph-objects/). All the options of `go.Bar` are documented in the reference https://plotly.com/python/reference/bar/ +You can also use [the more generic `go.Bar` class from `plotly.graph_objects`](graph-objects.md). All the options of `go.Bar` are documented in the reference https://plotly.com/python/reference/bar/ #### Basic Horizontal Bar Chart diff --git a/doc/python/horizontal-vertical-shapes.md b/doc/python/horizontal-vertical-shapes.md index 02ec8417230..e5ac64ae269 100644 --- a/doc/python/horizontal-vertical-shapes.md +++ b/doc/python/horizontal-vertical-shapes.md @@ -39,7 +39,7 @@ jupyter: Horizontal and vertical lines and rectangles that span an entire plot can be added via the `add_hline`, `add_vline`, `add_hrect`, and `add_vrect` methods of `plotly.graph_objects.Figure`. Shapes added with these methods are -added as [layout shapes](/python/shapes) (as shown when doing `print(fig)`, for +added as [layout shapes](shapes.md) (as shown when doing `print(fig)`, for example). These shapes are fixed to the endpoints of one axis, regardless of the range of the plot, and fixed to data coordinates on the other axis. The following shows some possibilities, try panning and zooming the resulting figure @@ -86,7 +86,7 @@ IFrame(snippet_url + 'horizontal-vertical-shapes', width='100%', height=1200) #### Adding Text Annotations -[Text annotations](/python/text-and-annotations) can optionally be added to an autoshape +[Text annotations](../text-and-annotations) can optionally be added to an autoshape using the `annotation_text` keyword argument, and positioned using the `annotation_position` argument: ```python @@ -125,7 +125,7 @@ fig.show() #### Adding to Multiple Facets / Subplots -The same line or box can be added to multiple [subplots](/python/subplots/) or [facets](/python/facet-plots/) by setting the `row` and/or `col` to `"all"`. The default `row` and `col` values are `"all"`. +The same line or box can be added to multiple [subplots](subplots.md) or [facets](facet-plots.md) by setting the `row` and/or `col` to `"all"`. The default `row` and `col` values are `"all"`. ```python import plotly.express as px @@ -143,7 +143,7 @@ fig.show() *New in 5.14* -[Text labels on shapes](/python/shapes/#addingtextlabelstoshapes), introduced in version 5.14, is now the recommended way to add text to shapes. The above examples using `add_hline`, `add_vrect`, `add_hrect`, and `add_vline` that add annotations can be rewritten to use `label`. +[Text labels on shapes](shapes.md#addingtextlabelstoshapes), introduced in version 5.14, is now the recommended way to add text to shapes. The above examples using `add_hline`, `add_vrect`, `add_hrect`, and `add_vline` that add annotations can be rewritten to use `label`. ```python import plotly.express as px @@ -176,11 +176,11 @@ fig.show() ``` -With [text labels on shapes](/python/shapes/#adding-text-labels-to-shapes), you can also add text labels to shapes other than lines and rectangles, and the labels can be added automatically to shapes drawn by the user. +With [text labels on shapes](shapes.md#adding-text-labels-to-shapes), you can also add text labels to shapes other than lines and rectangles, and the labels can be added automatically to shapes drawn by the user. ### Reference -More details are available about [layout shapes](/python/shapes/) and [annotations](/python/text-and-annotations). +More details are available about [layout shapes](shapes.md) and [annotations](text-and-annotations.md). Reference documentation is also available for [`add_hline`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html?highlight=add_hline#plotly.graph_objects.Figure.add_hline), [`add_vline`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html?highlight=add_vline#plotly.graph_objects.Figure.add_vline), [`add_hrect`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html?highlight=add_hrect#plotly.graph_objects.Figure.add_hrect), [`add_vrect`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html?highlight=add_vrect#plotly.graph_objects.Figure.add_vrect). diff --git a/doc/python/hover-text-and-formatting.md b/doc/python/hover-text-and-formatting.md index cdbc4058daf..edc1d4da8a3 100644 --- a/doc/python/hover-text-and-formatting.md +++ b/doc/python/hover-text-and-formatting.md @@ -154,7 +154,7 @@ IFrame(snippet_url + 'hover-text-and-formatting', width='100%', height=1200) #### Selecting a hovermode in a figure created with `plotly.graph_objects` -The hovermode is a property of the figure layout, so you can select a hovermode no matter how you created the figure, either with `plotly.express` or with `plotly.graph_objects`. Below is an example with a figure created with `plotly.graph_objects`. If you're not familiar with the structure of plotly figures, you can read [the tutorial on creating and updating plotly figures](/python/creating-and-updating-figures/). +The hovermode is a property of the figure layout, so you can select a hovermode no matter how you created the figure, either with `plotly.express` or with `plotly.graph_objects`. Below is an example with a figure created with `plotly.graph_objects`. If you're not familiar with the structure of plotly figures, you can read [the tutorial on creating and updating plotly figures](creating-and-updating-figures.md). ```python import plotly.graph_objects as go diff --git a/doc/python/icicle-charts.md b/doc/python/icicle-charts.md index 38569a7ea03..e9cecacc32c 100644 --- a/doc/python/icicle-charts.md +++ b/doc/python/icicle-charts.md @@ -39,7 +39,7 @@ Icicle charts visualize hierarchical data using rectangular sectors that cascade ### Basic Icicle Plot with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.icicle`, each item in the `character` list is represented as a rectangular sector of the icicle. @@ -155,7 +155,7 @@ fig.show() ### Basic Icicle Plot with go.Icicle -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Icicle` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Icicle` class from `plotly.graph_objects`](graph-objects.md). Main arguments: @@ -423,7 +423,7 @@ fig.show() *New in 5.15* -Icicle charts support [patterns](/python/pattern-hatching-texture/) (also known as hatching or texture) in addition to color. In this example, we apply a pattern to all chart sections. We also configure the `size` and `solidity` of the pattern. +Icicle charts support [patterns](pattern-hatching-texture.md) (also known as hatching or texture) in addition to color. In this example, we apply a pattern to all chart sections. We also configure the `size` and `solidity` of the pattern. ```python import plotly.graph_objects as go diff --git a/doc/python/images.md b/doc/python/images.md index d69aa91c883..627e4b3a915 100644 --- a/doc/python/images.md +++ b/doc/python/images.md @@ -35,7 +35,7 @@ jupyter: #### Add a Background Image -In this page we explain how to add static, non-interactive images as background, logo or annotation images to a figure. For exploring image data in interactive charts, see the [tutorial on displaying image data](/python/imshow). +In this page we explain how to add static, non-interactive images as background, logo or annotation images to a figure. For exploring image data in interactive charts, see the [tutorial on displaying image data](imshow.md). A background image can be added to the layout of a figure with `fig.add_layout_image` or by setting the `images` parameter of `go.Layout`. The @@ -313,9 +313,9 @@ It can be useful to add shapes to a layout image, for highlighting an object, dr In order to enable shape drawing, you need to - define a dragmode corresponding to a drawing tool (`'drawline'`,`'drawopenpath'`, `'drawclosedpath'`, `'drawcircle'`, or `'drawrect'`) -- add [modebar buttons](/python/configuration-options#add-optional-shapedrawing-buttons-to-modebar) corresponding to the drawing tools you wish to use. +- add [modebar buttons](configuration-options.md#add-optional-shapedrawing-buttons-to-modebar) corresponding to the drawing tools you wish to use. -The style of new shapes is specified by the `newshape` layout attribute. Shapes can be selected and modified after they have been drawn. More details and examples are given in the [tutorial on shapes](/python/shapes#drawing-shapes-on-cartesian-plots). +The style of new shapes is specified by the `newshape` layout attribute. Shapes can be selected and modified after they have been drawn. More details and examples are given in the [tutorial on shapes](shapes.md#drawing-shapes-on-cartesian-plots). Drawing or modifying a shape triggers a `relayout` event, which [can be captured by a callback inside a Dash application](https://dash.plotly.com/interactive-graphing). diff --git a/doc/python/imshow.md b/doc/python/imshow.md index 08be73e2985..b895d2b4922 100644 --- a/doc/python/imshow.md +++ b/doc/python/imshow.md @@ -38,7 +38,7 @@ jupyter: This tutorial shows how to display and explore image data. If you would like instead a logo or static image, use `go.layout.Image` as explained -[here](/python/images). +[here](images.md). ### Displaying RGB image data with px.imshow @@ -61,7 +61,13 @@ In order to create a numerical array to be passed to `px.imshow`, you can use a ```python import plotly.express as px from skimage import io -img = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg') +from io import BytesIO +import requests + +url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg' +headers = {"User-Agent": "Mozilla/5.0"} +response = requests.get(url, headers=headers) +img = io.imread(BytesIO(response.content)) fig = px.imshow(img) fig.show() ``` @@ -76,7 +82,7 @@ fig.show() ### Display single-channel 2D data as a heatmap -For a 2D image, `px.imshow` uses a colorscale to map scalar data to colors. The default colorscale is the one of the active template (see [the tutorial on templates](/python/templates/)). +For a 2D image, `px.imshow` uses a colorscale to map scalar data to colors. The default colorscale is the one of the active template (see [the tutorial on templates](templates.md)). ```python import plotly.express as px @@ -88,7 +94,7 @@ fig.show() ### Choose the colorscale to display a single-channel image -You can customize the [continuous color scale](/python/colorscales/) just like with any other Plotly Express function. However, `color_continuous_scale` is ignored when using `binary_string=True`, since the image is always represented as grayscale (and no colorbar is displayed). +You can customize the [continuous color scale](colorscales.md) just like with any other Plotly Express function. However, `color_continuous_scale` is ignored when using `binary_string=True`, since the image is always represented as grayscale (and no colorbar is displayed). ```python import plotly.express as px @@ -110,7 +116,7 @@ fig.show() ### Hiding the colorbar and axis labels -See the [continuous color](/python/colorscales/) and [cartesian axes](/python/axes/) pages for more details. +See the [continuous color](colorscales.md) and [cartesian axes](axes.md) pages for more details. ```python import plotly.express as px @@ -167,9 +173,9 @@ fig.show() ### Display multichannel image data with go.Image -It is also possible to use the `go.Image` trace from the low-level `graph_objects` API in order to display image data. Note that `go.Image` only accepts multichannel images. For single-channel images, use [`go.Heatmap`](/python/heatmaps). +It is also possible to use the `go.Image` trace from the low-level `graph_objects` API in order to display image data. Note that `go.Image` only accepts multichannel images. For single-channel images, use [`go.Heatmap`](heatmaps.md). -Note that the `go.Image` trace is different from the `go.layout.Image` class, which can be used for [adding background images or logos to figures](/python/images). +Note that the `go.Image` trace is different from the `go.layout.Image` class, which can be used for [adding background images or logos to figures](images.md). ```python import plotly.graph_objects as go @@ -239,6 +245,7 @@ These two modes can be used for single- and multichannel data. The default value ```python import plotly.express as px +import numpy as np img = np.arange(100, dtype=np.uint8).reshape((10, 10)) fig = px.imshow(img, contrast_rescaling='infer') fig.show() @@ -291,7 +298,7 @@ fig.show() ### imshow and datashader Arrays of rasterized values build by datashader can be visualized using -imshow. See the [plotly and datashader tutorial](/python/datashader/) for +imshow. See the [plotly and datashader tutorial](datashader.md) for examples on how to use plotly and datashader. @@ -305,7 +312,7 @@ In order to enable shape drawing, you need to - define a dragmode corresponding to a drawing tool (`'drawline'`,`'drawopenpath'`, `'drawclosedpath'`, `'drawcircle'`, or `'drawrect'`) - add modebar buttons corresponding to the drawing tools you wish to use. -The style of new shapes is specified by the `newshape` layout attribute. Shapes can be selected and modified after they have been drawn. More details and examples are given in the [tutorial on shapes](/python/shapes#drawing-shapes-on-cartesian-plots). +The style of new shapes is specified by the `newshape` layout attribute. Shapes can be selected and modified after they have been drawn. More details and examples are given in the [tutorial on shapes](shapes.md#drawing-shapes-on-cartesian-plots). Drawing or modifying a shape triggers a `relayout` event, which [can be captured by a callback inside a Dash application](https://dash.plotly.com/interactive-graphing). @@ -408,7 +415,7 @@ For three-dimensional image datasets, obtained for example by MRI or CT in medic It is recommended to use `binary_string=True` for facetted plots of images in order to keep a small figure size and a short rendering time. -See the [tutorial on facet plots](/python/facet-plots/) for more information on creating and styling facet plots. +See the [tutorial on facet plots](facet-plots.md) for more information on creating and styling facet plots. ```python import plotly.express as px diff --git a/doc/python/interactive-html-export.md b/doc/python/interactive-html-export.md index 461afe7f548..9ebfdeda6a2 100644 --- a/doc/python/interactive-html-export.md +++ b/doc/python/interactive-html-export.md @@ -36,7 +36,7 @@ jupyter: ### Interactive vs Static Export -Plotly figures are interactive when viewed in a web browser: you can hover over data points, pan and zoom axes, and show and hide traces by clicking or double-clicking on the legend. You can export figures either to [static image file formats like PNG, JPEG, SVG or PDF](/python/static-image-export/) or you can export them to HTML files which can be opened in a browser. This page explains how to do the latter. +Plotly figures are interactive when viewed in a web browser: you can hover over data points, pan and zoom axes, and show and hide traces by clicking or double-clicking on the legend. You can export figures either to [static image file formats like PNG, JPEG, SVG or PDF](static-image-export.md) or you can export them to HTML files which can be opened in a browser. This page explains how to do the latter. ### Saving to an HTML file diff --git a/doc/python/legend.md b/doc/python/legend.md index 6fc879fbc9c..695854702aa 100644 --- a/doc/python/legend.md +++ b/doc/python/legend.md @@ -35,18 +35,18 @@ jupyter: ### Trace Types, Legends and Color Bars -[Traces](/python/figure-structure) of most types and shapes can be optionally associated with a single legend item in the [legend](/python/legend/). Whether or not a given trace or shape appears in the legend is controlled via the `showlegend` attribute. Traces which are their own subplots (see above) do not support this, with the exception of traces of type `pie` and `funnelarea` for which every distinct color represented in the trace gets a separate legend item. Users may show or hide traces by clicking or double-clicking on their associated legend item. Traces that support legend items and shapes also support the `legendgroup` attribute, and all traces and shapes with the same legend group are treated the same way during click/double-click interactions. +[Traces](figure-structure.md) of most types and shapes can be optionally associated with a single legend item in the [legend](legend.md). Whether or not a given trace or shape appears in the legend is controlled via the `showlegend` attribute. Traces which are their own subplots (see above) do not support this, with the exception of traces of type `pie` and `funnelarea` for which every distinct color represented in the trace gets a separate legend item. Users may show or hide traces by clicking or double-clicking on their associated legend item. Traces that support legend items and shapes also support the `legendgroup` attribute, and all traces and shapes with the same legend group are treated the same way during click/double-click interactions. -The fact that legend items are linked to traces means that when using [discrete color](/python/discrete-color/), a figure must have one trace per color in order to get a meaningful legend. [Plotly Express has robust support for discrete color](/python/discrete-color/) to make this easy. +The fact that legend items are linked to traces means that when using [discrete color](discrete-color.md), a figure must have one trace per color in order to get a meaningful legend. [Plotly Express has robust support for discrete color](discrete-color.md) to make this easy. -Traces which support [continuous color](/python/colorscales/) can also be associated with color axes in the layout via the `coloraxis` attribute. Multiple traces can be linked to the same color axis. Color axes have a legend-like component called color bars. Alternatively, color axes can be configured within the trace itself. +Traces which support [continuous color](colorscales.md) can also be associated with color axes in the layout via the `coloraxis` attribute. Multiple traces can be linked to the same color axis. Color axes have a legend-like component called color bars. Alternatively, color axes can be configured within the trace itself. ### Legends with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). -Plotly Express functions will create one [trace](/python/figure-structure) per animation frame for each unique combination of data values mapped to discrete color, symbol, line-dash, facet-row and/or facet-column. Traces' `legendgroup` and `showlegend` attributed are set such that only one legend item appears per unique combination of discrete color, symbol and/or line-dash. The legend title is automatically set, and can be overrided with the `labels` keyword argument: +Plotly Express functions will create one [trace](figure-structure.md) per animation frame for each unique combination of data values mapped to discrete color, symbol, line-dash, facet-row and/or facet-column. Traces' `legendgroup` and `showlegend` attributed are set such that only one legend item appears per unique combination of discrete color, symbol and/or line-dash. The legend title is automatically set, and can be overrided with the `labels` keyword argument: ```python import plotly.express as px @@ -59,7 +59,7 @@ fig.show() ### Legend Order -By default, Plotly Express lays out legend items in the order in which values appear in the underlying data. Every Plotly Express function also includes a `category_orders` keyword argument which can be used to control [the order in which categorical axes are drawn](/python/categorical-axes/), but beyond that can also control the order in which legend items appear, and [the order in which facets are laid out](/python/facet-plots/). +By default, Plotly Express lays out legend items in the order in which values appear in the underlying data. Every Plotly Express function also includes a `category_orders` keyword argument which can be used to control [the order in which categorical axes are drawn](categorical-axes.md), but beyond that can also control the order in which legend items appear, and [the order in which facets are laid out](facet-plots.md). ```python import plotly.express as px @@ -84,7 +84,7 @@ fig.update_layout(legend_traceorder="reversed") fig.show() ``` -When using [`plotly.graph_objects`](/python/graph-objects/) rather than Plotly Express, legend items will appear in the order that traces appear in the `data`: +When using [`plotly.graph_objects`](graph-objects.md) rather than Plotly Express, legend items will appear in the order that traces appear in the `data`: ```python import plotly.graph_objects as go @@ -171,7 +171,7 @@ fig.show() ### Legend Positioning -Legends have an anchor point, which can be set to a point within the legend using `layout.legend.xanchor` and `layout.legend.yanchor`. The coordinate of the anchor can be positioned with `layout.legend.x` and `layout.legend.y` in [paper coordinates](/python/figure-structure/). Note that the plot margins will grow so as to accommodate the legend. The legend may also be placed within the plotting area. +Legends have an anchor point, which can be set to a point within the legend using `layout.legend.xanchor` and `layout.legend.yanchor`. The coordinate of the anchor can be positioned with `layout.legend.x` and `layout.legend.y` in [paper coordinates](figure-structure.md). Note that the plot margins will grow so as to accommodate the legend. The legend may also be placed within the plotting area. ```python import plotly.express as px @@ -328,7 +328,7 @@ fig.show() ### Legends with Graph Objects -When creating figures using [graph objects](/python/graph-objects/) without using [Plotly Express](/python/plotly-express/), legends must be manually configured using some of the options below. +When creating figures using [graph objects](graph-objects.md) without using [Plotly Express](plotly-express.md), legends must be manually configured using some of the options below. #### Legend Item Names diff --git a/doc/python/line-and-scatter.md b/doc/python/line-and-scatter.md index 51291cfaa5b..01bf019dfdd 100644 --- a/doc/python/line-and-scatter.md +++ b/doc/python/line-and-scatter.md @@ -36,7 +36,7 @@ jupyter: ## Scatter plots with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.scatter`, each data point is represented as a marker point, whose location is given by the `x` and `y` columns. @@ -424,7 +424,7 @@ fig.show() ## Scatter and line plots with go.Scatter -If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](/python/graph-objects/). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/). +If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](graph-objects.md). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/). #### Simple Scatter Plot diff --git a/doc/python/line-charts.md b/doc/python/line-charts.md index 840abdfa76c..dd82a6b57d3 100644 --- a/doc/python/line-charts.md +++ b/doc/python/line-charts.md @@ -36,7 +36,7 @@ jupyter: ### Line Plots with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.line`, each data point is represented as a vertex (which location is given by the `x` and `y` columns) of a **polyline mark** in 2D space. +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.line`, each data point is represented as a vertex (which location is given by the `x` and `y` columns) of a **polyline mark** in 2D space. For more examples of line plots, see the [line and scatter notebook](https://plotly.com/python/line-and-scatter/). @@ -174,7 +174,7 @@ fig.show(config=dict(displayModeBar=False)) ### Line Plot with go.Scatter -If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](/python/graph-objects/). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/). +If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](graph-objects.md). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/). #### Simple Line Plot diff --git a/doc/python/linear-fits.md b/doc/python/linear-fits.md index 0029be6c4be..8a673de1e6a 100644 --- a/doc/python/linear-fits.md +++ b/doc/python/linear-fits.md @@ -38,7 +38,7 @@ jupyter: ### Linear fit trendlines with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). Plotly Express allows you to add [Ordinary Least Squares](https://en.wikipedia.org/wiki/Ordinary_least_squares) regression trendline to scatterplots with the `trendline` argument. In order to do so, you will need to [install `statsmodels` and its dependencies](https://www.statsmodels.org/stable/install.html). Hovering over the trendline will show the equation of the line and its R-squared value. diff --git a/doc/python/lines-on-maps.md b/doc/python/lines-on-maps.md index 000ec1d0258..e816bdfceed 100644 --- a/doc/python/lines-on-maps.md +++ b/doc/python/lines-on-maps.md @@ -37,11 +37,11 @@ Below we show how to create geographical line plots using either Plotly Express #### Base Map Configuration -Plotly figures made with [Plotly Express](/python/plotly-express/) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](/python/graph-objects/) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](/python/map-configuration/) onto which data is plotted. +Plotly figures made with [Plotly Express](plotly-express.md) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](graph-objects.md) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](map-configuration.md) onto which data is plotted. ## Lines on Maps with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px diff --git a/doc/python/lines-on-tile-maps.md b/doc/python/lines-on-tile-maps.md index 47e1c57d1e5..efff0062d0e 100644 --- a/doc/python/lines-on-tile-maps.md +++ b/doc/python/lines-on-tile-maps.md @@ -133,7 +133,7 @@ fig.show() The earlier examples using `px.line_map` and `go.Scattermap` use [Maplibre](https://maplibre.org/maplibre-gl-js/docs/) for rendering. These traces were introduced in Plotly.py 5.24 and are now the recommended way to draw lines on tile-based maps. There are also traces that use [Mapbox](https://docs.mapbox.com): `px.line_mapbox` and `go.Scattermapbox` -To plot on Mapbox maps with Plotly you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](/python/mapbox-layers/) documentation for more information. +To plot on Mapbox maps with Plotly you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](mapbox-layers.md) documentation for more information. To draw a line on your map, you either can use [`px.line_mapbox`](https://plotly.com/python-api-reference/generated/plotly.express.line_mapbox.html) in Plotly Express, or [`Scattermapbox`](https://plotly.com/python/reference/scattermapbox/) traces. Below we show you how to draw a line on Mapbox using Plotly Express. diff --git a/doc/python/log-plot.md b/doc/python/log-plot.md index edce8eeb09b..60fb716824a 100644 --- a/doc/python/log-plot.md +++ b/doc/python/log-plot.md @@ -33,11 +33,11 @@ jupyter: thumbnail: thumbnail/log.jpg --- -This page shows examples of how to configure [2-dimensional Cartesian axes](/python/figure-structure/#2d-cartesian-trace-types-and-subplots) to follow a logarithmic rather than linear progression. [Configuring gridlines, ticks, tick labels and axis titles](/python/axes/) on logarithmic axes is done the same was as with [linear axes](/python/axes/). +This page shows examples of how to configure [2-dimensional Cartesian axes](figure-structure.md#2d-cartesian-trace-types-and-subplots) to follow a logarithmic rather than linear progression. [Configuring gridlines, ticks, tick labels and axis titles](axes.md) on logarithmic axes is done the same was as with [linear axes](axes.md). ### Logarithmic Axes with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). All of Plotly Express' 2-D Cartesian functions include the `log_x` and `log_y` keyword arguments, which can be set to `True` to set the corresponding axis to a logarithmic scale: @@ -114,7 +114,7 @@ fig.show() ### Logarithmic Axes with Graph Objects -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Figure` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Figure` class from `plotly.graph_objects`](graph-objects.md). ```python import plotly.graph_objects as go diff --git a/doc/python/map-configuration.md b/doc/python/map-configuration.md index f7cee50282a..36780eca29b 100644 --- a/doc/python/map-configuration.md +++ b/doc/python/map-configuration.md @@ -45,7 +45,7 @@ If your figure is created with a `px.scatter_map`, `px.scatter_mapbox`, `px.line Geo maps are outline-based maps. If your figure is created with a `px.scatter_geo`, `px.line_geo` or `px.choropleth` function or otherwise contains one or more traces of type `go.Scattergeo` or `go.Choropleth`, the `layout.geo` object in your figure contains configuration information for the map itself. -> This page documents **Geo outline-based maps**, and the [Tile Map Layers documentation](/python/tile-map-layers/) describes how to configure tile-based maps. +> This page documents **Geo outline-based maps**, and the [Tile Map Layers documentation](tile-map-layers.md) describes how to configure tile-based maps. **Note:** Plotly Express cannot create empty figures, so the examples below mostly create an "empty" map using `fig = go.Figure(go.Scattergeo())`. That said, every configuration option here is equally applicable to non-empty maps created with the Plotly Express `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions. @@ -59,7 +59,7 @@ In **Plotly.py 6.3 and later**, the base map layer is created from the following In **earlier versions of Plotly.py**, the base map layer is based on Natural Earth data only. Plotly includes data from Natural Earth "as-is". This dataset draws boundaries of countries according to de facto status. See the [Natural Earth page for more details](https://www.naturalearthdata.com/downloads/50m-cultural-vectors/50m-admin-0-countries-2/). -Various lines and area fills can be shown or hidden, and their color and line-widths specified. In the [default `plotly` template](/python/templates/), a map frame and physical features such as a coastal outline and filled land areas are shown, at a small-scale 1:110m resolution: +Various lines and area fills can be shown or hidden, and their color and line-widths specified. In the [default `plotly` template](templates.md), a map frame and physical features such as a coastal outline and filled land areas are shown, at a small-scale 1:110m resolution: ```python import plotly.graph_objects as go @@ -89,7 +89,7 @@ fig.show() ### Disabling Base Maps -In certain cases, such as large scale [choropleth maps](/python/choropleth-maps/), the default physical map can be distracting. In this case the `layout.geo.visible` attribute can be set to `False` to hide all base map attributes except those which are explicitly set to true. For example in the following map we hide all physical features except rivers and lakes, neither of which are shown by default: +In certain cases, such as large scale [choropleth maps](choropleth-maps.md), the default physical map can be distracting. In this case the `layout.geo.visible` attribute can be set to `False` to hide all base map attributes except those which are explicitly set to true. For example in the following map we hide all physical features except rivers and lakes, neither of which are shown by default: ```python import plotly.graph_objects as go @@ -114,7 +114,7 @@ In **Plotly.py 6.3 and later**, this base map is created from [UN data](https:// In **earlier versions of Plotly.py**, this base map is based on Natural Earth data only. Plotly includes data from Natural Earth "as-is". This dataset draws boundaries of countries according to defacto status. See the [Natural Earth page for more details](https://www.naturalearthdata.com/downloads/50m-cultural-vectors/50m-admin-0-countries-2/). -**To create a map with your own cultural features** please refer to our [choropleth documentation](/python/choropleth-maps/). +**To create a map with your own cultural features** please refer to our [choropleth documentation](choropleth-maps.md). Here is a map with only cultural features enabled and styled, at a 1:50m resolution, which includes only country boundaries. See below for country sub-unit cultural base map features: @@ -171,7 +171,7 @@ fig.show() ### Automatic Zooming or Bounds Fitting -The `layout.geo.fitbounds` attribute can be set to `locations` to automatically set the center and latitude and longitude range according to the data being plotted. See the [choropleth maps](/python/choropleth-maps/) documentation for more information. +The `layout.geo.fitbounds` attribute can be set to `locations` to automatically set the center and latitude and longitude range according to the data being plotted. See the [choropleth maps](choropleth-maps.md) documentation for more information. ```python import plotly.express as px @@ -218,7 +218,7 @@ fig.show() ### Graticules (Latitude and Longitude Grid Lines) -A graticule can be drawn using `layout.geo.lataxis.showgrid` and `layout.geo.lonaxis.showgrid` with options similar to [2d cartesian ticks](/python/axes/). +A graticule can be drawn using `layout.geo.lataxis.showgrid` and `layout.geo.lonaxis.showgrid` with options similar to [2d cartesian ticks](axes.md). ```python import plotly.graph_objects as go diff --git a/doc/python/marginal-plots.md b/doc/python/marginal-plots.md index 49728403f7f..e9461af3e28 100644 --- a/doc/python/marginal-plots.md +++ b/doc/python/marginal-plots.md @@ -35,11 +35,11 @@ jupyter: ### Overview -Marginal distribution plots are small subplots above or to the right of a main plot, which show the distribution of data along only one dimension. Marginal distribution plot capabilities are built into various Plotly Express functions such as `scatter` and `histogram`. [Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +Marginal distribution plots are small subplots above or to the right of a main plot, which show the distribution of data along only one dimension. Marginal distribution plot capabilities are built into various Plotly Express functions such as `scatter` and `histogram`. [Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ### Scatter Plot Marginals -The `marginal_x` and `marginal_y` arguments accept one of `"histogram"`, `"rug"`, `"box"`, or `"violin"` (see also how to create [histograms](/python/histograms/), [box plots](/python/box-plots/) and [violin plots](/python/violin-plots/) as the main figure). +The `marginal_x` and `marginal_y` arguments accept one of `"histogram"`, `"rug"`, `"box"`, or `"violin"` (see also how to create [histograms](histograms.md), [box plots](box-plots.md) and [violin plots](violin.md) as the main figure). Marginal plots are linked to the main plot: try zooming or panning on the main plot. @@ -74,7 +74,7 @@ fig.show() ### Marginal Plots on Histograms -[Histograms](/python/histograms/) are often used to show the distribution of a variable, and they also support marginal plots in Plotly Express, with the `marginal` argument: +[Histograms](histograms.md) are often used to show the distribution of a variable, and they also support marginal plots in Plotly Express, with the `marginal` argument: ```python import plotly.express as px @@ -95,7 +95,7 @@ fig.show() ### Marginal Plots and Facets -Marginal plots can be used in conjunction with [Plotly Express facets](/python/facet-plots/) so long as they go along different directions: +Marginal plots can be used in conjunction with [Plotly Express facets](facet-plots.md) so long as they go along different directions: ```python import plotly.express as px diff --git a/doc/python/mixed-subplots.md b/doc/python/mixed-subplots.md index 24ee5123beb..b6bf73e57dc 100644 --- a/doc/python/mixed-subplots.md +++ b/doc/python/mixed-subplots.md @@ -35,9 +35,9 @@ jupyter: ### Mixed Subplots and Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). -> *Note*: At this time, Plotly Express does not support creating figures with arbitrary mixed subplots i.e. figures with subplots of different types. Plotly Express only supports [facet plots](/python/facet-plots/) and [marginal distribution subplots](/python/marginal-plots/). To make a figure with mixed subplots, use the [`make_subplots()`](/python/subplots/) function in conjunction with [graph objects](/python/graph-objects/) as documented below. +> *Note*: At this time, Plotly Express does not support creating figures with arbitrary mixed subplots i.e. figures with subplots of different types. Plotly Express only supports [facet plots](facet-plots.md) and [marginal distribution subplots](marginal-plots.md). To make a figure with mixed subplots, use the [`make_subplots()`](subplots.md) function in conjunction with [graph objects](graph-objects.md) as documented below. #### Mixed Subplot diff --git a/doc/python/ml-knn.md b/doc/python/ml-knn.md index 28ff33469bd..fac065beba2 100644 --- a/doc/python/ml-knn.md +++ b/doc/python/ml-knn.md @@ -49,7 +49,7 @@ Using Scikit-learn, we first generate synthetic data that form the shape of a mo In the graph, we display all the negative labels as squares, and positive labels as circles. We differentiate the training and test set by adding a dot to the center of test data. -In this example, we will use [graph objects](/python/graph-objects/), Plotly's low-level API for building figures. +In this example, we will use [graph objects](graph-objects.md), Plotly's low-level API for building figures. ```python import plotly.graph_objects as go @@ -90,7 +90,7 @@ fig.show() Now, we train the kNN model on the same training data displayed in the previous graph. Then, we predict the confidence score of the model for each of the data points in the test set. We will use shapes to denote the true labels, and the color will indicate the confidence of the model for assign that score. -In this example, we will use [Plotly Express](/python/plotly-express/), Plotly's high-level API for building figures. Notice that `px.scatter` only require 1 function call to plot both negative and positive labels, and can additionally set a continuous color scale based on the `y_score` output by our kNN model. +In this example, we will use [Plotly Express](plotly-express.md), Plotly's high-level API for building figures. Notice that `px.scatter` only require 1 function call to plot both negative and positive labels, and can additionally set a continuous color scale based on the `y_score` output by our kNN model. ```python import plotly.express as px @@ -128,7 +128,7 @@ Instead of predicting the conference for the test set, we can predict the confid Then, for each of those points, we will use our model to give a confidence score, and plot it with a [contour plot](https://plotly.com/python/contour-plots/). -In this example, we will use [graph objects](/python/graph-objects/), Plotly's low-level API for building figures. +In this example, we will use [graph objects](graph-objects.md), Plotly's low-level API for building figures. ```python import plotly.graph_objects as go @@ -257,13 +257,14 @@ IFrame(snippet_url + 'knn-classification', width='100%', height=1200) It is also possible to visualize the prediction confidence of the model using [heatmaps](https://plotly.com/python/heatmaps/). In this example, you can see how to compute how confident the model is about its prediction at every point in the 2D grid. Here, we define the confidence as the difference between the highest score and the score of the other classes summed, at a certain point. -In this example, we will use [Plotly Express](/python/plotly-express/), Plotly's high-level API for building figures. +In this example, we will use [Plotly Express](plotly-express.md), Plotly's high-level API for building figures. ```python import plotly.express as px import plotly.graph_objects as go import numpy as np from sklearn.neighbors import KNeighborsClassifier +from sklearn.model_selection import train_test_split mesh_size = .02 margin = 1 diff --git a/doc/python/ml-pca.md b/doc/python/ml-pca.md index 1776d3be393..13766959136 100644 --- a/doc/python/ml-pca.md +++ b/doc/python/ml-pca.md @@ -52,7 +52,7 @@ First, let's plot all the features and see how the `species` in the Iris dataset In our example, we are plotting all 4 features from the Iris dataset, thus we can see how `sepal_width` is compared against `sepal_length`, then against `petal_width`, and so forth. Keep in mind how some pairs of features can more easily separate different species. -In this example, we will use [Plotly Express](/python/plotly-express/), Plotly's high-level API for building figures. +In this example, we will use [Plotly Express](plotly-express.md), Plotly's high-level API for building figures. ```python import plotly.express as px @@ -75,7 +75,7 @@ Now, we apply `PCA` the same dataset, and retrieve **all** the components. We us The importance of explained variance is demonstrated in the example below. The subplot between PC3 and PC4 is clearly unable to separate each class, whereas the subplot between PC1 and PC2 shows a clear separation between each species. -In this example, we will use [Plotly Express](/python/plotly-express/), Plotly's high-level API for building figures. +In this example, we will use [Plotly Express](plotly-express.md), Plotly's high-level API for building figures. ```python import plotly.express as px @@ -222,6 +222,7 @@ For more details about the linear algebra behind eigenvectors and loadings, see ```python import plotly.express as px +import numpy as np from sklearn.decomposition import PCA from sklearn import datasets from sklearn.preprocessing import StandardScaler diff --git a/doc/python/ml-regression.md b/doc/python/ml-regression.md index 5215058286d..09a2d155625 100644 --- a/doc/python/ml-regression.md +++ b/doc/python/ml-regression.md @@ -52,7 +52,7 @@ We will be using the [Linear Regression][lr], which is a simple model that fit a ### Ordinary Least Square (OLS) with `plotly.express` -This example shows [how to use `plotly.express`'s `trendline` parameter to train a simply Ordinary Least Square (OLS)](/python/linear-fits/) for predicting the tips waiters will receive based on the value of the total bill. +This example shows [how to use `plotly.express`'s `trendline` parameter to train a simply Ordinary Least Square (OLS)](linear-fits.md) for predicting the tips waiters will receive based on the value of the total bill. [lr]: https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html @@ -491,7 +491,7 @@ y = df['petal_width'] # Define and fit the grid model = DecisionTreeRegressor() param_grid = { - 'criterion': ['mse', 'friedman_mse', 'mae'], + 'criterion': ['squared_error', 'friedman_mse', 'absolute_error'], 'max_depth': range(2, 5) } grid = GridSearchCV(model, param_grid, cv=N_FOLD) diff --git a/doc/python/ml-roc-pr.md b/doc/python/ml-roc-pr.md index 8c4bd7e40da..7c1beff07ab 100644 --- a/doc/python/ml-roc-pr.md +++ b/doc/python/ml-roc-pr.md @@ -260,12 +260,12 @@ df.loc[samples.index, 'species'] = samples.values # Define the inputs and outputs X = df.drop(columns=['species', 'species_id']) y = df['species'] -y_onehot = pd.get_dummies(y, columns=model.classes_) # Fit the model model = LogisticRegression(max_iter=200) model.fit(X, y) y_scores = model.predict_proba(X) +y_onehot = pd.get_dummies(y, columns=model.classes_) # Create an empty figure, and iteratively add new lines # every time we compute a new class diff --git a/doc/python/ml-tsne-umap-projections.md b/doc/python/ml-tsne-umap-projections.md index dfd7d78d866..32bf72756a7 100644 --- a/doc/python/ml-tsne-umap-projections.md +++ b/doc/python/ml-tsne-umap-projections.md @@ -110,7 +110,7 @@ Just like t-SNE, [UMAP](https://umap-learn.readthedocs.io/en/latest/index.html) In the example below, we see how easy it is to use UMAP as a drop-in replacement for scikit-learn's `manifold.TSNE`. ```python -from umap import UMAP +from umap.umap_ import UMAP import plotly.express as px df = px.data.iris() @@ -146,7 +146,7 @@ Although there's over 1000 data points, and many more dimensions than the previo ```python import plotly.express as px from sklearn.datasets import load_digits -from umap import UMAP +from umap.umap_ import UMAP digits = load_digits() diff --git a/doc/python/multiple-axes.md b/doc/python/multiple-axes.md index 11cbf0261ab..773212fef28 100644 --- a/doc/python/multiple-axes.md +++ b/doc/python/multiple-axes.md @@ -35,9 +35,9 @@ jupyter: ### Multiple Y Axes and Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). -> *Note*: At this time, Plotly Express does not support multiple Y axes on a single figure. To make such a figure, use the [`make_subplots()`](/python/subplots/) function in conjunction with [graph objects](/python/graph-objects/) as documented below. +> *Note*: At this time, Plotly Express does not support multiple Y axes on a single figure. To make such a figure, use the [`make_subplots()`](subplots.md) function in conjunction with [graph objects](graph-objects.md) as documented below. #### Two Y Axes @@ -441,4 +441,4 @@ fig.show() ``` #### Reference -All of the y-axis properties are found here: https://plotly.com/python/reference/layout/yaxis/. For more information on creating subplots see the [Subplots in Python](/python/subplots/) section. +All of the y-axis properties are found here: https://plotly.com/python/reference/layout/yaxis/. For more information on creating subplots see the [Subplots in Python](subplots.md) section. diff --git a/doc/python/network-graphs.md b/doc/python/network-graphs.md index c9d85b5aa31..239de687983 100644 --- a/doc/python/network-graphs.md +++ b/doc/python/network-graphs.md @@ -120,7 +120,6 @@ node_text = [] for node, adjacencies in enumerate(G.adjacency()): node_adjacencies.append(len(adjacencies[1])) node_text.append('# of connections: '+str(len(adjacencies[1]))) - node_trace.marker.color = node_adjacencies node_trace.text = node_text ``` diff --git a/doc/python/orca-management.md b/doc/python/orca-management.md index d1ca867df59..7e6c4a73d35 100644 --- a/doc/python/orca-management.md +++ b/doc/python/orca-management.md @@ -33,12 +33,12 @@ jupyter: thumbnail: thumbnail/orca-management.png --- -> Orca support in Plotly.py is deprecated and will be removed after September 2025. See the [Static Image Export page](/python/static-image-export/) for details on using Kaleido for static image generation. +> Orca support in Plotly.py is deprecated and will be removed after September 2025. See the [Static Image Export page](static-image-export.md) for details on using Kaleido for static image generation. ### Overview This section covers the lower-level details of how plotly.py can use orca to perform static image generation. -Please refer to the [Static Image Export](/python/static-image-export/) section for general information on creating static images from plotly.py figures. +Please refer to the [Static Image Export](static-image-export.md) section for general information on creating static images from plotly.py figures. ### What is orca? Orca is an [Electron](https://electronjs.org/) application that inputs plotly figure specifications and converts them into static images. Orca can run as a command-line utility or as a long-running server process. In order to provide the fastest possible image export experience, plotly.py launches orca in server mode, and communicates with it over a local port. See https://github.com/plotly/orca for more information. diff --git a/doc/python/pandas-backend.md b/doc/python/pandas-backend.md index 2ee28762850..89f51420ba8 100644 --- a/doc/python/pandas-backend.md +++ b/doc/python/pandas-backend.md @@ -35,9 +35,9 @@ jupyter: ### Introduction -The popular [Pandas](https://pandas.pydata.org/) data analysis and manipulation tool provides [plotting functions on its `DataFrame` and `Series` objects](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html), which have historically produced `matplotlib` plots. Since version 0.25, Pandas has provided a mechanism to use different backends, and as of version 4.8 of `plotly`, you can now use a [Plotly Express-powered](/python/plotly-express/) backend for Pandas plotting. This means you can now produce interactive plots directly from a data frame, without even needing to import Plotly. +The popular [Pandas](https://pandas.pydata.org/) data analysis and manipulation tool provides [plotting functions on its `DataFrame` and `Series` objects](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html), which have historically produced `matplotlib` plots. Since version 0.25, Pandas has provided a mechanism to use different backends, and as of version 4.8 of `plotly`, you can now use a [Plotly Express-powered](plotly-express.md) backend for Pandas plotting. This means you can now produce interactive plots directly from a data frame, without even needing to import Plotly. -To activate this backend, you will need to [have Plotly installed](/python/getting-started/), and then just need to set `pd.options.plotting.backend` to `"plotly"` and call `.plot()` to get a `plotly.graph_objects.Figure` object back, just like if you had called Plotly Express directly: +To activate this backend, you will need to [have Plotly installed](getting-started.md), and then just need to set `pd.options.plotting.backend` to `"plotly"` and call `.plot()` to get a `plotly.graph_objects.Figure` object back, just like if you had called Plotly Express directly: ```python import pandas as pd @@ -48,7 +48,7 @@ fig = df.plot() fig.show() ``` -This functionality wraps [Plotly Express](/python/plotly-express/) and so you can use any of the [styling options available to Plotly Express methods](/python/styling-plotly-express/). Since what you get back is a regular `Figure` object, you can use any of the update mechanisms supported by these objects to apply [templates](/python/templates/) or further customize [axes](/python/axes/), [colors](/python/colorscales/), [legends](/python/legend/), [fonts](/python/figure-labels/), [hover labels](/python/hover-text-and-formatting/) etc. [Faceting](/python/facet-plots/) is also supported. +This functionality wraps [Plotly Express](plotly-express.md) and so you can use any of the [styling options available to Plotly Express methods](styling-plotly-express.md). Since what you get back is a regular `Figure` object, you can use any of the update mechanisms supported by these objects to apply [templates](templates.md) or further customize [axes](axes.md), [colors](colorscales.md), [legends](legend.md), [fonts](figure-labels.md), [hover labels](hover-text-and-formatting.md) etc. [Faceting](facet-plots.md) is also supported. ```python import pandas as pd @@ -65,7 +65,7 @@ fig.show() > The Plotly plotting backend for Pandas is *not intended* to be a drop-in replacement for the default; it does not implement all or even most of the same keyword arguments, such as `subplots=True` etc. -The Plotly plotting backend for Pandas is a more convenient way to invoke certain [Plotly Express](/python/plotly-express/) functions by chaining a `.plot()` call without having to import Plotly Express directly. Plotly Express, as of version 4.8 with [wide-form data support](/python/wide-form/) in addition to its robust long-form data support, implements behaviour for the `x` and `y` keywords that are very similar to the `matplotlib` backend. +The Plotly plotting backend for Pandas is a more convenient way to invoke certain [Plotly Express](plotly-express.md) functions by chaining a `.plot()` call without having to import Plotly Express directly. Plotly Express, as of version 4.8 with [wide-form data support](wide-form.md) in addition to its robust long-form data support, implements behaviour for the `x` and `y` keywords that are very similar to the `matplotlib` backend. In practice, this means that the following two ways of making a chart are identical and support the same additional arguments, because they call the same underlying code: @@ -84,7 +84,7 @@ fig2 = px.bar(df) fig2.show() ``` -To achieve a similar effect to `subplots=True`, for example, the [Plotly Express `facet_row` and `facet_col` options](/python/facet-plots/) can be used, the same was as they work when directly calling [Plotly Express with wide-form data](/python/wide-form/): +To achieve a similar effect to `subplots=True`, for example, the [Plotly Express `facet_row` and `facet_col` options](facet-plots.md) can be used, the same was as they work when directly calling [Plotly Express with wide-form data](wide-form.md): ```python import pandas as pd diff --git a/doc/python/parallel-categories-diagram.md b/doc/python/parallel-categories-diagram.md index 51ecd4168bb..14db0abfb78 100644 --- a/doc/python/parallel-categories-diagram.md +++ b/doc/python/parallel-categories-diagram.md @@ -39,7 +39,7 @@ The parallel categories diagram (also known as parallel sets or alluvial diagram Combinations of category rectangles across dimensions are connected by ribbons, where the height of the ribbon corresponds to the relative frequency of occurrence of the combination of categories in the data set. -For other representations of multivariate data, also see [parallel coordinates](/python/parallel-coordinates-plot/), [radar charts](/python/radar-chart/) and [scatterplot matrix (SPLOM)](/python/splom/). A visually-similar but more generic type of visualization is the [sankey diagrams](/python/sankey-diagram/). +For other representations of multivariate data, also see [parallel coordinates](parallel-coordinates-plot.md), [radar charts](radar-chart.md) and [scatterplot matrix (SPLOM)](splom.md). A visually-similar but more generic type of visualization is the [sankey diagrams](sankey-diagram.md). #### Basic Parallel Category Diagram with plotly.express diff --git a/doc/python/parallel-coordinates-plot.md b/doc/python/parallel-coordinates-plot.md index ee0c58bd999..3f675750dd9 100644 --- a/doc/python/parallel-coordinates-plot.md +++ b/doc/python/parallel-coordinates-plot.md @@ -37,7 +37,7 @@ jupyter: ## Parallel Coordinates plot with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). In a parallel coordinates plot with `px.parallel_coordinates`, each row of the DataFrame is represented by a polyline mark which traverses a set of parallel axes, one for each of the dimensions. For other representations of multivariate data, also see [parallel categories](/python/parallel-categories-diagram/), [radar charts](/python/radar-chart/) and [scatterplot matrix (SPLOM)](/python/splom/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). In a parallel coordinates plot with `px.parallel_coordinates`, each row of the DataFrame is represented by a polyline mark which traverses a set of parallel axes, one for each of the dimensions. For other representations of multivariate data, also see [parallel categories](parallel-categories-diagram.md), [radar charts](radar-chart.md) and [scatterplot matrix (SPLOM)](splom.md). ```python import plotly.express as px diff --git a/doc/python/pattern-hatching-texture.md b/doc/python/pattern-hatching-texture.md index ec5649eb325..c5840103bdf 100644 --- a/doc/python/pattern-hatching-texture.md +++ b/doc/python/pattern-hatching-texture.md @@ -36,7 +36,7 @@ jupyter: *New in 5.0, with support for pie, sunburst, icicle, funnelarea, and treemap charts in 5.15* -[Bar charts](/python/bar-charts/), [histograms](/python/histograms/), [polar bar charts](/python/wind-rose-charts/), [area charts](/python/filled-area-plots/), [pie charts](/python/pie-charts), [sunburst charts](/python/sunburst-charts), [funnelarea charts](/python/funnel-charts), [icicle charts](/python/icicle-charts/), and [treemap charts](/python/treemaps), have large markers or areas which support not only a fill color, but also an optional **pattern** (also known as "hatching" or "texture"). This can be used for a variety of reasons: +[Bar charts](bar-charts.md), [histograms](histograms.md), [polar bar charts](wind-rose-charts.md), [area charts](filled-area-plots.md), [pie charts](pie-charts.md), [sunburst charts](sunburst-charts.md), [funnelarea charts](funnel-charts.md), [icicle charts](icicle-charts.md), and [treemap charts](treemaps.md), have large markers or areas which support not only a fill color, but also an optional **pattern** (also known as "hatching" or "texture"). This can be used for a variety of reasons: * to double-encode variables (i.e. using both color and pattern) to improve accessibility for visually-impaired end-users * to encode an additional variable beyond just using color @@ -75,7 +75,7 @@ fig.show() ### Controlling Pattern Assignment -In the charts above, the first value of the variable assigned `pattern_shape` gets the empty pattern, but this (and indeed every pattern-to-variable assignment) can be controlled using `pattern_shape_sequence` and `pattern_shape_map`, analogously to the way [discrete colors](/python/discrete-color/) can be mapped using Plotly Express. +In the charts above, the first value of the variable assigned `pattern_shape` gets the empty pattern, but this (and indeed every pattern-to-variable assignment) can be controlled using `pattern_shape_sequence` and `pattern_shape_map`, analogously to the way [discrete colors](discrete-color.md) can be mapped using Plotly Express. Here we use `pattern_shape_sequence` to replace the defaults and include a pattern-shape for the first variable: @@ -136,7 +136,7 @@ fig.show() ### Patterns using Graph Objects -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Bar` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Bar` class from `plotly.graph_objects`](graph-objects.md). ```python import plotly.graph_objects as go diff --git a/doc/python/performance.md b/doc/python/performance.md index b162abaf8db..ae154f25cec 100644 --- a/doc/python/performance.md +++ b/doc/python/performance.md @@ -44,7 +44,7 @@ Plotly Express natively supports various dataframe libraries, including pandas, In versions of Plotly.py prior to version 6, Plotly Express functions accepted non-pandas dataframes as input but used the [dataframe interchange protocol](https://data-apis.org/dataframe-protocol/latest/) or converted those dataframes to pandas internally. -See [the Plotly Express Arguments page](/python/px-arguments) for full details on supported dataframe libraries. +See [the Plotly Express Arguments page](px-arguments.md) for full details on supported dataframe libraries. ## NumPy and NumPy Convertible Arrays for Improved Performance @@ -175,7 +175,7 @@ In a Jupyter notebook environment that supports magic commands, you can load it In the examples below we show that it is possible to represent up to around a million points with WebGL-enabled traces. For larger datasets, or for a clearer visualization of the density of points, -it is also possible to use [datashader](/python/datashader/). +it is also possible to use [datashader](datashader.md). ### WebGL with Plotly Express @@ -208,7 +208,7 @@ fig.show() #### WebGL with 1,000,000 points with Graph Objects -If Plotly Express does not provide a good starting point for creating a chart, you can use [the more generic `go.Scattergl` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point for creating a chart, you can use [the more generic `go.Scattergl` class from `plotly.graph_objects`](graph-objects.md). ```python import plotly.graph_objects as go @@ -243,7 +243,7 @@ Use [Datashader](https://datashader.org/) to reduce the size of a dataset passed ### Passing Datashader Rasters as a Tile Map Image Layer -The following example shows the spatial distribution of taxi rides in New York City, which are concentrated on major avenues. For more details about tile-based maps, see [the tile map layers tutorial](/python/tile-map-layers). +The following example shows the spatial distribution of taxi rides in New York City, which are concentrated on major avenues. For more details about tile-based maps, see [the tile map layers tutorial](tile-map-layers.md). ```python import pandas as pd @@ -263,7 +263,16 @@ coordinates = [[coords_lon[0], coords_lat[0]], from colorcet import fire import datashader.transfer_functions as tf +import io +import base64 + +# Get PIL Image and convert it into a unicode string (for JSON serializability) img = tf.shade(agg, cmap=fire)[::-1].to_pil() +buffer = io.BytesIO() +img.save(buffer, format='PNG') +raw_data = buffer.getvalue() +img_base64 = base64.b64encode(raw_data).decode('utf-8') +url = f"data:image/png;base64,{img_base64}" import plotly.express as px # Trick to create rapidly a figure with map axes @@ -271,7 +280,7 @@ fig = px.scatter_map(dff[:1], lat='Lat', lon='Lon', zoom=12) # Add the datashader image as a tile map layer image fig.update_layout( map_style="carto-darkmatter", - map_layers=[{"sourcetype": "image", "source": img, "coordinates": coordinates}], + map_layers=[{"sourcetype": "image", "source": url, "coordinates": coordinates}], ) fig.show() ``` @@ -312,4 +321,4 @@ fig.update_layout(coloraxis_colorbar=dict(title='Count', tickprefix='1.e')) fig.show() ``` -Instead of using Datashader, it would theoretically be possible to create a [2d histogram](/python/2d-histogram-contour/) with Plotly, but this is not recommended because you would need to load the whole dataset of around 5M rows in the browser for plotly.js to compute the heatmap. +Instead of using Datashader, it would theoretically be possible to create a [2d histogram](2d-histogram-contour.md) with Plotly, but this is not recommended because you would need to load the whole dataset of around 5M rows in the browser for plotly.js to compute the heatmap. diff --git a/doc/python/pie-charts.md b/doc/python/pie-charts.md index c03e37aba68..c7de8351a50 100644 --- a/doc/python/pie-charts.md +++ b/doc/python/pie-charts.md @@ -36,11 +36,11 @@ jupyter: A pie chart is a circular statistical chart, which is divided into sectors to illustrate numerical proportion. If you're looking instead for a multilevel hierarchical pie-like chart, go to the -[Sunburst tutorial](/python/sunburst-charts/). +[Sunburst tutorial](sunburst-charts.md). ### Pie chart with plotly express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). In `px.pie`, data visualized by the sectors of the pie is set in `values`. The sector labels are set in `names`. @@ -91,7 +91,7 @@ fig.show() ### Using an explicit mapping for discrete colors -For more information about discrete colors, see the [dedicated page](/python/discrete-color). +For more information about discrete colors, see the [dedicated page](discrete-color.md). ```python import plotly.express as px @@ -120,12 +120,12 @@ fig.show() ### Basic Pie Chart with go.Pie -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Pie` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Pie` class from `plotly.graph_objects`](graph-objects.md). In `go.Pie`, 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`. If you're looking instead for a multilevel hierarchical pie-like chart, go to the -[Sunburst tutorial](/python/sunburst-charts/). +[Sunburst tutorial](sunburst-charts.md). ```python import plotly.graph_objects as go @@ -306,7 +306,7 @@ fig.show() *New in 5.15* -Pie charts support [patterns](/python/pattern-hatching-texture/) (also known as hatching or texture) in addition to color. +Pie charts support [patterns](pattern-hatching-texture.md) (also known as hatching or texture) in addition to color. ```python import plotly.graph_objects as go @@ -331,7 +331,7 @@ fig.show() ### See Also: Sunburst charts -For multilevel pie charts representing hierarchical data, you can use the `Sunburst` chart. A simple example is given below, for more information see the [tutorial on Sunburst charts](/python/sunburst-charts/). +For multilevel pie charts representing hierarchical data, you can use the `Sunburst` chart. A simple example is given below, for more information see the [tutorial on Sunburst charts](sunburst-charts.md). ```python import plotly.graph_objects as go diff --git a/doc/python/plotly-express.md b/doc/python/plotly-express.md index 0aebc72dccf..76def2805b7 100644 --- a/doc/python/plotly-express.md +++ b/doc/python/plotly-express.md @@ -36,34 +36,33 @@ jupyter: ### Overview -The `plotly.express` module (usually imported as `px`) contains functions that can create entire figures at once, and is referred to as Plotly Express or PX. Plotly Express is a built-in part of the `plotly` library, and is the recommended starting point for creating most common figures. Every Plotly Express function uses [graph objects](/python/graph-objects/) internally and returns a `plotly.graph_objects.Figure` instance. Throughout the `plotly` documentation, you will find the Plotly Express way of building figures at the top of any applicable page, followed by a section on how to use graph objects to build similar figures. Any figure created in a single function call with Plotly Express could be created using graph objects alone, but with between 5 and 100 times more code. +The `plotly.express` module (usually imported as `px`) contains functions that can create entire figures at once, and is referred to as Plotly Express or PX. Plotly Express is a built-in part of the `plotly` library, and is the recommended starting point for creating most common figures. Every Plotly Express function uses [graph objects](graph-objects.md) internally and returns a `plotly.graph_objects.Figure` instance. Throughout the `plotly` documentation, you will find the Plotly Express way of building figures at the top of any applicable page, followed by a section on how to use graph objects to build similar figures. Any figure created in a single function call with Plotly Express could be created using graph objects alone, but with between 5 and 100 times more code. Plotly Express provides [more than 30 functions for creating different types of figures](https://plotly.com/python-api-reference/plotly.express.html). The API for these functions was carefully designed to be as consistent and easy to learn as possible, making it easy to switch from a scatter plot to a bar chart to a histogram to a sunburst chart throughout a data exploration session. *Scroll down for a gallery of Plotly Express plots, each made in a single function call.* Here is a talk from the [SciPy 2021 conference](https://www.scipy2021.scipy.org/) that gives a good introduction to Plotly Express and [Dash](https://dash.plotly.com/): -```html hide_code=true
-``` + Plotly Express currently includes the following functions: -* **Basics**: [`scatter`](/python/line-and-scatter/), [`line`](/python/line-charts/), [`area`](/python/filled-area-plots/), [`bar`](/python/bar-charts/), [`funnel`](/python/funnel-charts/), [`timeline`](https://plotly.com/python/gantt/) -* **Part-of-Whole**: [`pie`](/python/pie-charts/), [`sunburst`](/python/sunburst-charts/), [`treemap`](/python/treemaps/), [`icicle`](/python/icicle-charts/), [`funnel_area`](/python/funnel-charts/) -* **1D Distributions**: [`histogram`](/python/histograms/), [`box`](/python/box-plots/), [`violin`](/python/violin/), [`strip`](/python/strip-charts/), [`ecdf`](/python/ecdf-plots/) -* **2D Distributions**: [`density_heatmap`](/python/2D-Histogram/), [`density_contour`](/python/2d-histogram-contour/) -* **Matrix or Image Input**: [`imshow`](/python/imshow/) -* **3-Dimensional**: [`scatter_3d`](/python/3d-scatter-plots/), [`line_3d`](/python/3d-line-plots/) -* **Multidimensional**: [`scatter_matrix`](/python/splom/), [`parallel_coordinates`](/python/parallel-coordinates-plot/), [`parallel_categories`](/python/parallel-categories-diagram/) -* **Tile Maps**: [`scatter_map`](/python/tile-scatter-maps/), [`line_map`](/python/lines-on-tile-maps/), [`choropleth_map`](/python/tile-county-choropleth/), [`density_map`](/python/tile-density-heatmaps/) -* **Outline Maps**: [`scatter_geo`](/python/scatter-plots-on-maps/), [`line_geo`](/python/lines-on-maps/), [`choropleth`](/python/choropleth-maps/) -* **Polar Charts**: [`scatter_polar`](/python/polar-chart/), [`line_polar`](/python/polar-chart/), [`bar_polar`](/python/wind-rose-charts/) -* **Ternary Charts**: [`scatter_ternary`](/python/ternary-plots/), [`line_ternary`](/python/ternary-plots/) +* **Basics**: [`scatter`](line-and-scatter.md), [`line`](line-charts.md), [`area`](filled-area-plots.md), [`bar`](bar-charts.md), [`funnel`](funnel-charts.md), [`timeline`](https://plotly.com/python/gantt/) +* **Part-of-Whole**: [`pie`](pie-charts.md), [`sunburst`](sunburst-charts.md), [`treemap`](treemaps.md), [`icicle`](icicle-charts.md), [`funnel_area`](funnel-charts.md) +* **1D Distributions**: [`histogram`](histograms.md), [`box`](box-plots.md), [`violin`](violin.md), [`strip`](strip-charts.md), [`ecdf`](ecdf-plots.md) +* **2D Distributions**: [`density_heatmap`](2D-Histogram.md), [`density_contour`](2d-histogram-contour.md) +* **Matrix or Image Input**: [`imshow`](imshow.md) +* **3-Dimensional**: [`scatter_3d`](3d-scatter-plots.md), [`line_3d`](3d-line-plots.md) +* **Multidimensional**: [`scatter_matrix`](splom.md), [`parallel_coordinates`](parallel-coordinates-plot.md), [`parallel_categories`](parallel-categories-diagram.md) +* **Tile Maps**: [`scatter_map`](tile-scatter-maps.md), [`line_map`](lines-on-tile-maps.md), [`choropleth_map`](tile-county-choropleth.md), [`density_map`](tile-density-heatmaps.md) +* **Outline Maps**: [`scatter_geo`](scatter-plots-on-maps.md), [`line_geo`](lines-on-maps.md), [`choropleth`](choropleth-maps.md) +* **Polar Charts**: [`scatter_polar`](polar-chart.md), [`line_polar`](polar-chart.md), [`bar_polar`](wind-rose-charts.md) +* **Ternary Charts**: [`scatter_ternary`](ternary-plots.md), [`line_ternary`](ternary-plots.md) ### High-Level Features @@ -71,17 +70,17 @@ The Plotly Express API in general offers the following features: * **A single entry point into `plotly`**: just `import plotly.express as px` and get access to [all the plotting functions](https://plotly.com/python-api-reference/plotly.express.html), plus [built-in demo datasets under `px.data`](https://plotly.com/python-api-reference/generated/plotly.data.html#module-plotly.data) and [built-in color scales and sequences under `px.color`](https://plotly.com/python-api-reference/generated/plotly.colors.html#module-plotly.colors). Every PX function returns a `plotly.graph_objects.Figure` object, so you can edit it using all the same methods like [`update_layout` and `add_trace`](https://plotly.com/python/creating-and-updating-figures/#updating-figures). * **Sensible, Overridable Defaults**: PX functions will infer sensible defaults wherever possible, and will always let you override them. -* **Flexible Input Formats**: PX functions [accept input in a variety of formats](/python/px-arguments/), from `list`s and `dict`s to [long-form or wide-form `DataFrame`s](/python/wide-form/) to [`numpy` arrays and `xarrays`](/python/imshow/) to [GeoPandas `GeoDataFrames`](/python/maps/). -* **Automatic Trace and Layout configuration**: PX functions will create one [trace](/python/figure-structure) per animation frame for each unique combination of data values mapped to discrete color, symbol, line-dash, facet-row and/or facet-column. Traces' [`legendgroup` and `showlegend` attributes](https://plotly.com/python/legend/) are set such that only one legend item appears per unique combination of discrete color, symbol and/or line-dash. Traces are automatically linked to a correctly-configured [subplot of the appropriate type](/python/figure-structure). -* **Automatic Figure Labelling**: PX functions [label axes, legends and colorbars](https://plotly.com/python/figure-labels/) based in the input `DataFrame` or `xarray`, and provide [extra control with the `labels` argument](/python/styling-plotly-express/). -* **Automatic Hover Labels**: PX functions populate the hover-label using the labels mentioned above, and provide [extra control with the `hover_name` and `hover_data` arguments](/python/hover-text-and-formatting/). -* **Styling Control**: PX functions [read styling information from the default figure template](/python/styling-plotly-express/), and support commonly-needed [cosmetic controls like `category_orders` and `color_discrete_map`](/python/styling-plotly-express/) to precisely control categorical variables. -* **Uniform Color Handling**: PX functions automatically switch between [continuous](/python/colorscales/) and [categorical color](/python/discrete-color/) based on the input type. -* **Faceting**: the 2D-cartesian plotting functions support [row, column and wrapped facetting with `facet_row`, `facet_col` and `facet_col_wrap` arguments](/python/facet-plots/). -* **Marginal Plots**: the 2D-cartesian plotting functions support [marginal distribution plots](/python/marginal-plots/) with the `marginal`, `marginal_x` and `marginal_y` arguments. -* **A Pandas backend**: the 2D-cartesian plotting functions are available as [a Pandas plotting backend](/python/pandas-backend/) so you can call them via `df.plot()`. -* **Trendlines**: `px.scatter` supports [built-in trendlines with accessible model output](/python/linear-fits/). -* **Animations**: many PX functions support [simple animation support via the `animation_frame` and `animation_group` arguments](/python/animations/). +* **Flexible Input Formats**: PX functions [accept input in a variety of formats](px-arguments.md), from `list`s and `dict`s to [long-form or wide-form `DataFrame`s](wide-form.md) to [`numpy` arrays and `xarrays`](imshow.md) to [GeoPandas `GeoDataFrames`](maps.md). +* **Automatic Trace and Layout configuration**: PX functions will create one [trace](figure-structure.md) per animation frame for each unique combination of data values mapped to discrete color, symbol, line-dash, facet-row and/or facet-column. Traces' [`legendgroup` and `showlegend` attributes](https://plotly.com/python/legend.md) are set such that only one legend item appears per unique combination of discrete color, symbol and/or line-dash. Traces are automatically linked to a correctly-configured [subplot of the appropriate type](figure-structure.md). +* **Automatic Figure Labelling**: PX functions [label axes, legends and colorbars](https://plotly.com/python/figure-labels/) based in the input `DataFrame` or `xarray`, and provide [extra control with the `labels` argument](styling-plotly-express.md). +* **Automatic Hover Labels**: PX functions populate the hover-label using the labels mentioned above, and provide [extra control with the `hover_name` and `hover_data` arguments](hover-text-and-formatting.md). +* **Styling Control**: PX functions [read styling information from the default figure template](styling-plotly-express.md), and support commonly-needed [cosmetic controls like `category_orders` and `color_discrete_map`](styling-plotly-express.md) to precisely control categorical variables. +* **Uniform Color Handling**: PX functions automatically switch between [continuous](colorscales.md) and [categorical color](discrete-color.md) based on the input type. +* **Faceting**: the 2D-cartesian plotting functions support [row, column and wrapped facetting with `facet_row`, `facet_col` and `facet_col_wrap` arguments](facet-plots.md). +* **Marginal Plots**: the 2D-cartesian plotting functions support [marginal distribution plots](marginal-plots.md) with the `marginal`, `marginal_x` and `marginal_y` arguments. +* **A Pandas backend**: the 2D-cartesian plotting functions are available as [a Pandas plotting backend](pandas-backend.md) so you can call them via `df.plot()`. +* **Trendlines**: `px.scatter` supports [built-in trendlines with accessible model output](linear-fits.md). +* **Animations**: many PX functions support [simple animation support via the `animation_frame` and `animation_group` arguments](animations.md). * **Automatic WebGL switching**: for sufficiently large scatter plots, PX will automatically [use WebGL for hardware-accelerated rendering](https://plotly.com/python/webgl-vs-svg/). @@ -104,7 +103,7 @@ The following set of figures is just a sampling of what can be done with Plotly #### Scatter, Line, Area and Bar Charts -**Read more about [scatter plots](/python/line-and-scatter/) and [discrete color](/python/discrete-color/).** +**Read more about [scatter plots](line-and-scatter.md) and [discrete color](discrete-color.md).** ```python import plotly.express as px @@ -113,7 +112,7 @@ fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species") fig.show() ``` -**Read more about [trendlines](/python/linear-fits/) and [templates](/python/templates/) and [marginal distribution plots](https://plotly.com/python/marginal-plots/).** +**Read more about [trendlines](linear-fits.md) and [templates](templates.md) and [marginal distribution plots](https://plotly.com/python/marginal-plots/).** ```python import plotly.express as px @@ -123,7 +122,7 @@ fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", margina fig.show() ``` -**Read more about [error bars](/python/error-bars/).** +**Read more about [error bars](error-bars.md).** ```python import plotly.express as px @@ -133,7 +132,7 @@ fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", error_x fig.show() ``` -**Read more about [bar charts](/python/bar-charts/).** +**Read more about [bar charts](bar-charts.md).** ```python import plotly.express as px @@ -151,7 +150,7 @@ fig = px.bar(df, x="medal", y="count", color="nation", fig.show() ``` -**Read more about [facet plots](/python/facet-plots/).** +**Read more about [facet plots](facet-plots.md).** ```python import plotly.express as px @@ -161,7 +160,7 @@ fig = px.bar(df, x="sex", y="total_bill", color="smoker", barmode="group", facet fig.show() ``` -**Read more about [scatterplot matrices (SPLOMs)](/python/splom/).** +**Read more about [scatterplot matrices (SPLOMs)](splom.md).** ```python @@ -171,7 +170,7 @@ fig = px.scatter_matrix(df, dimensions=["sepal_width", "sepal_length", "petal_wi fig.show() ``` -**Read more about [parallel coordinates](/python/parallel-coordinates-plot/) and [parallel categories](/python/parallel-categories-diagram/), as well as [continuous color](/python/colorscales/).** +**Read more about [parallel coordinates](parallel-coordinates-plot.md) and [parallel categories](parallel-categories-diagram.md), as well as [continuous color](colorscales.md).** ```python import plotly.express as px @@ -190,7 +189,7 @@ fig = px.parallel_categories(df, color="size", color_continuous_scale=px.colors. fig.show() ``` -**Read more about [hover labels](/python/hover-text-and-formatting/).** +**Read more about [hover labels](hover-text-and-formatting.md).** ```python import plotly.express as px @@ -200,7 +199,7 @@ fig = px.scatter(df.query("year==2007"), x="gdpPercap", y="lifeExp", size="pop", fig.show() ``` -**Read more about [animations](/python/animations/).** +**Read more about [animations](animations.md).** ```python import plotly.express as px @@ -211,7 +210,7 @@ fig = px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animati fig.show() ``` -**Read more about [line charts](/python/line-charts/).** +**Read more about [line charts](line-charts.md).** ```python import plotly.express as px @@ -221,7 +220,7 @@ fig = px.line(df, x="year", y="lifeExp", color="continent", line_group="country" fig.show() ``` -**Read more about [area charts](/python/filled-area-plots/).** +**Read more about [area charts](filled-area-plots.md).** ```python import plotly.express as px @@ -230,7 +229,7 @@ fig = px.area(df, x="year", y="pop", color="continent", line_group="country") fig.show() ``` -**Read more about [timeline/Gantt charts](/python/gantt/).** +**Read more about [timeline/Gantt charts](gantt.md).** ```python import plotly.express as px @@ -246,7 +245,7 @@ fig = px.timeline(df, x_start="Start", x_end="Finish", y="Resource", color="Reso fig.show() ``` -**Read more about [funnel charts](/python/funnel-charts/).** +**Read more about [funnel charts](funnel-charts.md).** ```python import plotly.express as px @@ -259,7 +258,7 @@ fig.show() ### Part to Whole Charts -**Read more about [pie charts](/python/pie-charts/).** +**Read more about [pie charts](pie-charts.md).** ```python import plotly.express as px @@ -269,7 +268,7 @@ fig = px.pie(df, values='pop', names='country', title='Population of European co fig.show() ``` -**Read more about [sunburst charts](/python/sunburst-charts/).** +**Read more about [sunburst charts](sunburst-charts.md).** ```python import plotly.express as px @@ -280,7 +279,7 @@ fig = px.sunburst(df, path=['continent', 'country'], values='pop', fig.show() ``` -**Read more about [treemaps](/python/treemaps/).** +**Read more about [treemaps](treemaps.md).** ```python import plotly.express as px @@ -291,7 +290,7 @@ fig = px.treemap(df, path=[px.Constant('world'), 'continent', 'country'], values fig.show() ``` -**Read more about [icicle charts](/python/icicle-charts/).** +**Read more about [icicle charts](icicle-charts.md).** ```python import plotly.express as px @@ -304,7 +303,7 @@ fig.show() #### Distributions -**Read more about [histograms](/python/histograms/).** +**Read more about [histograms](histograms.md).** ```python import plotly.express as px @@ -313,7 +312,7 @@ fig = px.histogram(df, x="total_bill", y="tip", color="sex", marginal="rug", hov fig.show() ``` -**Read more about [box plots](/python/box-plots/).** +**Read more about [box plots](box-plots.md).** ```python import plotly.express as px @@ -322,7 +321,7 @@ fig = px.box(df, x="day", y="total_bill", color="smoker", notched=True) fig.show() ``` -**Read more about [violin plots](/python/violin/).** +**Read more about [violin plots](violin.md).** ```python import plotly.express as px @@ -349,7 +348,7 @@ fig = px.strip(df, x="total_bill", y="time", orientation="h", color="smoker") fig.show() ``` -**Read more about [density contours, also known as 2D histogram contours](/python/2d-histogram-contour/).** +**Read more about [density contours, also known as 2D histogram contours](2d-histogram-contour.md).** ```python import plotly.express as px @@ -358,7 +357,7 @@ fig = px.density_contour(df, x="sepal_width", y="sepal_length") fig.show() ``` -**Read more about [density heatmaps, also known as 2D histograms](/python/2D-Histogram/).** +**Read more about [density heatmaps, also known as 2D histograms](2D-Histogram.md).** ```python import plotly.express as px @@ -369,7 +368,7 @@ fig.show() ### Images and Heatmaps -**Read more about [heatmaps and images](/python/imshow/).** +**Read more about [heatmaps and images](imshow.md).** ```python import plotly.express as px @@ -386,14 +385,20 @@ fig.show() ```python import plotly.express as px from skimage import io -img = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg') +from io import BytesIO +import requests + +url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg' +headers = {"User-Agent": "Mozilla/5.0"} +response = requests.get(url, headers=headers) +img = io.imread(BytesIO(response.content)) fig = px.imshow(img) fig.show() ``` #### Tile Maps -**Read more about [tile maps](/python/tile-map-layers/) and [point on tile maps](/python/tile-scatter-maps/).** +**Read more about [tile maps](tile-map-layers.md) and [point on tile maps](tile-scatter-maps.md).** ```python import plotly.express as px @@ -404,7 +409,7 @@ fig = px.scatter_map(df, lat="centroid_lat", lon="centroid_lon", color="peak_hou fig.show() ``` -**Read more about [tile map GeoJSON choropleths](/python/tile-county-choropleth/).** +**Read more about [tile map GeoJSON choropleths](tile-county-choropleth.md).** ```python import plotly.express as px @@ -421,7 +426,7 @@ fig.show() ### Outline Maps -**Read more about [outline symbol maps](/python/scatter-plots-on-maps/).** +**Read more about [outline symbol maps](scatter-plots-on-maps.md).** ```python import plotly.express as px @@ -432,7 +437,7 @@ fig.show() ``` -**Read more about [choropleth maps](/python/choropleth-maps/).** +**Read more about [choropleth maps](choropleth-maps.md).** ```python import plotly.express as px @@ -444,7 +449,7 @@ fig.show() #### Polar Coordinates -**Read more about [polar plots](/python/polar-chart/).** +**Read more about [polar plots](polar-chart.md).** ```python import plotly.express as px @@ -464,7 +469,7 @@ fig = px.line_polar(df, r="frequency", theta="direction", color="strength", line fig.show() ``` -**Read more about [polar bar charts](/python/wind-rose-charts/).** +**Read more about [polar bar charts](wind-rose-charts.md).** ```python import plotly.express as px @@ -476,7 +481,7 @@ fig.show() #### 3D Coordinates -**Read more about [3D scatter plots](/python/3d-scatter-plots/).** +**Read more about [3D scatter plots](3d-scatter-plots.md).** ```python import plotly.express as px @@ -488,7 +493,7 @@ fig.show() #### Ternary Coordinates -**Read more about [ternary charts](/python/ternary-plots/).** +**Read more about [ternary charts](ternary-plots.md).** ```python import plotly.express as px diff --git a/doc/python/polar-chart.md b/doc/python/polar-chart.md index 63203c30f1c..bafe0e2b043 100644 --- a/doc/python/polar-chart.md +++ b/doc/python/polar-chart.md @@ -37,7 +37,7 @@ jupyter: A polar chart represents data along radial and angular axes. With Plotly Express, it is possible to represent polar data as scatter markers with `px.scatter_polar`, and as lines with `px.line_polar`. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). For other types of arguments, see the section below using `go.Scatterpolar`. @@ -85,7 +85,7 @@ fig.show() ## Polar Scatter Plot with go.Scatterpolar -If Plotly Express does not provide a good starting point, you can use [the more generic `go.Scatterpolar` class from `plotly.graph_objects`](/python/graph-objects/). All the options are documented in the [reference page](https://plotly.com/python/reference/scatterpolar/). +If Plotly Express does not provide a good starting point, you can use [the more generic `go.Scatterpolar` class from `plotly.graph_objects`](graph-objects.md). All the options are documented in the [reference page](https://plotly.com/python/reference/scatterpolar/). #### Basic Polar Chart diff --git a/doc/python/px-arguments.md b/doc/python/px-arguments.md index 308a8d02bdb..7a7702963ad 100644 --- a/doc/python/px-arguments.md +++ b/doc/python/px-arguments.md @@ -65,7 +65,7 @@ There are three common conventions for storing column-oriented data, usually in * **long-form data** has one row per observation, and one column per variable. This is suitable for storing and displaying multivariate data i.e. with dimension greater than 2. This format is sometimes called "tidy". * **wide-form data** has one row per value of one of the first variable, and one column per value of the second variable. This is suitable for storing and displaying 2-dimensional data. -* **mixed-form data** is a hybrid of long-form and wide-form data, with one row per value of one variable, and some columns representing values of another, and some columns representing more variables. See the [wide-form documentation](/python/wide-form/) for examples of how to use Plotly Express to visualize this kind of data. +* **mixed-form data** is a hybrid of long-form and wide-form data, with one row per value of one variable, and some columns representing values of another, and some columns representing more variables. See the [wide-form documentation](wide-form.md) for examples of how to use Plotly Express to visualize this kind of data. Every Plotly Express function can operate on long-form data (other than `px.imshow` which operates only on wide-form input), and in addition, the following 2D-Cartesian functions can operate on wide-form and mixed-form data: `px.scatter`, `px.line`, `px.area`, `px.bar`, `px.histogram`, `px.violin`, `px.box`, `px.strip`, `px.funnel`, `px.density_heatmap` and `px.density_contour`. @@ -101,7 +101,7 @@ fig = px.bar(wide_df, x="nation", y=["gold", "silver", "bronze"], title="Wide-Fo fig.show() ``` -You might notice that y-axis and legend labels are slightly different for the second plot: they are "value" and "variable", respectively, and this is also reflected in the hoverlabel text. Note that the labels "medal" and "count" do not appear in the wide-form data frame, so in this case, you must supply these yourself, or [you can use a data frame with named row- and column-indexes](/python/wide-form/). You can [rename these labels with the `labels` argument](/python/styling-plotly-express/): +You might notice that y-axis and legend labels are slightly different for the second plot: they are "value" and "variable", respectively, and this is also reflected in the hoverlabel text. Note that the labels "medal" and "count" do not appear in the wide-form data frame, so in this case, you must supply these yourself, or [you can use a data frame with named row- and column-indexes](wide-form.md). You can [rename these labels with the `labels` argument](styling-plotly-express.md): ```python import plotly.express as px @@ -112,7 +112,7 @@ fig = px.bar(wide_df, x="nation", y=["gold", "silver", "bronze"], title="Wide-Fo fig.show() ``` -Many more examples of wide-form and messy data input can be found in our [detailed wide-form support documentation](/python/wide-form/). +Many more examples of wide-form and messy data input can be found in our [detailed wide-form support documentation](wide-form.md). ## Dataframe Input @@ -130,7 +130,7 @@ PySpark dataframes are also supported and are converted to pandas dataframes int #### Additional Dependencies Required - Plotly Express requires NumPy. You can install it with `pip install numpy` if it's not installed by the dataframe library you are using. -- To use [trendlines](/python/linear-fits/), you'll also need to have pandas installed. +- To use [trendlines](linear-fits.md), you'll also need to have pandas installed. - To use PySpark dataframes, you'll need to have pandas installed. To use dataframes that support the dataframe interchange protocol, you'll need to have PyArrow installed. ### Example: Using a Pandas DataFrame with `px.bar` @@ -217,7 +217,7 @@ fig = px.line(x=[1, 2, 3, 4], y=[3, 5, 4, 8]) fig.show() ``` -List arguments can also be passed in as a list of lists, which triggers [wide-form data processing](/python/wide-form/), with the downside that the resulting traces will need to be manually renamed via `fig.data[].name = "name"`. +List arguments can also be passed in as a list of lists, which triggers [wide-form data processing](wide-form.md), with the downside that the resulting traces will need to be manually renamed via `fig.data[].name = "name"`. ```python import plotly.express as px diff --git a/doc/python/quiver-plots.md b/doc/python/quiver-plots.md index 530c305e47a..438e8f5a899 100644 --- a/doc/python/quiver-plots.md +++ b/doc/python/quiver-plots.md @@ -33,7 +33,7 @@ jupyter: thumbnail: thumbnail/quiver-plot.jpg --- -Quiver plots can be made using a [figure factory](/python/figure-factories/) as detailed in this page. +Quiver plots can be made using a [figure factory](figure-factories.md) as detailed in this page. #### Basic Quiver Plot @@ -81,7 +81,7 @@ fig.show() #### See also -[Cone plot](/python/cone-plot) for the 3D equivalent of quiver plots. +[Cone plot](cone-plot.md) for the 3D equivalent of quiver plots. #### Reference diff --git a/doc/python/radar-chart.md b/doc/python/radar-chart.md index eb3129d94a5..4f01a3fbf9f 100644 --- a/doc/python/radar-chart.md +++ b/doc/python/radar-chart.md @@ -33,13 +33,13 @@ jupyter: thumbnail: thumbnail/radar.gif --- -A [Radar Chart](https://en.wikipedia.org/wiki/Radar_chart) (also known as a spider plot or star plot) displays multivariate data in the form of a two-dimensional chart of quantitative variables represented on axes originating from the center. The relative position and angle of the axes is typically uninformative. It is equivalent to a [parallel coordinates plot](/python/parallel-coordinates-plot/) with the axes arranged radially. +A [Radar Chart](https://en.wikipedia.org/wiki/Radar_chart) (also known as a spider plot or star plot) displays multivariate data in the form of a two-dimensional chart of quantitative variables represented on axes originating from the center. The relative position and angle of the axes is typically uninformative. It is equivalent to a [parallel coordinates plot](parallel-coordinates-plot.md) with the axes arranged radially. -For a Radar Chart, use a [polar chart](/python/polar-chart/) with categorical angular variables, with `px.line_polar`, or with `go.Scatterpolar`. See [more examples of polar charts](/python/polar-chart/). +For a Radar Chart, use a [polar chart](polar-chart.md) with categorical angular variables, with `px.line_polar`, or with `go.Scatterpolar`. See [more examples of polar charts](polar-chart.md). #### Radar Chart with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). Use `line_close=True` for closed lines. diff --git a/doc/python/renderers.md b/doc/python/renderers.md index bdf18301dbb..f1480509204 100644 --- a/doc/python/renderers.md +++ b/doc/python/renderers.md @@ -263,4 +263,4 @@ No matter the approach chosen to display a figure, [the figure data structure](h The default JSON serialization mechanism can be slow for figures with many data points or with large `numpy` arrays or data frames. **If [the `orjson` package](https://github.com/ijl/orjson) is installed**, `plotly` will use that instead of the built-in `json` package, which can lead to **5-10x** speedups for large figures. -Once a figure is serialized to JSON, it must be rendered by a browser, either immediately in the user's browser, at some later point if the figure is exported to HTML, or immediately in Kaleido's internal headless browser for static image export. Rendering time is generally proportional to the total number of data points in the figure, the number of traces and the number of subplots. In situations where rendering performance is slow, we recommend considering [the use of `plotly` WebGL traces](/python/webgl-vs-svg/) to exploit GPU-accelerated rendering in the browser, or [using the Datashader library to do Python-side rendering](/python/datashader/) before using `px.imshow()` to render the figure. +Once a figure is serialized to JSON, it must be rendered by a browser, either immediately in the user's browser, at some later point if the figure is exported to HTML, or immediately in Kaleido's internal headless browser for static image export. Rendering time is generally proportional to the total number of data points in the figure, the number of traces and the number of subplots. In situations where rendering performance is slow, we recommend considering [the use of `plotly` WebGL traces](webgl-vs-svg.md) to exploit GPU-accelerated rendering in the browser, or [using the Datashader library to do Python-side rendering](datashader.md) before using `px.imshow()` to render the figure. diff --git a/doc/python/sankey-diagram.md b/doc/python/sankey-diagram.md index a014e5a5085..12879b04ecd 100644 --- a/doc/python/sankey-diagram.md +++ b/doc/python/sankey-diagram.md @@ -190,7 +190,7 @@ fig.show() ### Hovertemplate and customdata of Sankey diagrams -Links and nodes have their own hovertemplate, in which link- or node-specific attributes can be displayed. To add more data to links and nodes, it is possible to use the `customdata` attribute of `link` and `nodes`, as in the following example. For more information about hovertemplate and customdata, please see the [tutorial on hover text](/python/hover-text-and-formatting/). +Links and nodes have their own hovertemplate, in which link- or node-specific attributes can be displayed. To add more data to links and nodes, it is possible to use the `customdata` attribute of `link` and `nodes`, as in the following example. For more information about hovertemplate and customdata, please see the [tutorial on hover text](hover-text-and-formatting.md). ```python import plotly.graph_objects as go diff --git a/doc/python/scatter-plots-on-maps.md b/doc/python/scatter-plots-on-maps.md index ece97307817..ebcd98ed0eb 100644 --- a/doc/python/scatter-plots-on-maps.md +++ b/doc/python/scatter-plots-on-maps.md @@ -36,13 +36,13 @@ jupyter: #### Base Map Configuration -Plotly figures made with [Plotly Express](/python/plotly-express/) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](/python/graph-objects/) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](/python/map-configuration/) onto which data is plotted. +Plotly figures made with [Plotly Express](plotly-express.md) `px.scatter_geo`, `px.line_geo` or `px.choropleth` functions or containing `go.Choropleth` or `go.Scattergeo` [graph objects](graph-objects.md) have a `go.layout.Geo` object which can be used to [control the appearance of the base map](map-configuration.md) onto which data is plotted. ### Geographical Scatter Plot with px.scatter_geo -Here we show the [Plotly Express](/python/plotly-express/) function `px.scatter_geo` for a geographical scatter plot. The `size` argument is used to set the size of markers from a given column of the DataFrame. +Here we show the [Plotly Express](plotly-express.md) function `px.scatter_geo` for a geographical scatter plot. The `size` argument is used to set the size of markers from a given column of the DataFrame. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px diff --git a/doc/python/setting-graph-size.md b/doc/python/setting-graph-size.md index 717c25341df..510e39af9de 100644 --- a/doc/python/setting-graph-size.md +++ b/doc/python/setting-graph-size.md @@ -34,7 +34,7 @@ jupyter: ### Adjusting Height, Width, & Margins with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px @@ -69,7 +69,7 @@ IFrame(snippet_url + 'setting-graph-size', width='100%', height=1200) ### Adjusting Height, Width, & Margins With Graph Objects -[Graph objects](/python/graph-objects/) are the low-level building blocks of figures which you can use instead of Plotly Express for greater control. +[Graph objects](graph-objects.md) are the low-level building blocks of figures which you can use instead of Plotly Express for greater control. ```python import plotly.graph_objects as go diff --git a/doc/python/shapes.md b/doc/python/shapes.md index f14e2e7d3d6..9b914ee62e2 100644 --- a/doc/python/shapes.md +++ b/doc/python/shapes.md @@ -39,13 +39,13 @@ As a general rule, there are two ways to add shapes (lines or polygons) to figur 1. Trace types in the `scatter` family (e.g. `scatter`, `scatter3d`, `scattergeo` etc) can be drawn with `mode="lines"` and optionally support a `fill="self"` attribute, and so can be used to draw open or closed shapes on figures. 2. Standalone lines, ellipses and rectangles can be added to figures using `fig.add_shape()`, and they can be positioned absolutely within the figure, or they can be positioned relative to the axes of 2d cartesian subplots i.e. in data coordinates. -*Note:* there are [special methods `add_hline`, `add_vline`, `add_hrect` and `add_vrect` for the common cases of wanting to draw horizontal or vertical lines or rectangles](/python/horizontal-vertical-shapes/) that are fixed to data coordinates in one axis and absolutely positioned in another. +*Note:* there are [special methods `add_hline`, `add_vline`, `add_hrect` and `add_vrect` for the common cases of wanting to draw horizontal or vertical lines or rectangles](horizontal-vertical-shapes.md) that are fixed to data coordinates in one axis and absolutely positioned in another. The differences between these two approaches are that: * Traces can optionally support hover labels and can appear in legends. * Shapes can be positioned absolutely or relative to data coordinates in 2d cartesian subplots only. * Traces cannot be positioned absolutely but can be positioned relative to date coordinates in any subplot type. -* Traces also support [optional text](/python/text-and-annotations/), although there is a [textual equivalent to shapes in text annotations](/python/text-and-annotations/). +* Traces also support [optional text](text-and-annotations.md), although there is a [textual equivalent to shapes in text annotations](text-and-annotations.md). @@ -281,7 +281,7 @@ fig.show() #### Highlighting Time Series Regions with Rectangle Shapes -*Note:* there are [special methods `add_hline`, `add_vline`, `add_hrect` and `add_vrect` for the common cases of wanting to draw horizontal or vertical lines or rectangles](/python/horizontal-vertical-shapes/) that are fixed to data coordinates in one axis and absolutely positioned in another. +*Note:* there are [special methods `add_hline`, `add_vline`, `add_hrect` and `add_vrect` for the common cases of wanting to draw horizontal or vertical lines or rectangles](horizontal-vertical-shapes.md) that are fixed to data coordinates in one axis and absolutely positioned in another. ```python @@ -659,9 +659,9 @@ fig.show() _introduced in plotly 4.7_ -You can create layout shapes programmatically, but you can also draw shapes manually by setting the `dragmode` to one of the shape-drawing modes: `'drawline'`,`'drawopenpath'`, `'drawclosedpath'`, `'drawcircle'`, or `'drawrect'`. If you need to switch between different shape-drawing or other dragmodes (panning, selecting, etc.), [modebar buttons can be added](/python/configuration-options#add-optional-shapedrawing-buttons-to-modebar) in the `config` to select the dragmode. If you switch to a different dragmode such as pan or zoom, you will need to select the drawing tool in the modebar to go back to shape drawing. +You can create layout shapes programmatically, but you can also draw shapes manually by setting the `dragmode` to one of the shape-drawing modes: `'drawline'`,`'drawopenpath'`, `'drawclosedpath'`, `'drawcircle'`, or `'drawrect'`. If you need to switch between different shape-drawing or other dragmodes (panning, selecting, etc.), [modebar buttons can be added](configuration-options.md#add-optional-shapedrawing-buttons-to-modebar) in the `config` to select the dragmode. If you switch to a different dragmode such as pan or zoom, you will need to select the drawing tool in the modebar to go back to shape drawing. -This shape-drawing feature is particularly interesting for annotating graphs, in particular [image traces](/python/imshow) or [layout images](/python/images). +This shape-drawing feature is particularly interesting for annotating graphs, in particular [image traces](imshow.md) or [layout images](images.md). Once you have drawn shapes, you can select and modify an existing shape by clicking on its boundary (note the arrow pointer). Its fillcolor turns to pink to highlight the activated shape and then you can - drag and resize it for lines, rectangles and circles/ellipses diff --git a/doc/python/smoothing.md b/doc/python/smoothing.md index 2fd3e400fa5..e33406c4bf5 100644 --- a/doc/python/smoothing.md +++ b/doc/python/smoothing.md @@ -132,6 +132,16 @@ TMA_i = \frac{SMA_i + ... + SMA_{i+n}}{n} $$ ```python +import plotly.graph_objects as go +import numpy as np + +np.random.seed(1) + +x = np.linspace(0, 10, 100) +y = np.sin(x) +noise = 2 * np.random.random(len(x)) - 1 # uniformly distributed between -1 and 1 +y_noise = y + noise + def smoothTriangle(data, degree): triangle=np.concatenate((np.arange(degree + 1), np.arange(degree)[::-1])) # up then down smoothed=[] diff --git a/doc/python/splom.md b/doc/python/splom.md index bb9a8a748ed..b2d01aed157 100644 --- a/doc/python/splom.md +++ b/doc/python/splom.md @@ -41,7 +41,7 @@ A scatterplot matrix is a matrix associated to n numerical arrays (data variable Here we show the Plotly Express function `px.scatter_matrix` to plot the scatter matrix for the columns of the dataframe. By default, all columns are considered. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px @@ -80,7 +80,7 @@ fig.show() ### Scatter matrix (splom) with go.Splom -If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Splom` class from `plotly.graph_objects`](/python/graph-objects/). All its parameters are documented in the reference page https://plotly.com/python/reference/splom/. +If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Splom` class from `plotly.graph_objects`](graph-objects.md). All its parameters are documented in the reference page https://plotly.com/python/reference/splom/. The Plotly splom trace implementation for the scatterplot matrix does not require to set $x=Xi$ , and $y=Xj$, for each scatter plot. All arrays, $X_1,X_2,…,X_n$ , are passed once, through a list of dicts called dimensions, i.e. each array/variable represents a dimension. @@ -293,7 +293,7 @@ fig.show() *New in 5.21* -Set `hoversubplots='axis'` with `hovermode` set to `x`, `x unified`, `y`, or `y unified` for hover effects to appear across a column or row. For more on hover effects, see the [Hover Text and Formatting](/python/hover-text-and-formatting/) page. +Set `hoversubplots='axis'` with `hovermode` set to `x`, `x unified`, `y`, or `y unified` for hover effects to appear across a column or row. For more on hover effects, see the [Hover Text and Formatting](hover-text-and-formatting.md) page. ```python import plotly.graph_objects as go diff --git a/doc/python/static-image-export.md b/doc/python/static-image-export.md index 43f584e097e..75c53a62dcb 100644 --- a/doc/python/static-image-export.md +++ b/doc/python/static-image-export.md @@ -35,7 +35,7 @@ jupyter: thumbnail: thumbnail/static-image-export.png --- -This page demonstrates how to export interactive Plotly figures to static image formats like PNG, JPEG, SVG, and PDF. If you want to export Plotly figures to HTML to retain interactivity, see the [Interactive HTML Export page](/python/interactive-html-export/) +This page demonstrates how to export interactive Plotly figures to static image formats like PNG, JPEG, SVG, and PDF. If you want to export Plotly figures to HTML to retain interactivity, see the [Interactive HTML Export page](interactive-html-export.md) ## Install Dependencies @@ -52,7 +52,7 @@ or with conda: $ conda install -c conda-forge python-kaleido ``` -It's also possible to generate static images using [Orca](https://github.com/plotly/orca), though support for Orca will be removed after September 2025. See the [Orca Management](/python/orca-management/) page for more details. +It's also possible to generate static images using [Orca](https://github.com/plotly/orca), though support for Orca will be removed after September 2025. See the [Orca Management](orca-management.md) page for more details. ### Chrome @@ -200,11 +200,13 @@ fig = px.bar(data_canada, x='year', y='pop') img_bytes = fig.to_image(format="png") ``` -Here's the bytes object displayed using `IPython.display.Image`: +Here's the bytes object displayed using `Image.show()`: ```python -from IPython.display import Image -Image(img_bytes) +from PIL import Image +from io import BytesIO +img = Image.open(BytesIO(img_bytes)) +img.show() ``` ## Specify Image Dimensions and Scale @@ -212,7 +214,8 @@ In addition to the image format, the `to_image` and `write_image` functions prov ```python img_bytes = fig.to_image(format="png", width=600, height=350, scale=2) -Image(img_bytes) +img = Image.open(BytesIO(img_bytes)) +img.show() ``` ## Specify Image Export Engine diff --git a/doc/python/static-image-generation-migration.md b/doc/python/static-image-generation-migration.md index f6476a9cb93..bafa5e8ecd1 100644 --- a/doc/python/static-image-generation-migration.md +++ b/doc/python/static-image-generation-migration.md @@ -38,7 +38,7 @@ jupyter: Plotly.py 6.1 introduces support for Kaleido v1, which [improves static image generation](https://plotly.com/blog/kaleido-the-next-generation/) for Plotly figures. -While adding support for Kaleido v1, we are deprecating support for earlier versions of Kaleido and support for [Orca](/python/orca-management/). Support for Orca and earlier versions of Kaleido will be removed after September 2025, and we recommend updating to the latest Kaleido. This page documents how to migrate your Plotly code to Kaleido v1 and outlines the changes in functionality. +While adding support for Kaleido v1, we are deprecating support for earlier versions of Kaleido and support for [Orca](orca-management.md). Support for Orca and earlier versions of Kaleido will be removed after September 2025, and we recommend updating to the latest Kaleido. This page documents how to migrate your Plotly code to Kaleido v1 and outlines the changes in functionality. To migrate from either Orca or Kaleido v0, first install the latest Kaleido with: @@ -50,7 +50,7 @@ pip install --upgrade kaleido Kaleido uses Chrome for static image generation. Versions of Kaleido prior to v1 included Chrome as part of the Kaleido package. Kaleido v1 does not include Chrome; instead, it looks for a compatible version of Chrome (or Chromium) already installed on the machine on which it's running. -See the [Chrome section](/python/static-image-export#chrome) on the Static Image Export page for more details on Chome and Kaleido. +See the [Chrome section](static-image-export.md#chrome) on the Static Image Export page for more details on Chome and Kaleido. ## Engine Parameter @@ -79,5 +79,5 @@ If you are migrating from Orca, the following config settings do not apply to Ka ## Multiple Image Export -Plotly.py 6.1 includes a `write_images` function (`plotly.io.write_images`), which we recommend over `write_image` when exporting more than one figure. Calling `write_images` with a list of figures (or dicts representing figures) to export provides better performance than multiple calls with `write_image`. See the [Write Multiple Images](/python/static-image-export#write-multiple-images) section for more details. +Plotly.py 6.1 includes a `write_images` function (`plotly.io.write_images`), which we recommend over `write_image` when exporting more than one figure. Calling `write_images` with a list of figures (or dicts representing figures) to export provides better performance than multiple calls with `write_image`. See the [Write Multiple Images](static-image-export.md#write-multiple-images) section for more details. diff --git a/doc/python/streamline-plots.md b/doc/python/streamline-plots.md index 3fc0e6e69a2..618716f6bcd 100644 --- a/doc/python/streamline-plots.md +++ b/doc/python/streamline-plots.md @@ -35,7 +35,7 @@ jupyter: A Streamline plot is a representation based on a 2-D vector field interpreted as a velocity field, consisting of closed curves tangent to the velocity field. In the case of a stationary velocity field, streamlines coincide with trajectories (see also the [Wikipedia page on streamlines, streaklines and pathlines](https://en.wikipedia.org/wiki/Streamlines,_streaklines,_and_pathlines)). -For the streamline [figure factory](/python/figure-factories/), one needs to provide +For the streamline [figure factory](figure-factories.md), one needs to provide - uniformly spaced ranges of `x` and `y` values (1D) - 2-D velocity values `u` and `v` defined on the cross-product (`np.meshgrid(x, y)`) of `x` and `y`. @@ -43,7 +43,7 @@ Velocity values are interpolated when determining the streamlines. Streamlines a #### Basic Streamline Plot -Streamline plots can be made with a [figure factory](/python/figure-factories/) as detailed in this page. +Streamline plots can be made with a [figure factory](figure-factories.md) as detailed in this page. ```python import plotly.figure_factory as ff @@ -99,9 +99,9 @@ fig.show() #### See also -For a 3D version of streamlines, use the trace `go.Streamtube` documented [here](/python/streamtube-plot/). +For a 3D version of streamlines, use the trace `go.Streamtube` documented [here](streamtube-plot.md). -For representing the 2-D vector field as arrows, see the [quiver plot tutorial](/python/quiver-plots/). +For representing the 2-D vector field as arrows, see the [quiver plot tutorial](quiver-plots.md). #### Reference diff --git a/doc/python/strip-charts.md b/doc/python/strip-charts.md index bad5d5e4c49..8da14c7b38c 100644 --- a/doc/python/strip-charts.md +++ b/doc/python/strip-charts.md @@ -35,11 +35,11 @@ jupyter: ### Strip Charts with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). The `px.strip()` function will make strip charts using underlying `box` traces with the box hidden. -See also [box plots](/python/box-plots/) and [violin plots](/python/violin/). +See also [box plots](box-plots.md) and [violin plots](violin.md). ```python import plotly.express as px @@ -49,7 +49,7 @@ fig = px.strip(df, x="total_bill", y="day") fig.show() ``` -Strip charts support [faceting](/python/facet-plots/) and [discrete color](/python/discrete-color/): +Strip charts support [faceting](facet-plots.md) and [discrete color](discrete-color.md): ```python import plotly.express as px diff --git a/doc/python/styling-plotly-express.md b/doc/python/styling-plotly-express.md index 60c4a3a30d6..b808cbe0c3a 100644 --- a/doc/python/styling-plotly-express.md +++ b/doc/python/styling-plotly-express.md @@ -37,15 +37,15 @@ jupyter: ### Styling Figures made with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/). Every Plotly Express function returns [a `plotly.graph_objects.Figure` object](/python/graph-objects/) whose `data` and `layout` has been pre-populated according to the provided arguments. +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md). Every Plotly Express function returns [a `plotly.graph_objects.Figure` object](graph-objects.md) whose `data` and `layout` has been pre-populated according to the provided arguments. > You can style and customize figures made with Plotly Express _in all the same ways_ as you can style figures made more manually by explicitly assembling `graph_objects` into a figure. More specifically, here are the 4 ways you can style and customize figures made with Plotly Express: 1. Control common parameters like width & height, titles, labeling and colors using built-in Plotly Express function arguments -2. Updating the figure attributes using [update methods or by directly setting attributes](/python/creating-and-updating-figures/) -3. Using Plotly's [theming/templating mechanism](/python/templates/) via the `template` argument to every Plotly Express function +2. Updating the figure attributes using [update methods or by directly setting attributes](creating-and-updating-figures.md) +3. Using Plotly's [theming/templating mechanism](templates.md) via the `template` argument to every Plotly Express function 4. Setting default values for common parameters using `px.defaults` ### Built-in Plotly Express Styling Arguments @@ -54,11 +54,11 @@ Many common styling options can be set directly in the `px` function call. Every - `title` to set the figure title - `width` and `height` to set the figure dimensions -- `template` to [set many styling parameters at once](/python/templates/) (see below for more details) +- `template` to [set many styling parameters at once](templates.md) (see below for more details) - `labels` to override the default axis and legend labels behaviour, which is to use the data frame column name if available, and otherwise to use the label name itself like "x", "y", "color" etc. `labels` accepts a `dict` whose keys are the label to rename and whose values are the desired labels. These labels appear in axis labels, legend and color bar titles, and in hover labels. - `category_orders` to override the default category ordering behaviour, which is to use the order in which the data appears in the input. `category_orders` accepts a `dict` whose keys are the column name to reorder and whose values are a `list` of values in the desired order. These orderings apply everywhere categories appear: in legends, on axes, in bar stacks, in the order of facets, in the order of animation frames etc. - `hover_data` and `hover_name` to control which attributes appear in the hover label and how they are formatted. -- [Various color-related attributes](/python/colorscales/) such as `color_continuous_scale`, `color_range`, `color_discrete_sequence` and/or `color_discrete_map` set the colors used in the figure. `color_discrete_map` accepts a dict whose keys are values mapped to `color` and whose values are the desired CSS colors. +- [Various color-related attributes](colorscales.md) such as `color_continuous_scale`, `color_range`, `color_discrete_sequence` and/or `color_discrete_map` set the colors used in the figure. `color_discrete_map` accepts a dict whose keys are values mapped to `color` and whose values are the desired CSS colors. To illustrate each of these, here is a simple, default figure made with Plotly Express. Note the default orderings for the x-axis categories and the usage of lowercase & snake_case data frame columns for axis labelling. @@ -93,7 +93,7 @@ fig.show() ### Updating or Modifying Figures made with Plotly Express -If none of the built-in Plotly Express arguments allow you to customize the figure the way you need to, you can use [the `update_*` and `add_*` methods](/python/creating-and-updating-figures/) on [the `plotly.graph_objects.Figure` object](/python/graph-objects/) returned by the PX function to make any further modifications to the figure. This approach is the one used throughout the Plotly.py documentation to [customize axes](/python/axes/), control [legends](/python/legend/) and [colorbars](/python/colorscales/), add [shapes](/python/shapes/) and [annotations](/python/text-and-annotations/) etc. +If none of the built-in Plotly Express arguments allow you to customize the figure the way you need to, you can use [the `update_*` and `add_*` methods](creating-and-updating-figures.md) on [the `plotly.graph_objects.Figure` object](graph-objects.md) returned by the PX function to make any further modifications to the figure. This approach is the one used throughout the Plotly.py documentation to [customize axes](axes.md), control [legends](legend.md) and [colorbars](colorscales.md), add [shapes](shapes.md) and [annotations](text-and-annotations.md) etc. Here is the same figure as above, with some additional customizations to the axes and legend via `.update_yaxes()`, and `.update_layout()`, as well as some annotations added via `.add_shape()` and `.add_annotation()`. @@ -134,7 +134,7 @@ fig.show() ### How Plotly Express Works with Templates -Plotly has a [theming system based on templates](/python/templates/) and figures created with Plotly Express interact smoothly with this system: +Plotly has a [theming system based on templates](templates.md) and figures created with Plotly Express interact smoothly with this system: - Plotly Express methods will use the default template if one is set in `plotly.io` (by default, this is set to `plotly`) or in `plotly.express.defaults` (see below) - The template in use can always be overridden via the `template` argument to every PX function diff --git a/doc/python/subplots.md b/doc/python/subplots.md index b5711ee5de8..4af44f8a9b5 100644 --- a/doc/python/subplots.md +++ b/doc/python/subplots.md @@ -37,9 +37,9 @@ jupyter: ### Subplots and Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). -Plotly Express does not support arbitrary subplot capabilities, instead it supports [faceting by a given data dimension](/python/facet-plots/), and it also supports [marginal charts to display distribution information](/python/marginal-plots/). +Plotly Express does not support arbitrary subplot capabilities, instead it supports [faceting by a given data dimension](facet-plots.md), and it also supports [marginal charts to display distribution information](marginal-plots.md). This page documents the usage of the lower-level `plotly.subplots` module and the `make_subplots` function it exposes to construct figures with arbitrary subplots. **Plotly Express faceting uses `make_subplots` internally** so adding traces to Plotly Express facets works just as documented here, with `fig.add_trace(..., row=, col=)`. diff --git a/doc/python/sunburst-charts.md b/doc/python/sunburst-charts.md index 06cfb38e57d..b3e31ce5b77 100644 --- a/doc/python/sunburst-charts.md +++ b/doc/python/sunburst-charts.md @@ -37,7 +37,7 @@ Sunburst plots visualize hierarchical data spanning outwards radially from root ### Basic Sunburst Plot with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.sunburst`, each row of the DataFrame is represented as a sector of the sunburst. @@ -105,7 +105,7 @@ fig.show() ### Using an explicit mapping for discrete colors -For more information about discrete colors, see the [dedicated page](/python/discrete-color). +For more information about discrete colors, see the [dedicated page](discrete-color.md). ```python import plotly.express as px @@ -138,7 +138,7 @@ fig.show() ### Basic Sunburst Plot with go.Sunburst -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Sunburst` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Sunburst` class from `plotly.graph_objects`](graph-objects.md). Main arguments: @@ -304,7 +304,7 @@ fig.show() *New in 5.15* -Sunburst charts support [patterns](/python/pattern-hatching-texture/) (also known as hatching or texture) in addition to color. In this example, we add a different pattern to each level of the hierarchy. We also specify the `solidity` of the pattern. +Sunburst charts support [patterns](pattern-hatching-texture.md) (also known as hatching or texture) in addition to color. In this example, we add a different pattern to each level of the hierarchy. We also specify the `solidity` of the pattern. ```python import plotly.graph_objects as go diff --git a/doc/python/templates.md b/doc/python/templates.md index 070d8633f35..dfe512c52aa 100644 --- a/doc/python/templates.md +++ b/doc/python/templates.md @@ -192,7 +192,7 @@ fig.add_scatter(y=[4, 5, 6], mode="markers", name="forth") fig.show() ``` -Note that because we built the template with a list of 3 scatter trace [graph objects](/python/graph-objects/) (one each for the diamond, square, and circle symbols), the forth scatter trace in the figure cycles around and takes on the defaults specified in the first template trace (The diamond symbol). +Note that because we built the template with a list of 3 scatter trace [graph objects](graph-objects.md) (one each for the diamond, square, and circle symbols), the forth scatter trace in the figure cycles around and takes on the defaults specified in the first template trace (The diamond symbol). #### Theming object tuple properties diff --git a/doc/python/ternary-contour.md b/doc/python/ternary-contour.md index 41e63baf273..81cef1c05d4 100644 --- a/doc/python/ternary-contour.md +++ b/doc/python/ternary-contour.md @@ -38,7 +38,7 @@ jupyter: A ternary contour plots represents isovalue lines of a quantity defined inside a [ternary diagram](https://en.wikipedia.org/wiki/Ternary_plot), i.e. as a function of three variables which sum is constant. Coordinates of the ternary plot often correspond to concentrations of three species, and the quantity represented as contours is some property (e.g., physical, chemical, thermodynamical) varying with the composition. -For ternary contour plots, use the [figure factory](/python/figure-factories/) called ``create_ternary_contour``. The figure factory interpolates between given data points in order to compute the contours. +For ternary contour plots, use the [figure factory](figure-factories.md) called ``create_ternary_contour``. The figure factory interpolates between given data points in order to compute the contours. Below we represent an example from metallurgy, where the mixing enthalpy is represented as a contour plot for aluminum-copper-yttrium (Al-Cu-Y) alloys. diff --git a/doc/python/ternary-plots.md b/doc/python/ternary-plots.md index f53a0862b08..754643f3bbe 100644 --- a/doc/python/ternary-plots.md +++ b/doc/python/ternary-plots.md @@ -39,7 +39,7 @@ A ternary plot depicts the ratios of three variables as positions in an equilate ## Ternary scatter plot with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). Here we use `px.scatter_ternary` to visualize the three-way split between the three major candidates in a municipal election. diff --git a/doc/python/ternary-scatter-contour.md b/doc/python/ternary-scatter-contour.md index 03f9f13da6a..808673b4d33 100644 --- a/doc/python/ternary-scatter-contour.md +++ b/doc/python/ternary-scatter-contour.md @@ -114,7 +114,6 @@ fig.show() ```python import plotly.graph_objects as go - contour_dict = contour_raw_data['Data'] # Defining a colormap: diff --git a/doc/python/text-and-annotations.md b/doc/python/text-and-annotations.md index 56f341e8728..3bdbb70b620 100644 --- a/doc/python/text-and-annotations.md +++ b/doc/python/text-and-annotations.md @@ -42,7 +42,7 @@ The differences between these two approaches are that: * Traces can optionally support hover labels and can appear in legends. * Text annotations can be positioned absolutely or relative to data coordinates in 2d/3d cartesian subplots only. * Traces cannot be positioned absolutely but can be positioned relative to data coordinates in any subplot type. -* Traces also be used to [draw shapes](/python/shapes/), although there is a [shape equivalent to text annotations](/python/shapes/). +* Traces also be used to [draw shapes](shapes.md), although there is a [shape equivalent to text annotations](shapes.md). ### Text on scatter plots with Plotly Express @@ -122,7 +122,7 @@ IFrame(snippet_url + 'text-and-annotations', width='100%', height=1200) ### Controlling Text Size with `uniformtext` -For the [pie](/python/pie-charts), [bar](/python/bar-charts)-like, [sunburst](/python/sunburst-charts) and [treemap](/python/treemaps) traces, it is possible to force all the text labels to have the same size thanks to the `uniformtext` layout parameter. The `minsize` attribute sets the font size, and the `mode` attribute sets what happens for labels which cannot fit with the desired fontsize: either `hide` them or `show` them with overflow. +For the [pie](pie-charts.md), [bar](bar-charts.md)-like, [sunburst](sunburst-charts.md) and [treemap](treemaps.md) traces, it is possible to force all the text labels to have the same size thanks to the `uniformtext` layout parameter. The `minsize` attribute sets the font size, and the `mode` attribute sets what happens for labels which cannot fit with the desired fontsize: either `hide` them or `show` them with overflow. Here is a bar chart with the default behavior which will scale down text to fit. @@ -162,7 +162,7 @@ fig.show() ### Controlling Maximum Text Size -The `textfont_size` parameter of the the [pie](/python/pie-charts), [bar](/python/bar-charts)-like, [sunburst](/python/sunburst-charts) and [treemap](/python/treemaps) traces can be used to set the **maximum font size** used in the chart. Note that the `textfont` parameter sets the `insidetextfont` and `outsidetextfont` parameter, which can also be set independently. +The `textfont_size` parameter of the the [pie](pie-charts.md), [bar](bar-charts.md)-like, [sunburst](sunburst-charts.md) and [treemap](treemaps.md) traces can be used to set the **maximum font size** used in the chart. Note that the `textfont` parameter sets the `insidetextfont` and `outsidetextfont` parameter, which can also be set independently. ```python import plotly.express as px @@ -703,7 +703,7 @@ fig.show() ### Positioning Text Annotations Absolutely -By default, text annotations have `xref` and `yref` set to `"x"` and `"y"`, respectively, meaning that their x/y coordinates are with respect to the axes of the plot. This means that panning the plot will cause the annotations to move. Setting `xref` and/or `yref` to `"paper"` will cause the `x` and `y` attributes to be interpreted in [paper coordinates](/python/figure-structure/#positioning-with-paper-container-coordinates-or-axis-domain-coordinates). +By default, text annotations have `xref` and `yref` set to `"x"` and `"y"`, respectively, meaning that their x/y coordinates are with respect to the axes of the plot. This means that panning the plot will cause the annotations to move. Setting `xref` and/or `yref` to `"paper"` will cause the `x` and `y` attributes to be interpreted in [paper coordinates](figure-structure.md#positioning-with-paper-container-coordinates-or-axis-domain-coordinates). Try panning or zooming in the following figure: diff --git a/doc/python/tile-county-choropleth.md b/doc/python/tile-county-choropleth.md index 06f6bd7b2da..07ec392507a 100644 --- a/doc/python/tile-county-choropleth.md +++ b/doc/python/tile-county-choropleth.md @@ -34,7 +34,7 @@ jupyter: thumbnail: thumbnail/mapbox-choropleth.png --- -A [Choropleth Map](https://en.wikipedia.org/wiki/Choropleth_map) is a map composed of colored polygons. It is used to represent spatial variations of a quantity. This page documents how to build **tile-map** choropleth maps, but you can also build [**outline** choropleth maps](/python/choropleth-maps). +A [Choropleth Map](https://en.wikipedia.org/wiki/Choropleth_map) is a map composed of colored polygons. It is used to represent spatial variations of a quantity. This page documents how to build **tile-map** choropleth maps, but you can also build [**outline** choropleth maps](choropleth-maps.md). Below we show how to create Choropleth Maps using either Plotly Express' `px.choropleth_map` function or the lower-level `go.Choroplethmap` graph object. @@ -75,7 +75,7 @@ df.head() ### Choropleth map using plotly.express and carto base map -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.choropleth_map`, each row of the DataFrame is represented as a region of the choropleth. @@ -154,7 +154,7 @@ fig.show() ### Discrete Colors -In addition to [continuous colors](/python/colorscales/), we can [discretely-color](/python/discrete-color/) our choropleth maps by setting `color` to a non-numerical column, like the name of the winner of an election. +In addition to [continuous colors](colorscales.md), we can [discretely-color](discrete-color.md) our choropleth maps by setting `color` to a non-numerical column, like the name of the winner of an election. ```python import plotly.express as px @@ -195,7 +195,7 @@ fig.show() ### Choropleth map using plotly.graph_objects and carto base map -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Choroplethmap` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Choroplethmap` class from `plotly.graph_objects`](graph-objects.md). ```python from urllib.request import urlopen @@ -224,7 +224,7 @@ fig.show() The earlier examples using `px.choropleth_map` and `go.Choroplethmap` use [Maplibre](https://maplibre.org/maplibre-gl-js/docs/) for rendering. These traces were introduced in Plotly.py 5.24 and are now the recommended way to create tile-based choropleth maps. There are also choropleth traces that use [Mapbox](https://docs.mapbox.com): `px.choropleth_mapbox` and `go.Choroplethmapbox` -To plot on Mapbox maps with Plotly you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](/python/mapbox-layers/) documentation for more information. +To plot on Mapbox maps with Plotly you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](mapbox-layers.md) documentation for more information. Here's an exmaple of using the Mapbox Light base map, which requires a free token. diff --git a/doc/python/tile-map-layers.md b/doc/python/tile-map-layers.md index a60ec6646d7..197de4534a6 100644 --- a/doc/python/tile-map-layers.md +++ b/doc/python/tile-map-layers.md @@ -48,7 +48,7 @@ If your figure is created with a `px.scatter_map`, `px_scatter_mapbox`, `px.line Geo maps are outline-based maps. If your figure is created with a `px.scatter_geo`, `px.line_geo` or `px.choropleth` function or otherwise contains one or more traces of type `go.Scattergeo` or `go.Choropleth`, the `layout.geo` object in your figure contains configuration information for the map itself. -> This page documents tile-based maps, and the [Geo map documentation](/python/map-configuration/) describes how to configure outline-based maps. +> This page documents tile-based maps, and the [Geo map documentation](map-configuration.md) describes how to configure outline-based maps. ## Tile Map Renderers diff --git a/doc/python/tile-scatter-maps.md b/doc/python/tile-scatter-maps.md index 69996cea08f..8e50a2e6d9e 100644 --- a/doc/python/tile-scatter-maps.md +++ b/doc/python/tile-scatter-maps.md @@ -36,9 +36,9 @@ jupyter: ### Basic example with Plotly Express -Here we show the [Plotly Express](/python/plotly-express/) function `px.scatter_map` for a scatter plot on a tile map. +Here we show the [Plotly Express](plotly-express.md) function `px.scatter_map` for a scatter plot on a tile map. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px @@ -298,7 +298,7 @@ fig.show() The earlier examples using `px.scatter_map` and `go.Scattermap` use [Maplibre](https://maplibre.org/maplibre-gl-js/docs/) for rendering. These traces were introduced in Plotly.py 5.24 and are now the recommended way to create scatter plots on tile-based maps. There are also traces that use [Mapbox](https://docs.mapbox.com): `px.scatter_mapbox` and `go.Scattermapbox` -To plot on Mapbox maps with Plotly you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](/python/mapbox-layers/) documentation for more information. +To plot on Mapbox maps with Plotly you _may_ need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](mapbox-layers.md) documentation for more information. Here's the first example rewritten to use `px.scatter_mapbox`. diff --git a/doc/python/time-series.md b/doc/python/time-series.md index bc3ee71df17..49d465137c0 100644 --- a/doc/python/time-series.md +++ b/doc/python/time-series.md @@ -35,9 +35,9 @@ jupyter: ### Time Series using Axes of type `date` -Time series can be represented using either `plotly.express` functions (`px.line`, `px.scatter`, `px.bar` etc) or `plotly.graph_objects` charts objects (`go.Scatter`, `go.Bar` etc). For more examples of such charts, see the documentation of [line and scatter plots](https://plotly.com/python/line-and-scatter/) or [bar charts](/python/bar-charts/). +Time series can be represented using either `plotly.express` functions (`px.line`, `px.scatter`, `px.bar` etc) or `plotly.graph_objects` charts objects (`go.Scatter`, `go.Bar` etc). For more examples of such charts, see the documentation of [line and scatter plots](https://plotly.com/python/line-and-scatter/) or [bar charts](bar-charts.md). -For financial applications, Plotly can also be used to create [Candlestick charts](/python/candlestick-charts/) and [OHLC charts](/python/ohlc-charts/), which default to date axes. +For financial applications, Plotly can also be used to create [Candlestick charts](candlestick-charts.md) and [OHLC charts](ohlc-charts.md), which default to date axes. Plotly auto-sets the axis type to a date format when the corresponding data are either ISO-formatted date strings or if they're a [date pandas column](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html) or [datetime NumPy array](https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html). @@ -90,7 +90,7 @@ fig = px.bar(df, x=df.index, y="GOOG") fig.show() ``` -Or this [facetted](/python/facet-plots/) area plot: +Or this [facetted](facet-plots.md) area plot: ```python import plotly.express as px @@ -106,7 +106,7 @@ By default, the tick labels (and optional ticks) are associated with a specific Date axis tick labels have the special property that any portion after the first instance of `'\n'` in `tickformat` will appear on a second line only once per unique value, as with the year numbers in the example below. To have the year number appear on every tick label, `'
'` should be used instead of `'\n'`. -Note that by default, the formatting of values of X and Y values in the hover label matches that of the tick labels of the corresponding axes, so when customizing the tick labels to something broad like "month", it's usually necessary to [customize the hover label](/python/hover-text-and-formatting/) to something narrower like the actual date, as below. +Note that by default, the formatting of values of X and Y values in the hover label matches that of the tick labels of the corresponding axes, so when customizing the tick labels to something broad like "month", it's usually necessary to [customize the hover label](hover-text-and-formatting.md) to something narrower like the actual date, as below. ```python import plotly.express as px @@ -190,7 +190,7 @@ fig.show() ### Summarizing Time-series Data with Histograms -Plotly [histograms](/python/histograms/) are powerful data-aggregation tools which even work on date axes. In the figure below, we pass in daily data and display it as monthly averages by setting `histfunc="avg` and `xbins_size="M1"`. +Plotly [histograms](histograms.md) are powerful data-aggregation tools which even work on date axes. In the figure below, we pass in daily data and display it as monthly averages by setting `histfunc="avg` and `xbins_size="M1"`. ```python import plotly.express as px diff --git a/doc/python/tree-plots.md b/doc/python/tree-plots.md index ba44146673d..77f354bb0f1 100644 --- a/doc/python/tree-plots.md +++ b/doc/python/tree-plots.md @@ -37,8 +37,8 @@ jupyter: Install igraph with `pip install igraph`. -```python -!pip install igraph +``` +$ pip install igraph ``` ```python diff --git a/doc/python/treemaps.md b/doc/python/treemaps.md index 6671698cb93..31e61c8cd70 100644 --- a/doc/python/treemaps.md +++ b/doc/python/treemaps.md @@ -37,7 +37,7 @@ jupyter: ### Basic Treemap with plotly.express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). With `px.treemap`, each row of the DataFrame is represented as a sector of the treemap. @@ -109,7 +109,7 @@ fig.show() ### Using an explicit mapping for discrete colors -For more information about discrete colors, see the [dedicated page](/python/discrete-color). +For more information about discrete colors, see the [dedicated page](discrete-color.md). ```python import plotly.express as px @@ -164,7 +164,7 @@ fig.show() ### Basic Treemap with go.Treemap -If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Treemap` class from `plotly.graph_objects`](/python/graph-objects/). +If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Treemap` class from `plotly.graph_objects`](graph-objects.md). ```python import plotly.graph_objects as go @@ -428,7 +428,7 @@ fig.show() *New in 5.15* -Treemap charts support [patterns](/python/pattern-hatching-texture/) (also known as hatching or texture) in addition to color. In this example, we apply a pattern to the root node. +Treemap charts support [patterns](pattern-hatching-texture.md) (also known as hatching or texture) in addition to color. In this example, we apply a pattern to the root node. ```python import plotly.graph_objects as go diff --git a/doc/python/trisurf.md b/doc/python/trisurf.md index 30a6e0edaa7..06f1c844fc8 100644 --- a/doc/python/trisurf.md +++ b/doc/python/trisurf.md @@ -33,7 +33,7 @@ jupyter: thumbnail: thumbnail/trisurf.jpg --- -Trisurf plots can be made using a [figure factory](/python/figure-factories/) as detailed in this page. +Trisurf plots can be made using a [figure factory](figure-factories.md) as detailed in this page. #### Torus diff --git a/doc/python/troubleshooting.md b/doc/python/troubleshooting.md index 09c274e3e60..166fe2f7de9 100644 --- a/doc/python/troubleshooting.md +++ b/doc/python/troubleshooting.md @@ -37,13 +37,13 @@ jupyter: ### Version Problems -In order to follow the examples in this documentation site, you should have the latest version of `plotly` installed (5.x), as detailed in the [Getting Started](/python/getting-started) guide. This documentation (under https://plotly.com/python) is compatible with `plotly` version 4.x but *not* with version 3.x, for which the documentation is available under https://plotly.com/python/v3. In general you must also have the correct version of the underlying Plotly.js rendering engine installed, and the way to do that depends on the environment in which you are rendering figures: Dash, Jupyter Lab or Classic Notebook, VSCode etc. Read on for details about troubleshooting `plotly` in these environments. +In order to follow the examples in this documentation site, you should have the latest version of `plotly` installed (5.x), as detailed in the [Getting Started](getting-started.md) guide. This documentation (under https://plotly.com/python) is compatible with `plotly` version 4.x but *not* with version 3.x, for which the documentation is available under https://plotly.com/python/v3. In general you must also have the correct version of the underlying Plotly.js rendering engine installed, and the way to do that depends on the environment in which you are rendering figures: Dash, Jupyter Lab or Classic Notebook, VSCode etc. Read on for details about troubleshooting `plotly` in these environments. ### Import Problems It's very important that you not have a file named `plotly.py` in the same directory as the Python script you're running, and this includes not naming the script itself `plotly.py`, otherwise importing `plotly` can fail with mysterious error messages. -Beyond this, most `import` problems or `AttributeError`s can be traced back to having multiple versions of `plotly` installed, for example once with `conda` and once with `pip`. It's often worthwhile to uninstall with both methods before following the [Getting Started](/python/getting-started) instructions from scratch with one or the other. You can run the following commands in a terminal to fully remove `plotly` before installing again: +Beyond this, most `import` problems or `AttributeError`s can be traced back to having multiple versions of `plotly` installed, for example once with `conda` and once with `pip`. It's often worthwhile to uninstall with both methods before following the [Getting Started](getting-started.md) instructions from scratch with one or the other. You can run the following commands in a terminal to fully remove `plotly` before installing again: ```bash $ conda uninstall plotly @@ -77,7 +77,7 @@ The situation is similar for environments like Nteract and Streamlit: in these e ### Orca Problems -> Orca support in Plotly.py is deprecated and will be removed after September 2025. See the [Static Image Export page](/python/static-image-export/) for details on using Kaleido for static image generation. +> Orca support in Plotly.py is deprecated and will be removed after September 2025. See the [Static Image Export page](static-image-export.md) for details on using Kaleido for static image generation. If you get an error message stating that the `orca` executable that was found is not valid, this may be because another executable with the same name was found on your system. Please specify the complete path to the Plotly-Orca binary that you downloaded (for instance in the Miniconda folder) with the following command: diff --git a/doc/python/v4-migration.md b/doc/python/v4-migration.md index 459b35d4037..4cb90ca2a55 100644 --- a/doc/python/v4-migration.md +++ b/doc/python/v4-migration.md @@ -35,7 +35,7 @@ jupyter: ### Upgrading to Version 4 -Upgrading to version 4 of `plotly` is a matter of following the instructions in the [Getting Started](/python/getting-started/) guide and reinstalling the packages, subject to the notices below. +Upgrading to version 4 of `plotly` is a matter of following the instructions in the [Getting Started](getting-started.md) guide and reinstalling the packages, subject to the notices below. ### Getting Help @@ -81,7 +81,7 @@ Similarly, ### Offline features (`plotly.offline`) replaced by Renderers framework & HTML export -Version 4 introduces a new renderers framework that is a generalization of version 3's `plotly.offline.init_notebook_mode` and `plotly.offline.iplot` functions for displaying figures. *This is a non-breaking change*: the `plotly.offline.iplot` function is still available and has been reimplemented on top of the renderers framework, so no changes are required when porting to version 4. Going forward, we recommend using the renderers framework directly. See [Displaying plotly figures](/python/renderers) for more information. +Version 4 introduces a new renderers framework that is a generalization of version 3's `plotly.offline.init_notebook_mode` and `plotly.offline.iplot` functions for displaying figures. *This is a non-breaking change*: the `plotly.offline.iplot` function is still available and has been reimplemented on top of the renderers framework, so no changes are required when porting to version 4. Going forward, we recommend using the renderers framework directly. See [Displaying plotly figures](renderers.md) for more information. In version 3, the `plotly.offline.plot` function was used to export figures to HTML files. In version 4, this function has been reimplemented on top of the new `to_html` and `write_html` functions from the `plotly.io` module. These functions have a slightly more consistent API (see docstrings for details), and going forward we recommend using them directly when performing HTML export. When working with a graph object figure, these functions are also available as the `.to_html` and `.write_html` figure methods. @@ -160,7 +160,7 @@ fig.show() pio.templates.default = "plotly" ``` -See [Theming and templates](/python/templates) for more information on theming in plotly.py version 4. +See [Theming and templates](templates.md) for more information on theming in plotly.py version 4. ### Add trace return value In version 3, the `add_trace` graph object figure method returned a reference to the newly created trace. This was also the case for the `add_{trace_type}` methods (e.g. `add_scatter`, `add_bar`, etc.). In version 4, these methods return a reference to the calling figure. This change was made to support method chaining of figure operations. For example @@ -286,7 +286,7 @@ pio.orca.config.use_xvfb = False The `fileopt` argument to `chart_studio.plotly.plot` has been removed, so in-place modifications to previously published figures are no longer supported. #### Legacy online `GraphWidget` -The legacy online-only `GraphWidget` class has been removed. Please use the `plotly.graph_objects.FigureWidget` class instead. See the [Figure Widget Overview](/python/figurewidget/) for more information. +The legacy online-only `GraphWidget` class has been removed. Please use the `plotly.graph_objects.FigureWidget` class instead. See the [Figure Widget Overview](figurewidget.md) for more information. ### Recommended style updates diff --git a/doc/python/v6-changes.md b/doc/python/v6-changes.md index fe18e674205..7572df71f96 100644 --- a/doc/python/v6-changes.md +++ b/doc/python/v6-changes.md @@ -57,7 +57,7 @@ pip install anywidget Plotly.py now takes advantage of recent changes in how Plotly.js handles typed arrays for improved performance. See the [performance page](https://plotly.com/python/performance/) for more details. -> If you are using Plotly.py 6 or later with Dash Design Kit, you may need to upgrade your Dash Design Kit version. See the [Dash Design Kit Compatibility section on the performance page](/python/performance/#dash-design-kit-compatibility) for more details. +> If you are using Plotly.py 6 or later with Dash Design Kit, you may need to upgrade your Dash Design Kit version. See the [Dash Design Kit Compatibility section on the performance page](performance.md#dash-design-kit-compatibility) for more details. ## Dataframe Support @@ -109,12 +109,12 @@ The following traces have been removed. ### `heatmapgl` -The `heatmapgl` trace has been removed. Use [`heatmap`](/python/heatmaps/) instead. +The `heatmapgl` trace has been removed. Use [`heatmap`](heatmaps.md) instead. ### `pointcloud` -The `pointcloud` trace has been removed. Use [`scattergl`](/python/reference/scattergl/). +The `pointcloud` trace has been removed. Use [`scattergl`](/reference/scattergl.md). diff --git a/doc/python/violin.md b/doc/python/violin.md index 0e0e86cdd1b..ce586f8e89f 100644 --- a/doc/python/violin.md +++ b/doc/python/violin.md @@ -46,7 +46,7 @@ Alternatives to violin plots for visualizing distributions include [histograms]( ### Basic Violin Plot with Plotly Express -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python @@ -93,7 +93,7 @@ fig.show() ## Violin Plot with go.Violin -If Plotly Express does not provide a good starting point, you can use [the more generic `go.Violin` class from `plotly.graph_objects`](/python/graph-objects/). All the options of `go.Violin` are documented in the reference https://plotly.com/python/reference/violin/ +If Plotly Express does not provide a good starting point, you can use [the more generic `go.Violin` class from `plotly.graph_objects`](graph-objects.md). All the options of `go.Violin` are documented in the reference https://plotly.com/python/reference/violin/ #### Basic Violin Plot @@ -265,7 +265,7 @@ fig.show() ### Violin Plot With Only Points -A [strip chart](/python/strip-charts/) is like a violin plot with points showing, and no violin: +A [strip chart](strip-charts.md) is like a violin plot with points showing, and no violin: ```python import plotly.express as px diff --git a/doc/python/wide-form.md b/doc/python/wide-form.md index 88d9c08865a..0aea180af21 100644 --- a/doc/python/wide-form.md +++ b/doc/python/wide-form.md @@ -36,9 +36,9 @@ jupyter: ### Plotly Express works with Column-oriented, Matrix or Geographic Data -Plotly Express provides functions to visualize a variety of types of data. Most functions such as `px.bar` or `px.scatter` expect to operate on column-oriented data of the type you might store in a `DataFrame` (in either "long" or "wide" format, see below). These functions use Pandas internally to process the data, but also accept other types of DataFrames as arguments. See the [Plotly Express arguments page](/python/px-arguments/) for more details. +Plotly Express provides functions to visualize a variety of types of data. Most functions such as `px.bar` or `px.scatter` expect to operate on column-oriented data of the type you might store in a `DataFrame` (in either "long" or "wide" format, see below). These functions use Pandas internally to process the data, but also accept other types of DataFrames as arguments. See the [Plotly Express arguments page](px-arguments.md) for more details. -[`px.imshow` operates on matrix-like data](/python/imshow/) you might store in a `numpy` or `xarray` array and functions like [`px.choropleth` and `px.choropleth_mapbox` can operate on geographic data](/python/maps/) of the kind you might store in a GeoPandas `GeoDataFrame`. This page details how to provide a specific form of column-oriented data to 2D-Cartesian Plotly Express functions, but you can also check out our [detailed column-input-format documentation](/python/px-arguments/). +[`px.imshow` operates on matrix-like data](imshow.md) you might store in a `numpy` or `xarray` array and functions like [`px.choropleth` and `px.choropleth_mapbox` can operate on geographic data](/maps/) of the kind you might store in a GeoPandas `GeoDataFrame`. This page details how to provide a specific form of column-oriented data to 2D-Cartesian Plotly Express functions, but you can also check out our [detailed column-input-format documentation](px-arguments.md). ### Plotly Express works with Long-, Wide-, and Mixed-Form Data @@ -88,7 +88,7 @@ fig.show() ### Labeling axes, legends and hover text -You might notice that y-axis and legend labels are slightly different for the second plot: they are "value" and "variable", respectively, and this is also reflected in the hoverlabel text. This is because Plotly Express performed an [internal Pandas `melt()` operation](https://pandas.pydata.org/docs/reference/api/pandas.melt.html) to convert the wide-form data into long-form for plotting, and used the Pandas convention for assign column names to the intermediate long-form data. Note that the labels "medal" and "count" do not appear in the wide-form data frame, so in this case, you must supply these yourself, (or see below regarding using a data frame with named row- and column-indexes). You can [rename these labels with the `labels` argument](/python/styling-plotly-express/): +You might notice that y-axis and legend labels are slightly different for the second plot: they are "value" and "variable", respectively, and this is also reflected in the hoverlabel text. This is because Plotly Express performed an [internal Pandas `melt()` operation](https://pandas.pydata.org/docs/reference/api/pandas.melt.html) to convert the wide-form data into long-form for plotting, and used the Pandas convention for assign column names to the intermediate long-form data. Note that the labels "medal" and "count" do not appear in the wide-form data frame, so in this case, you must supply these yourself, (or see below regarding using a data frame with named row- and column-indexes). You can [rename these labels with the `labels` argument](styling-plotly-express.md): ```python import plotly.express as px @@ -99,7 +99,7 @@ fig = px.bar(wide_df, x="nation", y=["gold", "silver", "bronze"], title="Wide-Fo fig.show() ``` -Plotly Express figures created using wide-form data can be [styled just like any other Plotly Express figure](/python/styling-plotly-express/): +Plotly Express figures created using wide-form data can be [styled just like any other Plotly Express figure](styling-plotly-express.md): ```python import plotly.express as px @@ -190,7 +190,7 @@ mixed_df = px.data.experiment(indexed=True) mixed_df.head() ``` -We can visualize just the wide-form portion of the data frame easily with a [violin chart](/python/violin/). As a special note, we'll assign the index, which is the participant ID, to the `hover_data`, so that hovering over outlier points will identify their row. +We can visualize just the wide-form portion of the data frame easily with a [violin chart](violin.md). As a special note, we'll assign the index, which is the participant ID, to the `hover_data`, so that hovering over outlier points will identify their row. ```python import plotly.express as px @@ -214,7 +214,7 @@ fig = px.violin(mixed_df, y=["experiment_1", "experiment_2", "experiment_3"], fig.show() ``` -In the plots above, the column names provided to `y` are internally mapped to long-form column called `variable`, as is apparent in the x-axis labels. We can reassign `variable` to another argument as well, in this case we'll assign it to `facet_col` and reassign `group` to the `x` axis. We'll switch to a [box plot](/python/box-plots/) for variety. +In the plots above, the column names provided to `y` are internally mapped to long-form column called `variable`, as is apparent in the x-axis labels. We can reassign `variable` to another argument as well, in this case we'll assign it to `facet_col` and reassign `group` to the `x` axis. We'll switch to a [box plot](box-plots.md) for variety. ```python import plotly.express as px @@ -236,7 +236,7 @@ fig = px.scatter(mixed_df, x="experiment_1", y="experiment_2", fig.show() ``` -In fact, we can even visualize the results of every experiment against every other, using a [scatterplot matrix](/python/splom/): +In fact, we can even visualize the results of every experiment against every other, using a [scatterplot matrix](splom.md): ```python import plotly.express as px diff --git a/doc/python/wind-rose-charts.md b/doc/python/wind-rose-charts.md index 40fd2aa87ce..ed50294fa0b 100644 --- a/doc/python/wind-rose-charts.md +++ b/doc/python/wind-rose-charts.md @@ -38,7 +38,7 @@ jupyter: A [wind rose chart](https://en.wikipedia.org/wiki/Wind_rose) (also known as a polar bar chart) is a graphical tool used to visualize how wind speed and direction are typically distributed at a given location. You can use the `px.bar_polar` function from Plotly Express as below, otherwise use `go.Barpolar` as explained in the next section. -[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). ```python import plotly.express as px diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index b7b9ba9bcbc..00000000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,48 +0,0 @@ -plotly==6.3.0 -anywidget -cufflinks==0.17.3 -dash-bio -dask==2022.2.0 -datashader==0.14.4 -geopandas==0.8.1 -geoparse<=2.0.3 -igraph -jinja2<3.1 -jupyter -jupyter-client<7 -jupytext==1.16.4 -kaleido -nbconvert==5.6.1 -networkx==2.8.0 -notebook -numpy==1.22.4 -orjson -pandas==1.4.0 -pathlib -patsy==0.5.6 -plotly-geo -polars -pooch -psutil -pyarrow -pyshp==2.1.2 -python-frontmatter -recommonmark -requests -scikit-image==0.20.0 -scikit-learn -scipy==1.9.1 -shapely==2.0.5 -sphinx==3.5.4 -sphinx_bootstrap_theme -sphinxcontrib-applehelp==1.0.2 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 -squarify -statsmodels==0.14.2 -umap-learn==0.5.1 -wget -xarray==2022.9.0 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000000..6bdba12d714 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,219 @@ +site_name: "Plotly.py Docs" +docs_dir: pages +site_dir: docs + +plugins: + - search + - gen-files: + scripts: + - bin/generate_reference_pages.py + - literate-nav: + nav_file: SUMMARY.md + - mkdocstrings: + handlers: + python: + options: + preload_modules: + - _plotly_utils + docstring_style: numpy + show_source: false + show_root_heading: true + show_root_toc_entry: true + merge_init_into_class: true + +extra_css: + - css/plotly-styles.css + +nav: +- Home: index.md +- Getting Started: examples/getting-started.md +- 3d_charts: + - 3D Axes: examples/3d-axes.md + - 3D Scatter Plots: examples/3d-scatter-plots.md + - 3D Surface Plots: examples/3d-surface-plots.md + - 3D Subplots: examples/3d-subplots.md + - 3D Camera Controls: examples/3d-camera-controls.md + - 3D Bubble Charts: examples/3d-bubble-charts.md + - 3D Line Plots: examples/3d-line-plots.md + - Trisurf Plots: examples/trisurf.md + - 3D Mesh Plots: examples/3d-mesh.md + - 3D Isosurface Plots: examples/3d-isosurface-plots.md + - 3D Volume Plots: examples/3d-volume.md + - 3D Cone Plots: examples/cone-plot.md + - 3D Streamtube Plots: examples/streamtube-plot.md +- advanced_opt: + - Plot CSV Data: examples/plot-data-from-csv.md + - Random Walk: examples/random-walk.md + - Peak Finding: examples/peak-finding.md + - Smoothing: examples/smoothing.md + - LaTeX: examples/LaTeX.md +- ai_ml: + - ML Regression: examples/ml-regression.md + - kNN Classification: examples/ml-knn.md + - ROC and PR Curves: examples/ml-roc-pr.md + - PCA Visualization: examples/ml-pca.md + - AI/ML Apps with Dash: https://plotly.com/building-machine-learning-web-apps-in-python/ + - t-SNE and UMAP projections: examples/ml-tsne-umap-projections.md +- animations: + - Intro to Animations: examples/animations.md +- basic: + - Scatter Plots: examples/line-and-scatter.md + - Line Charts: examples/line-charts.md + - Bar Charts: examples/bar-charts.md + - Pie Charts: examples/pie-charts.md + - Bubble Charts: examples/bubble-charts.md + - Dot Plots: examples/dot-plots.md + - Filled Area Plots: examples/filled-area-plots.md + - Horizontal Bar Charts: examples/horizontal-bar-charts.md + - Gantt Charts: examples/gantt.md + - Sunburst Charts: examples/sunburst-charts.md + - Tables: examples/table.md + - Sankey Diagram: examples/sankey-diagram.md + - Treemap Charts: examples/treemaps.md + - High Performance Visualization: examples/performance.md + - Figure Factory Tables: examples/figure-factory-table.md + - Categorical Axes: examples/categorical-axes.md + - Icicle Charts: examples/icicle-charts.md + - Patterns, Hatching, Texture: examples/pattern-hatching-texture.md + - Dumbbell Plots: examples/dumbbell-plots.md +- bio: + - Alignment Chart: examples/bio-alignment-chart.md + - Clustergram: examples/bio-clustergram.md + - Manhattan Plot: examples/bio-manhattanplot.md + - Volcano Plot: examples/bio-volcano-plot.md +- chart_events: + - Plotly FigureWidget Overview: examples/figurewidget.md + - Jupyter Lab with FigureWidget: examples/jupyter-lab-tools.md + - Interactive Data Analysis with FigureWidget ipywidgets: examples/figurewidget-app.md + - Click Events: examples/click-events.md +- controls: + - Custom Buttons: examples/custom-buttons.md + - Sliders: examples/sliders.md + - Dropdown Menus: examples/dropdowns.md + - Range Slider and Selector: examples/range-slider.md +- fundamentals: + - The Figure Data Structure: examples/figure-structure.md + - Creating and Updating Figures: examples/creating-and-updating-figures.md + - Displaying Figures: examples/renderers.md + - Plotly Express: examples/plotly-express.md + - Analytical Apps with Dash: https://dash.plotly.com/ + - Static Image Export: examples/static-image-export.md + - Theming and templates: examples/templates.md + - Changes in Version 6: examples/v6-changes.md + - Orca Management: examples/orca-management.md + - Configuration: examples/configuration-options.md + - Setting Graph Size: examples/setting-graph-size.md + - Formatting Ticks: examples/tick-formatting.md + - Setting the Font, Title, Legend Entries, and Axis Titles: examples/figure-labels.md + - Axes: examples/axes.md + - Legends: examples/legend.md + - Multiple Axes: examples/multiple-axes.md + - Subplots: examples/subplots.md + - Multiple Chart Types: examples/graphing-multiple-chart-types.md + - Plotly Express Arguments: examples/px-arguments.md + - Styling Markers: examples/marker-style.md + - Continuous Color Scales and Color Bars: examples/colorscales.md + - Text and Annotations: examples/text-and-annotations.md + - Hover Text and Formatting: examples/hover-text-and-formatting.md + - Images: examples/images.md + - Shapes: examples/shapes.md + - IPython vs Python: examples/ipython-vs-python.md + - Troubleshooting: examples/troubleshooting.md + - Built-in Continuous Color Scales: examples/builtin-colorscales.md + - Discrete Colors: examples/discrete-color.md + - Styling Plotly Express Figures: examples/styling-plotly-express.md + - Interactive HTML Export: examples/interactive-html-export.md + - Pandas Plotting Backend: examples/pandas-backend.md + - Figure Factories: examples/figure-factories.md + - Plotly Express Wide-Form Support: examples/wide-form.md + - Graph Objects: examples/graph-objects.md + - Introspecting Figures: examples/figure-introspection.md + - Horizontal and Vertical Lines and Rectangles: examples/horizontal-vertical-shapes.md + - Selections: examples/selections.md + - Version 4 Migration Guide: examples/v4-migration.md + - Static Image Generation Changes in Plotly.py 6.1: examples/static-image-generation-migration.md + - Supported CSS Colors: examples/supported-colors.md +- financial: + - Time Series and Date Axes: examples/time-series.md + - Candlestick Charts: examples/candlestick-charts.md + - Waterfall Charts: examples/waterfall-charts.md + - Funnel Chart: examples/funnel-charts.md + - OHLC Charts: examples/ohlc-charts.md + - Indicators: examples/indicator.md + - Gauge Charts: examples/gauge-charts.md + - Bullet Charts: examples/bullet-charts.md +- maps: + - MapLibre Migration: examples/migrate-to-maplibre.md + - Tile Choropleth Maps: examples/tile-county-choropleth.md + - Lines on Tile Maps: examples/lines-on-tile-maps.md + - Filled Area on Tile Maps: examples/filled-area-tile-maps.md + - Bubble Maps: examples/bubble-maps.md + - Density Heatmap: examples/density-heatmaps.md + - Lines on Maps: examples/lines-on-maps.md + - Choropleth Maps: examples/choropleth-maps.md + - Tile Map Layers: examples/tile-map-layers.md + - Scatter Plots on Tile Maps: examples/tile-scatter-maps.md + - USA County Choropleth Maps: examples/county-choropleth.md + - Scatter Plots on Maps: examples/scatter-plots-on-maps.md + - Map Configuration and Styling on Geo Maps: examples/map-configuration.md + - Hexbin Mapbox: examples/hexbin-mapbox.md +- multiple_axes: + - Mixed Subplots: examples/mixed-subplots.md + - Map Subplots: examples/map-subplots-and-small-multiples.md + - Table and Chart Subplots: examples/table-subplots.md + - Figure Factory Subplots: examples/figure-factory-subplots.md +- scientific: + - Contour Plots: examples/contour-plots.md + - Heatmaps: examples/heatmaps.md + - Imshow: examples/imshow.md + - Ternary Plots: examples/ternary-plots.md + - Log Plots: examples/log-plot.md + - Dendrograms: examples/dendrogram.md + - Annotated Heatmaps: examples/annotated-heatmap.md + - Ternary Overlay: examples/ternary-scatter-contour.md + - Parallel Coordinates Plot: examples/parallel-coordinates-plot.md + - Quiver Plots: examples/quiver-plots.md + - Streamline Plots: examples/streamline-plots.md + - Network Graphs: examples/network-graphs.md + - Carpet Plots: examples/carpet-plot.md + - Carpet Contour Plot: examples/carpet-contour.md + - Carpet Scatter Plot: examples/carpet-scatter.md + - Polar Charts: examples/polar-chart.md + - Radar Charts: examples/radar-chart.md + - Ternary contours: examples/ternary-contour.md + - Wind Rose and Polar Bar Charts: examples/wind-rose-charts.md + - Smith Charts: examples/smith-charts.md +- statistical: + - Error Bars: examples/error-bars.md + - Box Plots: examples/box-plots.md + - Histograms: examples/histograms.md + - Distplots: examples/distplot.md + - 2D Histograms: examples/2D-Histogram.md + - Scatterplot Matrix: examples/splom.md + - Facet and Trellis Plots: examples/facet-plots.md + - Parallel Categories Diagram: examples/parallel-categories-diagram.md + - Tree-plots: examples/tree-plots.md + - Violin Plots: examples/violin.md + - 2D Histogram Contour: examples/2d-histogram-contour.md + - Linear and Non-Linear Trendlines: examples/linear-fits.md + - Marginal Distribution Plots: examples/marginal-plots.md + - Strip Charts: examples/strip-charts.md + - Continuous Error Bands: examples/continuous-error-bars.md + - Empirical Cumulative Distribution Plots: examples/ecdf-plots.md +- API Reference: reference/ +- Project: + - license.md + - conduct.md + - contributing.md + +theme: + name: "material" + +markdown_extensions: +- def_list +- markdown_include.include: + base_path: docs +- footnotes + +exclude_docs: > + *~ diff --git a/notes.txt b/notes.txt new file mode 100644 index 00000000000..c8c6d9533ae --- /dev/null +++ b/notes.txt @@ -0,0 +1,17 @@ +1. Replace (almost) all imports of `plotly.graph_objs` with `plotly.graph_objects` in `tests/**/*.py`. + - Done. +2. Move plotly/graph_objects to ./tmp; rename plotly/graph_objs and plotly/graph_objects; move ./tmp to plotly/graph_objs. +3. Replace all instances of `graph_objs` with `graph_objects` in `bin/codegen/*.py`. + - `sed -I .bak -e 's/graph_objs/graph_objects/g' bin/codegen/*.py` + - `rm bin/codegen/*.bak` +4. Delete `plotly.graph_objects` and run `make generate` to regenerate. +5. Try `python -m pytest tests/test_import.py`. + +---------------------------------------- + +- Can we get rid of `plotly/api` entirely? +- Can we eliminate `plotly/conftest.py` and fix breaking tests? +- Why the distinction between `graph_objects` and `graph_objs`? + - Historical reasons, but `graph_objs` is widely used. + - Generate code into `graph_objects` and have `graph_objs` point at it + instead of vice versa. diff --git a/pages/conduct.md b/pages/conduct.md new file mode 100644 index 00000000000..14a6a4a839a --- /dev/null +++ b/pages/conduct.md @@ -0,0 +1 @@ +{!../CODE_OF_CONDUCT.md!} diff --git a/pages/contributing.md b/pages/contributing.md new file mode 100644 index 00000000000..568877b4a4f --- /dev/null +++ b/pages/contributing.md @@ -0,0 +1 @@ +{!../CONTRIBUTING.md!} diff --git a/pages/css/plotly-styles.css b/pages/css/plotly-styles.css new file mode 100644 index 00000000000..089452035eb --- /dev/null +++ b/pages/css/plotly-styles.css @@ -0,0 +1,30 @@ +/* Plotly Custom Colors */ + +/* Define the custom primary color scheme */ +[data-md-color-primary="custom"] { + --md-primary-fg-color: #6E56CF; + --md-primary-fg-color--light: #8B72D9; + --md-primary-fg-color--dark: #5A47B8; + --md-primary-bg-color: #FFFFFF; + --md-primary-bg-color--light: #F8F7FD; + } + + /* Define the custom accent color scheme */ + [data-md-color-accent="custom"] { + --md-accent-fg-color: #6E56CF; + --md-accent-fg-color--transparent: rgba(110, 86, 207, 0.1); + --md-accent-bg-color: #FFFFFF; + --md-accent-bg-color--light: #F8F7FD; + } + + /* Additional custom properties for consistency */ + :root { + --md-primary-fg-color: orange; + --plotly-primary: #6E56CF; + --plotly-primary-light: #8B72D9; + --plotly-primary-dark: #5A47B8; + --plotly-primary-alpha-10: rgba(110, 86, 207, 0.1); + --plotly-primary-alpha-20: rgba(110, 86, 207, 0.2); + } + + \ No newline at end of file diff --git a/pages/examples/2D-Histogram.md b/pages/examples/2D-Histogram.md new file mode 100644 index 00000000000..2f2e0d5e596 --- /dev/null +++ b/pages/examples/2D-Histogram.md @@ -0,0 +1,349 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.13.4 + kernelspec: + display_name: Python 3 + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.8.11 + plotly: + description: How to make 2D Histograms in Python with Plotly. + display_as: statistical + language: python + layout: base + name: 2D Histograms + order: 5 + page_type: u-guide + permalink: python/2D-Histogram/ + redirect_from: + - python/2d-histogram/ + - python/2d-histograms/ + thumbnail: thumbnail/histogram2d.jpg +--- + +## 2D Histograms or Density Heatmaps + +A 2D histogram, also known as a density heatmap, is the 2-dimensional generalization of a [histogram](histograms.md) which resembles a [heatmap](heatmaps.md) but is computed by grouping a set of points specified by their `x` and `y` coordinates into bins, and applying an aggregation function such as `count` or `sum` (if `z` is provided) to compute the color of the tile representing the bin. This kind of visualization (and the related [2D histogram contour, or density contour](https://plotly.com/python/2d-histogram-contour/)) is often used to manage over-plotting, or situations where showing large data sets as [scatter plots](line-and-scatter.md) would result in points overlapping each other and hiding patterns. For data sets of more than a few thousand points, a better approach than the ones listed here would be to [use Plotly with Datashader](datashader.md) to precompute the aggregations before displaying the data with Plotly. + +## Density Heatmaps with Plotly Express + +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). The Plotly Express function `density_heatmap()` can be used to produce density heatmaps. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_heatmap(df, x="total_bill", y="tip") +fig.show() +``` + +![Generated Plot](./2D-Histogram_1.png) + +**Interactive Plot:** + +
+
+ +The number of bins can be controlled with `nbinsx` and `nbinsy` and the [color scale](colorscales.md) with `color_continuous_scale`. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_heatmap(df, x="total_bill", y="tip", nbinsx=20, nbinsy=20, color_continuous_scale="Viridis") +fig.show() +``` + +![Generated Plot](./2D-Histogram_2.png) + +**Interactive Plot:** + +
+
+ +Marginal plots can be added to visualize the 1-dimensional distributions of the two variables. Here we use a marginal [`histogram`](histograms.md). Other allowable values are `violin`, `box` and `rug`. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_heatmap(df, x="total_bill", y="tip", marginal_x="histogram", marginal_y="histogram") +fig.show() +``` + +![Generated Plot](./2D-Histogram_3.png) + +**Interactive Plot:** + +
+
+ +Density heatmaps can also be [faceted](facet-plots.md): + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_heatmap(df, x="total_bill", y="tip", facet_row="sex", facet_col="smoker") +fig.show() +``` + +![Generated Plot](./2D-Histogram_4.png) + +**Interactive Plot:** + +
+
+ +### Displaying Text + +*New in v5.5* + +You can add the `z` values as text using the `text_auto` argument. Setting it to `True` will display the values on the bars, and setting it to a `d3-format` formatting string will control the output format. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_heatmap(df, x="total_bill", y="tip", text_auto=True) +fig.show() +``` + +![Generated Plot](./2D-Histogram_5.png) + +**Interactive Plot:** + +
+
+ +### Other aggregation functions than `count` + +By passing in a `z` value and a `histfunc`, density heatmaps can perform basic aggregation operations. Here we show average Sepal Length grouped by Petal Length and Petal Width for the Iris dataset. + +```python +import plotly.express as px +df = px.data.iris() + +fig = px.density_heatmap(df, x="petal_length", y="petal_width", z="sepal_length", histfunc="avg") +fig.show() +``` + +![Generated Plot](./2D-Histogram_6.png) + +**Interactive Plot:** + +
+
+ +### 2D Histograms with Graph Objects + +To build this kind of figure using [graph objects](graph-objects.md) without using Plotly Express, we can use the `go.Histogram2d` class. + + +### 2D Histogram of a Bivariate Normal Distribution ### + +```python +import plotly.graph_objects as go + +import numpy as np +np.random.seed(1) + +x = np.random.randn(500) +y = np.random.randn(500)+1 + +fig = go.Figure(go.Histogram2d( + x=x, + y=y + )) +fig.show() +``` + +![Generated Plot](./2D-Histogram_7.png) + +**Interactive Plot:** + +
+
+ +### 2D Histogram Binning and Styling Options ### + +```python +import plotly.graph_objects as go + +import numpy as np + +x = np.random.randn(500) +y = np.random.randn(500)+1 + +fig = go.Figure(go.Histogram2d(x=x, y=y, histnorm='probability', + autobinx=False, + xbins=dict(start=-3, end=3, size=0.1), + autobiny=False, + ybins=dict(start=-2.5, end=4, size=0.1), + colorscale=[[0, 'rgb(12,51,131)'], [0.25, 'rgb(10,136,186)'], [0.5, 'rgb(242,211,56)'], [0.75, 'rgb(242,143,56)'], [1, 'rgb(217,30,30)']] + )) +fig.show() +``` + +![Generated Plot](./2D-Histogram_8.png) + +**Interactive Plot:** + +
+
+### Sharing bin settings between 2D Histograms +This example shows how to use [bingroup](https://plotly.com/python/reference/histogram/#histogram-bingroup) attribute to have a compatible bin settings for both histograms. To define `start`, `end` and `size` value of x-axis and y-axis separately, set [ybins](https://plotly.com/python/reference/histogram2dcontour/#histogram2dcontour-ybins) and `xbins`. + +```python +import plotly.graph_objects as go +from plotly.subplots import make_subplots + +fig = make_subplots(2,2) +fig.add_trace(go.Histogram2d( + x = [ 1, 2, 2, 3, 4 ], + y = [ 1, 2, 2, 3, 4 ], + coloraxis = "coloraxis", + xbins = {'start':1, 'size':1}), 1,1) +fig.add_trace(go.Histogram2d( + x = [ 4, 5, 5, 5, 6 ], + y = [ 4, 5, 5, 5, 6 ], + coloraxis = "coloraxis", + ybins = {'start': 3, 'size': 1}),1,2) +fig.add_trace(go.Histogram2d( + x = [ 1, 2, 2, 3, 4 ], + y = [ 1, 2, 2, 3, 4 ], + bingroup = 1, + coloraxis = "coloraxis", + xbins = {'start':1, 'size':1}), 2,1) +fig.add_trace(go.Histogram2d( + x = [ 4, 5, 5, 5, 6 ], + y = [ 4, 5, 5, 5, 6 ], + bingroup = 1, + coloraxis = "coloraxis", + ybins = {'start': 3, 'size': 1}),2,2) +fig.show() +``` + +![Generated Plot](./2D-Histogram_9.png) + +**Interactive Plot:** + +
+
+ +### 2D Histogram Overlaid with a Scatter Chart ### + +```python +import plotly.graph_objects as go + +import numpy as np + +x0 = np.random.randn(100)/5. + 0.5 # 5. enforces float division +y0 = np.random.randn(100)/5. + 0.5 +x1 = np.random.rand(50) +y1 = np.random.rand(50) + 1.0 + +x = np.concatenate([x0, x1]) +y = np.concatenate([y0, y1]) + +fig = go.Figure() + +fig.add_trace(go.Scatter( + x=x0, + y=y0, + mode='markers', + showlegend=False, + marker=dict( + symbol='x', + opacity=0.7, + color='white', + size=8, + line=dict(width=1), + ) +)) +fig.add_trace(go.Scatter( + x=x1, + y=y1, + mode='markers', + showlegend=False, + marker=dict( + symbol='circle', + opacity=0.7, + color='white', + size=8, + line=dict(width=1), + ) +)) +fig.add_trace(go.Histogram2d( + x=x, + y=y, + colorscale='YlGnBu', + zmax=10, + nbinsx=14, + nbinsy=14, + zauto=False, +)) + +fig.update_layout( + xaxis=dict( ticks='', showgrid=False, zeroline=False, nticks=20 ), + yaxis=dict( ticks='', showgrid=False, zeroline=False, nticks=20 ), + autosize=False, + height=550, + width=550, + hovermode='closest', + +) + +fig.show() +``` + +![Generated Plot](./2D-Histogram_10.png) + +**Interactive Plot:** + +
+
+ +### Text on 2D Histogram Points + +In this example we add text to 2D Histogram points. We use the values from the `z` attribute for the text. + +```python +import plotly.graph_objects as go +from plotly import data + +df = data.tips() + +fig = go.Figure(go.Histogram2d( + x=df.total_bill, + y=df.tip, + texttemplate= "%{z}" + )) + +fig.show() +``` + +![Generated Plot](./2D-Histogram_11.png) + +**Interactive Plot:** + +
+
+ +#### Reference +See https://plotly.com/python/reference/histogram2d/ for more information and chart attribute options! diff --git a/pages/examples/2D-Histogram_1.html b/pages/examples/2D-Histogram_1.html new file mode 100644 index 00000000000..307f4670c19 --- /dev/null +++ b/pages/examples/2D-Histogram_1.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_1.png b/pages/examples/2D-Histogram_1.png new file mode 100644 index 00000000000..5bed7e161c4 Binary files /dev/null and b/pages/examples/2D-Histogram_1.png differ diff --git a/pages/examples/2D-Histogram_10.html b/pages/examples/2D-Histogram_10.html new file mode 100644 index 00000000000..37657e856e2 --- /dev/null +++ b/pages/examples/2D-Histogram_10.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_10.png b/pages/examples/2D-Histogram_10.png new file mode 100644 index 00000000000..34b20826117 Binary files /dev/null and b/pages/examples/2D-Histogram_10.png differ diff --git a/pages/examples/2D-Histogram_11.html b/pages/examples/2D-Histogram_11.html new file mode 100644 index 00000000000..7335a4b3f4c --- /dev/null +++ b/pages/examples/2D-Histogram_11.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_11.png b/pages/examples/2D-Histogram_11.png new file mode 100644 index 00000000000..93a2ff2b37d Binary files /dev/null and b/pages/examples/2D-Histogram_11.png differ diff --git a/pages/examples/2D-Histogram_2.html b/pages/examples/2D-Histogram_2.html new file mode 100644 index 00000000000..0362eddb61d --- /dev/null +++ b/pages/examples/2D-Histogram_2.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_2.png b/pages/examples/2D-Histogram_2.png new file mode 100644 index 00000000000..c3cf03f7028 Binary files /dev/null and b/pages/examples/2D-Histogram_2.png differ diff --git a/pages/examples/2D-Histogram_3.html b/pages/examples/2D-Histogram_3.html new file mode 100644 index 00000000000..f1c6cc81257 --- /dev/null +++ b/pages/examples/2D-Histogram_3.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_3.png b/pages/examples/2D-Histogram_3.png new file mode 100644 index 00000000000..3ff4dc84c52 Binary files /dev/null and b/pages/examples/2D-Histogram_3.png differ diff --git a/pages/examples/2D-Histogram_4.html b/pages/examples/2D-Histogram_4.html new file mode 100644 index 00000000000..86fac0325c3 --- /dev/null +++ b/pages/examples/2D-Histogram_4.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_4.png b/pages/examples/2D-Histogram_4.png new file mode 100644 index 00000000000..c4df930e9c7 Binary files /dev/null and b/pages/examples/2D-Histogram_4.png differ diff --git a/pages/examples/2D-Histogram_5.html b/pages/examples/2D-Histogram_5.html new file mode 100644 index 00000000000..1b0c5898695 --- /dev/null +++ b/pages/examples/2D-Histogram_5.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_5.png b/pages/examples/2D-Histogram_5.png new file mode 100644 index 00000000000..777300761f5 Binary files /dev/null and b/pages/examples/2D-Histogram_5.png differ diff --git a/pages/examples/2D-Histogram_6.html b/pages/examples/2D-Histogram_6.html new file mode 100644 index 00000000000..f3569f1bc35 --- /dev/null +++ b/pages/examples/2D-Histogram_6.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_6.png b/pages/examples/2D-Histogram_6.png new file mode 100644 index 00000000000..5f8f73c1653 Binary files /dev/null and b/pages/examples/2D-Histogram_6.png differ diff --git a/pages/examples/2D-Histogram_7.html b/pages/examples/2D-Histogram_7.html new file mode 100644 index 00000000000..30376897846 --- /dev/null +++ b/pages/examples/2D-Histogram_7.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_7.png b/pages/examples/2D-Histogram_7.png new file mode 100644 index 00000000000..4d29e2392fb Binary files /dev/null and b/pages/examples/2D-Histogram_7.png differ diff --git a/pages/examples/2D-Histogram_8.html b/pages/examples/2D-Histogram_8.html new file mode 100644 index 00000000000..409efd4b4f8 --- /dev/null +++ b/pages/examples/2D-Histogram_8.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_8.png b/pages/examples/2D-Histogram_8.png new file mode 100644 index 00000000000..b866b84d82f Binary files /dev/null and b/pages/examples/2D-Histogram_8.png differ diff --git a/pages/examples/2D-Histogram_9.html b/pages/examples/2D-Histogram_9.html new file mode 100644 index 00000000000..9794e7563b2 --- /dev/null +++ b/pages/examples/2D-Histogram_9.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2D-Histogram_9.png b/pages/examples/2D-Histogram_9.png new file mode 100644 index 00000000000..d0453affd38 Binary files /dev/null and b/pages/examples/2D-Histogram_9.png differ diff --git a/pages/examples/2d-histogram-contour.md b/pages/examples/2d-histogram-contour.md new file mode 100644 index 00000000000..ffbfa7fe19f --- /dev/null +++ b/pages/examples/2d-histogram-contour.md @@ -0,0 +1,315 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.2' + jupytext_version: 1.3.1 + kernelspec: + display_name: Python 3 + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.6.8 + plotly: + description: How to make 2D Histogram Contour plots in Python with Plotly. + display_as: statistical + language: python + layout: base + name: 2D Histogram Contour + order: 11 + page_type: u-guide + permalink: python/2d-histogram-contour/ + redirect_from: python/2d-density-plots/ + thumbnail: thumbnail/hist2dcontour.png +--- + +## 2D Histogram Contours or Density Contours + +A 2D histogram contour plot, also known as a density contour plot, is a 2-dimensional generalization of a [histogram](histograms.md) which resembles a [contour plot](contour-plots.md) but is computed by grouping a set of points specified by their `x` and `y` coordinates into bins, and applying an aggregation function such as `count` or `sum` (if `z` is provided) to compute the value to be used to compute contours. This kind of visualization (and the related [2D histogram, or density heatmap](2D-Histogram.md)) is often used to manage over-plotting, or situations where showing large data sets as [scatter plots](line-and-scatter.md) would result in points overlapping each other and hiding patterns. + +## Density Contours with Plotly Express + +[Plotly Express](plotly-express.md) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](px-arguments.md) and produces [easy-to-style figures](styling-plotly-express.md). The Plotly Express function `density_contour()` can be used to produce density contours. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_contour(df, x="total_bill", y="tip") +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_1.png) + +**Interactive Plot:** + +
+
+ +Marginal plots can be added to visualize the 1-dimensional distributions of the two variables. Here we use a marginal [`histogram`](histograms.md). Other allowable values are `violin`, `box` and `rug`. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_contour(df, x="total_bill", y="tip", marginal_x="histogram", marginal_y="histogram") +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_2.png) + +**Interactive Plot:** + +
+
+ +Density contours can also be [faceted](facet-plots.md) and [discretely colored](discrete-color.md): + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_contour(df, x="total_bill", y="tip", facet_col="sex", color="smoker") +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_3.png) + +**Interactive Plot:** + +
+
+ +Plotly Express density contours can be [continuously-colored](colorscales.md) and labeled: + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_contour(df, x="total_bill", y="tip") +fig.update_traces(contours_coloring="fill", contours_showlabels = True) +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_4.png) + +**Interactive Plot:** + +
+
+ +### Other aggregation functions than `count` + +By passing in a `z` value and a `histfunc`, density contours can perform basic aggregation operations. Here we show average Sepal Length grouped by Petal Length and Petal Width for the Iris dataset. + +```python +import plotly.express as px +df = px.data.iris() + +fig = px.density_contour(df, x="petal_length", y="petal_width", z="sepal_length", histfunc="avg") +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_5.png) + +**Interactive Plot:** + +
+
+ +### 2D Histograms with Graph Objects + +To build this kind of figure with [graph objects](graph-objects.md) without using Plotly Express, we can use the `go.Histogram2d` class. + +#### Basic 2D Histogram Contour + +```python +import plotly.graph_objects as go + +import numpy as np +np.random.seed(1) + +x = np.random.uniform(-1, 1, size=500) +y = np.random.uniform(-1, 1, size=500) + +fig = go.Figure(go.Histogram2dContour( + x = x, + y = y +)) + +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_6.png) + +**Interactive Plot:** + +
+
+ +#### 2D Histogram Contour Colorscale + +```python +import plotly.graph_objects as go + +import numpy as np + +x = np.random.uniform(-1, 1, size=500) +y = np.random.uniform(-1, 1, size=500) + +fig = go.Figure(go.Histogram2dContour( + x = x, + y = y, + colorscale = 'Blues' +)) + +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_7.png) + +**Interactive Plot:** + +
+
+ +#### 2D Histogram Contour Styled + +```python +import plotly.graph_objects as go + +import numpy as np + +x = np.random.uniform(-1, 1, size=500) +y = np.random.uniform(-1, 1, size=500) + +fig = go.Figure(go.Histogram2dContour( + x = x, + y = y, + colorscale = 'Jet', + contours = dict( + showlabels = True, + labelfont = dict( + family = 'Raleway', + color = 'white' + ) + ), + hoverlabel = dict( + bgcolor = 'white', + bordercolor = 'black', + font = dict( + family = 'Raleway', + color = 'black' + ) + ) + +)) + +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_8.png) + +**Interactive Plot:** + +
+
+ +#### 2D Histogram Contour Subplot + +```python +import plotly.graph_objects as go + +import numpy as np + +t = np.linspace(-1, 1.2, 2000) +x = (t**3) + (0.3 * np.random.randn(2000)) +y = (t**6) + (0.3 * np.random.randn(2000)) + +fig = go.Figure() +fig.add_trace(go.Histogram2dContour( + x = x, + y = y, + colorscale = 'Blues', + reversescale = True, + xaxis = 'x', + yaxis = 'y' + )) +fig.add_trace(go.Scatter( + x = x, + y = y, + xaxis = 'x', + yaxis = 'y', + mode = 'markers', + marker = dict( + color = 'rgba(0,0,0,0.3)', + size = 3 + ) + )) +fig.add_trace(go.Histogram( + y = y, + xaxis = 'x2', + marker = dict( + color = 'rgba(0,0,0,1)' + ) + )) +fig.add_trace(go.Histogram( + x = x, + yaxis = 'y2', + marker = dict( + color = 'rgba(0,0,0,1)' + ) + )) + +fig.update_layout( + autosize = False, + xaxis = dict( + zeroline = False, + domain = [0,0.85], + showgrid = False + ), + yaxis = dict( + zeroline = False, + domain = [0,0.85], + showgrid = False + ), + xaxis2 = dict( + zeroline = False, + domain = [0.85,1], + showgrid = False + ), + yaxis2 = dict( + zeroline = False, + domain = [0.85,1], + showgrid = False + ), + height = 600, + width = 600, + bargap = 0, + hovermode = 'closest', + showlegend = False +) + +fig.show() +``` + +![Generated Plot](./2d-histogram-contour_9.png) + +**Interactive Plot:** + +
+
+ +#### Reference +See https://plotly.com/python/reference/histogram2dcontour/ for more information and chart attribute options! diff --git a/pages/examples/2d-histogram-contour_1.html b/pages/examples/2d-histogram-contour_1.html new file mode 100644 index 00000000000..79e2263fc01 --- /dev/null +++ b/pages/examples/2d-histogram-contour_1.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_1.png b/pages/examples/2d-histogram-contour_1.png new file mode 100644 index 00000000000..bdb41a07ef3 Binary files /dev/null and b/pages/examples/2d-histogram-contour_1.png differ diff --git a/pages/examples/2d-histogram-contour_2.html b/pages/examples/2d-histogram-contour_2.html new file mode 100644 index 00000000000..5e8cec8b1b5 --- /dev/null +++ b/pages/examples/2d-histogram-contour_2.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_2.png b/pages/examples/2d-histogram-contour_2.png new file mode 100644 index 00000000000..5c62610ce21 Binary files /dev/null and b/pages/examples/2d-histogram-contour_2.png differ diff --git a/pages/examples/2d-histogram-contour_3.html b/pages/examples/2d-histogram-contour_3.html new file mode 100644 index 00000000000..03df2e39159 --- /dev/null +++ b/pages/examples/2d-histogram-contour_3.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_3.png b/pages/examples/2d-histogram-contour_3.png new file mode 100644 index 00000000000..4cb6c22b9e5 Binary files /dev/null and b/pages/examples/2d-histogram-contour_3.png differ diff --git a/pages/examples/2d-histogram-contour_4.html b/pages/examples/2d-histogram-contour_4.html new file mode 100644 index 00000000000..cffdcfec761 --- /dev/null +++ b/pages/examples/2d-histogram-contour_4.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_4.png b/pages/examples/2d-histogram-contour_4.png new file mode 100644 index 00000000000..5524df4baf2 Binary files /dev/null and b/pages/examples/2d-histogram-contour_4.png differ diff --git a/pages/examples/2d-histogram-contour_5.html b/pages/examples/2d-histogram-contour_5.html new file mode 100644 index 00000000000..d7523eed972 --- /dev/null +++ b/pages/examples/2d-histogram-contour_5.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_5.png b/pages/examples/2d-histogram-contour_5.png new file mode 100644 index 00000000000..ad0479b928f Binary files /dev/null and b/pages/examples/2d-histogram-contour_5.png differ diff --git a/pages/examples/2d-histogram-contour_6.html b/pages/examples/2d-histogram-contour_6.html new file mode 100644 index 00000000000..76f2fc5bd6f --- /dev/null +++ b/pages/examples/2d-histogram-contour_6.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_6.png b/pages/examples/2d-histogram-contour_6.png new file mode 100644 index 00000000000..b54c36592da Binary files /dev/null and b/pages/examples/2d-histogram-contour_6.png differ diff --git a/pages/examples/2d-histogram-contour_7.html b/pages/examples/2d-histogram-contour_7.html new file mode 100644 index 00000000000..53d5b900acd --- /dev/null +++ b/pages/examples/2d-histogram-contour_7.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_7.png b/pages/examples/2d-histogram-contour_7.png new file mode 100644 index 00000000000..bb08849676f Binary files /dev/null and b/pages/examples/2d-histogram-contour_7.png differ diff --git a/pages/examples/2d-histogram-contour_8.html b/pages/examples/2d-histogram-contour_8.html new file mode 100644 index 00000000000..c6b01b49aa8 --- /dev/null +++ b/pages/examples/2d-histogram-contour_8.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_8.png b/pages/examples/2d-histogram-contour_8.png new file mode 100644 index 00000000000..79e1c7cb208 Binary files /dev/null and b/pages/examples/2d-histogram-contour_8.png differ diff --git a/pages/examples/2d-histogram-contour_9.html b/pages/examples/2d-histogram-contour_9.html new file mode 100644 index 00000000000..4ab491cf793 --- /dev/null +++ b/pages/examples/2d-histogram-contour_9.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/2d-histogram-contour_9.png b/pages/examples/2d-histogram-contour_9.png new file mode 100644 index 00000000000..dce432a750f Binary files /dev/null and b/pages/examples/2d-histogram-contour_9.png differ diff --git a/pages/examples/3d-axes.md b/pages/examples/3d-axes.md new file mode 100644 index 00000000000..110c01ffa30 --- /dev/null +++ b/pages/examples/3d-axes.md @@ -0,0 +1,323 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.16.4 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.10.4 + plotly: + description: How to format axes of 3d plots in Python with Plotly. + display_as: 3d_charts + language: python + layout: base + name: 3D Axes + order: 1 + page_type: example_index + permalink: python/3d-axes/ + thumbnail: thumbnail/3d-axes.png +--- + +### Range of axes + +3D figures have an attribute in `layout` called `scene`, which contains +attributes such as `xaxis`, `yaxis` and `zaxis` parameters, in order to +set the range, title, ticks, color etc. of the axes. + +For creating 3D charts, see [this page](https://plotly.com/python/3d-charts/). + +Set `range` on an axis to manually configure a range for that axis. If you don't set `range`, it's automatically calculated. In this example, we set a `range` on `xaxis`, `yaxis`, and `zaxis`. + +```python +import plotly.graph_objects as go +import numpy as np +np.random.seed(1) + +N = 70 + +fig = go.Figure(data=[go.Mesh3d(x=(70*np.random.randn(N)), + y=(55*np.random.randn(N)), + z=(40*np.random.randn(N)), + opacity=0.5, + color='rgba(244,22,100,0.6)' + )]) + +fig.update_layout( + scene = dict( + xaxis = dict(nticks=4, range=[-100,100],), + yaxis = dict(nticks=4, range=[-50,100],), + zaxis = dict(nticks=4, range=[-100,100],),), + width=700, + margin=dict(r=20, l=10, b=10, t=10)) + +fig.show() +``` + +![Generated Plot](./3d-axes_1.png) + +**Interactive Plot:** + +
+
+ +### Setting only a Lower or Upper Bound for Range + +*New in 5.17* + +You can also set just a lower or upper bound for `range`. In this case, autorange is used for the other bound. In this example, we apply autorange to the lower bound of the `yaxis` and the upper bound of `zaxis` by setting them to `None`. + +```python +import plotly.graph_objects as go +import numpy as np +np.random.seed(1) + +N = 70 + +fig = go.Figure(data=[go.Mesh3d(x=(70*np.random.randn(N)), + y=(55*np.random.randn(N)), + z=(40*np.random.randn(N)), + opacity=0.5, + color='rgba(244,22,100,0.6)' + )]) + +fig.update_layout( + scene = dict( + xaxis = dict(nticks=4, range=[-100,100],), + yaxis = dict(nticks=4, range=[None, 100],), + zaxis = dict(nticks=4, range=[-100, None],),), + width=700, + margin=dict(r=20, l=10, b=10, t=10)) + +fig.show() +``` + +![Generated Plot](./3d-axes_2.png) + +**Interactive Plot:** + +
+
+ +### Fixed Ratio Axes + +```python +import plotly.graph_objects as go +from plotly.subplots import make_subplots +import numpy as np + +N = 50 + +fig = make_subplots(rows=2, cols=2, + specs=[[{'is_3d': True}, {'is_3d': True}], + [{'is_3d': True}, {'is_3d': True}]], + print_grid=False) +for i in [1,2]: + for j in [1,2]: + fig.add_trace( + go.Mesh3d( + x=(60*np.random.randn(N)), + y=(25*np.random.randn(N)), + z=(40*np.random.randn(N)), + opacity=0.5, + ), + row=i, col=j) + +fig.update_layout(width=700, margin=dict(r=10, l=10, b=10, t=10)) +# fix the ratio in the top left subplot to be a cube +fig.update_layout(scene_aspectmode='cube') +# manually force the z-axis to appear twice as big as the other two +fig.update_layout(scene2_aspectmode='manual', + scene2_aspectratio=dict(x=1, y=1, z=2)) +# draw axes in proportion to the proportion of their ranges +fig.update_layout(scene3_aspectmode='data') +# automatically produce something that is well proportioned using 'data' as the default +fig.update_layout(scene4_aspectmode='auto') +fig.show() +``` + +![Generated Plot](./3d-axes_3.png) + +**Interactive Plot:** + +
+
+ +### Set Axes Title + +```python +import plotly.graph_objects as go +import numpy as np + +# Define random surface +N = 50 +fig = go.Figure() +fig.add_trace(go.Mesh3d(x=(60*np.random.randn(N)), + y=(25*np.random.randn(N)), + z=(40*np.random.randn(N)), + opacity=0.5, + color='yellow' + )) +fig.add_trace(go.Mesh3d(x=(70*np.random.randn(N)), + y=(55*np.random.randn(N)), + z=(30*np.random.randn(N)), + opacity=0.5, + color='pink' + )) + +fig.update_layout(scene = dict( + xaxis=dict( + title=dict( + text='X AXIS TITLE' + ) + ), + yaxis=dict( + title=dict( + text='Y AXIS TITLE' + ) + ), + zaxis=dict( + title=dict( + text='Z AXIS TITLE' + ) + ), + ), + width=700, + margin=dict(r=20, b=10, l=10, t=10)) + +fig.show() +``` + +![Generated Plot](./3d-axes_4.png) + +**Interactive Plot:** + +
+
+ +### Ticks Formatting + +```python +import plotly.graph_objects as go +import numpy as np + +# Define random surface +N = 50 +fig = go.Figure(data=[go.Mesh3d(x=(60*np.random.randn(N)), + y=(25*np.random.randn(N)), + z=(40*np.random.randn(N)), + opacity=0.5, + color='rgba(100,22,200,0.5)' + )]) + +# Different types of customized ticks +fig.update_layout(scene = dict( + xaxis = dict( + ticktext= ['TICKS','MESH','PLOTLY','PYTHON'], + tickvals= [0,50,75,-50]), + yaxis = dict( + nticks=5, tickfont=dict( + color='green', + size=12, + family='Old Standard TT, serif',), + ticksuffix='#'), + zaxis = dict( + nticks=4, ticks='outside', + tick0=0, tickwidth=4),), + width=700, + margin=dict(r=10, l=10, b=10, t=10) + ) + +fig.show() +``` + +![Generated Plot](./3d-axes_5.png) + +**Interactive Plot:** + +
+
+ +### Background and Grid Color + +```python +import plotly.graph_objects as go +import numpy as np + +N = 50 +fig = go.Figure(data=[go.Mesh3d(x=(30*np.random.randn(N)), + y=(25*np.random.randn(N)), + z=(30*np.random.randn(N)), + opacity=0.5,)]) + + +# xaxis.backgroundcolor is used to set background color +fig.update_layout(scene = dict( + xaxis = dict( + backgroundcolor="rgb(200, 200, 230)", + gridcolor="white", + showbackground=True, + zerolinecolor="white",), + yaxis = dict( + backgroundcolor="rgb(230, 200,230)", + gridcolor="white", + showbackground=True, + zerolinecolor="white"), + zaxis = dict( + backgroundcolor="rgb(230, 230,200)", + gridcolor="white", + showbackground=True, + zerolinecolor="white",),), + width=700, + margin=dict( + r=10, l=10, + b=10, t=10) + ) +fig.show() +``` + +![Generated Plot](./3d-axes_6.png) + +**Interactive Plot:** + +
+
+ +### Disabling tooltip spikes + +By default, guidelines originating from the tooltip point are drawn. It is possible to disable this behaviour with the `showspikes` parameter. In this example we only keep the `z` spikes (projection of the tooltip on the `x-y` plane). Hover on the data to show this behaviour. + +```python +import plotly.graph_objects as go +import numpy as np + +N = 50 +fig = go.Figure(data=[go.Mesh3d(x=(30*np.random.randn(N)), + y=(25*np.random.randn(N)), + z=(30*np.random.randn(N)), + opacity=0.5,)]) +fig.update_layout(scene=dict(xaxis_showspikes=False, + yaxis_showspikes=False)) +fig.show() +``` + +![Generated Plot](./3d-axes_7.png) + +**Interactive Plot:** + +
+
diff --git a/pages/examples/3d-axes_1.html b/pages/examples/3d-axes_1.html new file mode 100644 index 00000000000..99d210f0c46 --- /dev/null +++ b/pages/examples/3d-axes_1.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_1.png b/pages/examples/3d-axes_1.png new file mode 100644 index 00000000000..aa8b927a47b Binary files /dev/null and b/pages/examples/3d-axes_1.png differ diff --git a/pages/examples/3d-axes_2.html b/pages/examples/3d-axes_2.html new file mode 100644 index 00000000000..ca4dbcf2317 --- /dev/null +++ b/pages/examples/3d-axes_2.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_2.png b/pages/examples/3d-axes_2.png new file mode 100644 index 00000000000..98ef72d851f Binary files /dev/null and b/pages/examples/3d-axes_2.png differ diff --git a/pages/examples/3d-axes_3.html b/pages/examples/3d-axes_3.html new file mode 100644 index 00000000000..5c39e805f8d --- /dev/null +++ b/pages/examples/3d-axes_3.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_3.png b/pages/examples/3d-axes_3.png new file mode 100644 index 00000000000..755ed838f99 Binary files /dev/null and b/pages/examples/3d-axes_3.png differ diff --git a/pages/examples/3d-axes_4.html b/pages/examples/3d-axes_4.html new file mode 100644 index 00000000000..d1c27e4ae21 --- /dev/null +++ b/pages/examples/3d-axes_4.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_4.png b/pages/examples/3d-axes_4.png new file mode 100644 index 00000000000..f852eec9306 Binary files /dev/null and b/pages/examples/3d-axes_4.png differ diff --git a/pages/examples/3d-axes_5.html b/pages/examples/3d-axes_5.html new file mode 100644 index 00000000000..95f69080a8e --- /dev/null +++ b/pages/examples/3d-axes_5.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_5.png b/pages/examples/3d-axes_5.png new file mode 100644 index 00000000000..ce5eb0ef9cd Binary files /dev/null and b/pages/examples/3d-axes_5.png differ diff --git a/pages/examples/3d-axes_6.html b/pages/examples/3d-axes_6.html new file mode 100644 index 00000000000..1568f58814e --- /dev/null +++ b/pages/examples/3d-axes_6.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_6.png b/pages/examples/3d-axes_6.png new file mode 100644 index 00000000000..346d9e9d85f Binary files /dev/null and b/pages/examples/3d-axes_6.png differ diff --git a/pages/examples/3d-axes_7.html b/pages/examples/3d-axes_7.html new file mode 100644 index 00000000000..7f7253006b7 --- /dev/null +++ b/pages/examples/3d-axes_7.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-axes_7.png b/pages/examples/3d-axes_7.png new file mode 100644 index 00000000000..a9e90e512d9 Binary files /dev/null and b/pages/examples/3d-axes_7.png differ diff --git a/pages/examples/3d-bubble-charts.md b/pages/examples/3d-bubble-charts.md new file mode 100644 index 00000000000..b1b13aed877 --- /dev/null +++ b/pages/examples/3d-bubble-charts.md @@ -0,0 +1,249 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.16.4 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.11.10 + plotly: + description: How to make 3D Bubble Charts in Python with Plotly. Three examples + of 3D Bubble Charts. + display_as: 3d_charts + language: python + layout: base + name: 3D Bubble Charts + order: 6 + page_type: u-guide + permalink: python/3d-bubble-charts/ + thumbnail: thumbnail/3dbubble.jpg +--- + +### 3d Bubble chart with Plotly Express + +```python +import plotly.express as px +import numpy as np +df = px.data.gapminder() +fig = px.scatter_3d(df, x='year', y='continent', z='pop', size='gdpPercap', color='lifeExp', + hover_data=['country']) +fig.update_layout(scene_zaxis_type="log") +fig.show() +``` + +![Generated Plot](./3d-bubble-charts_1.png) + +**Interactive Plot:** + +
+
+ +#### Simple Bubble Chart + +```python +import plotly.graph_objects as go + +import pandas as pd + +# Get Data: this ex will only use part of it (i.e. rows 750-1500) +df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv') + +start, end = 750, 1500 + +fig = go.Figure(data=go.Scatter3d( + x=df['year'][start:end], + y=df['continent'][start:end], + z=df['pop'][start:end], + text=df['country'][start:end], + mode='markers', + marker=dict( + sizemode='diameter', + sizeref=750, + size=df['gdpPercap'][start:end], + color = df['lifeExp'][start:end], + colorscale = 'Viridis', + colorbar_title = 'Life
Expectancy', + line_color='rgb(140, 140, 170)' + ) +)) + + +fig.update_layout(height=800, width=800, + title=dict(text='Examining Population and Life Expectancy Over Time')) + +fig.show() +``` + +![Generated Plot](./3d-bubble-charts_2.png) + +**Interactive Plot:** + +
+
+ +#### Bubble Chart Sized by a Variable + +Plot planets' distance from sun, density, and gravity with bubble size based on planet size + +```python +import plotly.graph_objects as go + +planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto'] +planet_colors = ['rgb(135, 135, 125)', 'rgb(210, 50, 0)', 'rgb(50, 90, 255)', + 'rgb(178, 0, 0)', 'rgb(235, 235, 210)', 'rgb(235, 205, 130)', + 'rgb(55, 255, 217)', 'rgb(38, 0, 171)', 'rgb(255, 255, 255)'] +distance_from_sun = [57.9, 108.2, 149.6, 227.9, 778.6, 1433.5, 2872.5, 4495.1, 5906.4] +density = [5427, 5243, 5514, 3933, 1326, 687, 1271, 1638, 2095] +gravity = [3.7, 8.9, 9.8, 3.7, 23.1, 9.0, 8.7, 11.0, 0.7] +planet_diameter = [4879, 12104, 12756, 6792, 142984, 120536, 51118, 49528, 2370] + +# Create trace, sizing bubbles by planet diameter +fig = go.Figure(data=go.Scatter3d( + x = distance_from_sun, + y = density, + z = gravity, + text = planets, + mode = 'markers', + marker = dict( + sizemode = 'diameter', + sizeref = 750, # info on sizeref: https://plotly.com/python/reference/scatter/#scatter-marker-sizeref + size = planet_diameter, + color = planet_colors, + ) +)) + +fig.update_layout( + width=800, + height=800, + title=dict(text="Planets!"), + scene=dict( + xaxis=dict( + title=dict( + text="Distance from Sun", + font=dict( + color="white" + ) + ) + ), + yaxis=dict( + title=dict( + text="Density", + font=dict( + color="white" + ) + ) + ), + zaxis=dict( + title=dict( + text="Gravity", + font=dict( + color="white" + ) + ) + ), + bgcolor="rgb(20, 24, 54)" + ) +) + +fig.show() +``` + +![Generated Plot](./3d-bubble-charts_3.png) + +**Interactive Plot:** + +
+
+ +#### Edit the Colorbar + +Plot planets' distance from sun, density, and gravity with bubble size based on planet size + +```python +import plotly.graph_objects as go + +planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto'] +temperatures = [167, 464, 15, -20, -65, -110, -140, -195, -200, -225] +distance_from_sun = [57.9, 108.2, 149.6, 227.9, 778.6, 1433.5, 2872.5, 4495.1, 5906.4] +density = [5427, 5243, 5514, 3933, 1326, 687, 1271, 1638, 2095] +gravity = [3.7, 8.9, 9.8, 3.7, 23.1, 9.0, 8.7, 11.0, 0.7] +planet_diameter = [4879, 12104, 12756, 6792, 142984, 120536, 51118, 49528, 2370] + +# Create trace, sizing bubbles by planet diameter +fig = go.Figure(go.Scatter3d( + x = distance_from_sun, + y = density, + z = gravity, + text = planets, + mode = 'markers', + marker = dict( + sizemode = 'diameter', + sizeref = 750, # info on sizeref: https://plotly.com/python/reference/scatter/#scatter-marker-sizeref + size = planet_diameter, + color = temperatures, + colorbar_title = 'Mean
Temperature', + colorscale=[[0, 'rgb(5, 10, 172)'], [.3, 'rgb(255, 255, 255)'], [1, 'rgb(178, 10, 28)']] + ) +)) + +fig.update_layout( + width=800, + height=800, + title=dict(text="Planets!"), + scene=dict( + xaxis=dict( + title=dict( + text="Distance from Sun", + font=dict( + color="white" + ) + ) + ), + yaxis=dict( + title=dict( + text="Density", + font=dict( + color="white" + ) + ) + ), + zaxis=dict( + title=dict( + text="Gravity", + font=dict( + color="white" + ) + ) + ), + bgcolor="rgb(20, 24, 54)" + ) +) + +fig.show() +``` + +![Generated Plot](./3d-bubble-charts_4.png) + +**Interactive Plot:** + +
+
+ +#### Reference + +See https://plotly.com/python/reference/scatter3d/ and https://plotly.com/python/reference/scatter/#scatter-marker-sizeref
for more information and chart attribute options! diff --git a/pages/examples/3d-bubble-charts_1.html b/pages/examples/3d-bubble-charts_1.html new file mode 100644 index 00000000000..68564dd6b25 --- /dev/null +++ b/pages/examples/3d-bubble-charts_1.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-bubble-charts_1.png b/pages/examples/3d-bubble-charts_1.png new file mode 100644 index 00000000000..f607c37360e Binary files /dev/null and b/pages/examples/3d-bubble-charts_1.png differ diff --git a/pages/examples/3d-bubble-charts_2.html b/pages/examples/3d-bubble-charts_2.html new file mode 100644 index 00000000000..d02557ffe23 --- /dev/null +++ b/pages/examples/3d-bubble-charts_2.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-bubble-charts_2.png b/pages/examples/3d-bubble-charts_2.png new file mode 100644 index 00000000000..ccbd1f3d710 Binary files /dev/null and b/pages/examples/3d-bubble-charts_2.png differ diff --git a/pages/examples/3d-bubble-charts_3.html b/pages/examples/3d-bubble-charts_3.html new file mode 100644 index 00000000000..bb0ddbdc57a --- /dev/null +++ b/pages/examples/3d-bubble-charts_3.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-bubble-charts_3.png b/pages/examples/3d-bubble-charts_3.png new file mode 100644 index 00000000000..bef5641ac69 Binary files /dev/null and b/pages/examples/3d-bubble-charts_3.png differ diff --git a/pages/examples/3d-bubble-charts_4.html b/pages/examples/3d-bubble-charts_4.html new file mode 100644 index 00000000000..15eac420b93 --- /dev/null +++ b/pages/examples/3d-bubble-charts_4.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-bubble-charts_4.png b/pages/examples/3d-bubble-charts_4.png new file mode 100644 index 00000000000..ecba8b26a42 Binary files /dev/null and b/pages/examples/3d-bubble-charts_4.png differ diff --git a/pages/examples/3d-camera-controls.md b/pages/examples/3d-camera-controls.md new file mode 100644 index 00000000000..71b38cfca3e --- /dev/null +++ b/pages/examples/3d-camera-controls.md @@ -0,0 +1,356 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.1' + jupytext_version: 1.2.3 + kernelspec: + display_name: Python 3 + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.7.3 + plotly: + description: How to Control the Camera in your 3D Charts in Python with Plotly. + display_as: 3d_charts + language: python + layout: base + name: 3D Camera Controls + order: 5 + permalink: python/3d-camera-controls/ + thumbnail: thumbnail/3d-camera-controls.jpg +--- + +### How camera controls work + +The camera position and direction is determined by three vectors: *up*, *center*, *eye*. Their coordinates refer to the 3-d domain, i.e., `(0, 0, 0)` is always the center of the domain, no matter data values. +The `eye` vector determines the position of the camera. The default is $(x=1.25, y=1.25, z=1.25)$. + +The `up` vector determines the `up` direction on the page. The default is $(x=0, y=0, z=1)$, that is, the z-axis points up. + +The projection of the `center` point lies at the center of the view. By default it is $(x=0, y=0, z=0)$. + + +### Default parameters + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=40, r=0, l=20, b=20) +) + +name = 'default' +# Default parameters which are used when `layout.scene.camera` is not provided +camera = dict( + up=dict(x=0, y=0, z=1), + center=dict(x=0, y=0, z=0), + eye=dict(x=1.25, y=1.25, z=1.25) +) + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_1.png) + +**Interactive Plot:** + +
+
+ +### Changing the camera position by setting the eye parameter + +#### Lower the View Point + +by setting `eye.z` to a smaller value. + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +name = 'eye = (x:2, y:2, z:0.1)' +camera = dict( + eye=dict(x=2, y=2, z=0.1) +) + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_2.png) + +**Interactive Plot:** + +
+
+ +#### X-Z plane + +set `eye.x` and `eye.z` to zero + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +name = 'eye = (x:0., y:2.5, z:0.)' +camera = dict( + eye=dict(x=0., y=2.5, z=0.) +) + + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_3.png) + +**Interactive Plot:** + +
+
+ +#### Y-Z plane + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +name = 'eye = (x:2.5, y:0., z:0.)' +camera = dict( + eye=dict(x=2.5, y=0., z=0.) +) + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_4.png) + +**Interactive Plot:** + +
+
+ +#### View from Above (X-Y plane) + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +name = 'eye = (x:0., y:0., z:2.5)' +camera = dict( + eye=dict(x=0., y=0., z=2.5) +) + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_5.png) + +**Interactive Plot:** + +
+
+ +#### Zooming In +... by placing the camera closer to the origin (`eye` with a smaller norm) + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +name = 'eye = (x:0.1, y:0.1, z:1.5)' +camera = dict( + eye=dict(x=0.1, y=0.1, z=1.5) +) + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_6.png) + +**Interactive Plot:** + +
+
+ +### Tilting the camera vertical by setting the up parameter + +Tilt camera by changing the `up` vector: here the vertical of the view points in the `x` direction. + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +name = 'eye = (x:0., y:2.5, z:0.), point along x' +camera = dict( + up=dict(x=1, y=0., z=0), + eye=dict(x=0., y=2.5, z=0.) +) + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_7.png) + +**Interactive Plot:** + +
+
+ +Note when `up` does not correspond to the direction of an axis, you also need to set `layout.scene.dragmode='orbit'`. + +```python +import math +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=30, r=0, l=20, b=10) +) + +angle = math.pi / 4 # 45 degrees + +name = 'vertical is along y+z' +camera = dict( + up=dict(x=0, y=math.cos(angle), z=math.sin(angle)), + eye=dict(x=2, y=0, z=0) +) + +fig.update_layout(scene_camera=camera, scene_dragmode='orbit', title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_8.png) + +**Interactive Plot:** + +
+
+ +### Changing the focal point by setting center + +You can change the focal point (a point which projection lies at the center of the view) by setting the `center` parameter of `camera`. Note how a part of the data is cropped below because the camera is looking up. + +```python +import plotly.graph_objects as go +import pandas as pd + +# Read data from a csv +z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv') + +fig = go.Figure(data=go.Surface(z=z_data, showscale=False)) +fig.update_layout( + title=dict(text='Mt Bruno Elevation'), + width=400, height=400, + margin=dict(t=25, r=0, l=20, b=30) +) + +name = 'looking up' +camera = dict( + center=dict(x=0, y=0, z=0.7)) + + +fig.update_layout(scene_camera=camera, title=name) +fig.show() +``` + +![Generated Plot](./3d-camera-controls_9.png) + +**Interactive Plot:** + +
+
+ +#### Reference + + +See https://plotly.com/python/reference/layout/scene/#layout-scene-camera for more information and chart attribute options! \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_1.html b/pages/examples/3d-camera-controls_1.html new file mode 100644 index 00000000000..df5c18e5ea2 --- /dev/null +++ b/pages/examples/3d-camera-controls_1.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_1.png b/pages/examples/3d-camera-controls_1.png new file mode 100644 index 00000000000..25e8ed1441b Binary files /dev/null and b/pages/examples/3d-camera-controls_1.png differ diff --git a/pages/examples/3d-camera-controls_2.html b/pages/examples/3d-camera-controls_2.html new file mode 100644 index 00000000000..fdf33ad7191 --- /dev/null +++ b/pages/examples/3d-camera-controls_2.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_2.png b/pages/examples/3d-camera-controls_2.png new file mode 100644 index 00000000000..7cf792fa5eb Binary files /dev/null and b/pages/examples/3d-camera-controls_2.png differ diff --git a/pages/examples/3d-camera-controls_3.html b/pages/examples/3d-camera-controls_3.html new file mode 100644 index 00000000000..8f33a03d77c --- /dev/null +++ b/pages/examples/3d-camera-controls_3.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_3.png b/pages/examples/3d-camera-controls_3.png new file mode 100644 index 00000000000..b1aa0ca1d1c Binary files /dev/null and b/pages/examples/3d-camera-controls_3.png differ diff --git a/pages/examples/3d-camera-controls_4.html b/pages/examples/3d-camera-controls_4.html new file mode 100644 index 00000000000..a083d2dbbaa --- /dev/null +++ b/pages/examples/3d-camera-controls_4.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_4.png b/pages/examples/3d-camera-controls_4.png new file mode 100644 index 00000000000..64cedbe274d Binary files /dev/null and b/pages/examples/3d-camera-controls_4.png differ diff --git a/pages/examples/3d-camera-controls_5.html b/pages/examples/3d-camera-controls_5.html new file mode 100644 index 00000000000..4c510d3b1c0 --- /dev/null +++ b/pages/examples/3d-camera-controls_5.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_5.png b/pages/examples/3d-camera-controls_5.png new file mode 100644 index 00000000000..f68d7152cd7 Binary files /dev/null and b/pages/examples/3d-camera-controls_5.png differ diff --git a/pages/examples/3d-camera-controls_6.html b/pages/examples/3d-camera-controls_6.html new file mode 100644 index 00000000000..3e81014a8c0 --- /dev/null +++ b/pages/examples/3d-camera-controls_6.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_6.png b/pages/examples/3d-camera-controls_6.png new file mode 100644 index 00000000000..0ef3c24dd33 Binary files /dev/null and b/pages/examples/3d-camera-controls_6.png differ diff --git a/pages/examples/3d-camera-controls_7.html b/pages/examples/3d-camera-controls_7.html new file mode 100644 index 00000000000..56ef40642c0 --- /dev/null +++ b/pages/examples/3d-camera-controls_7.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_7.png b/pages/examples/3d-camera-controls_7.png new file mode 100644 index 00000000000..025a7f4d296 Binary files /dev/null and b/pages/examples/3d-camera-controls_7.png differ diff --git a/pages/examples/3d-camera-controls_8.html b/pages/examples/3d-camera-controls_8.html new file mode 100644 index 00000000000..8fae1b060cb --- /dev/null +++ b/pages/examples/3d-camera-controls_8.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_8.png b/pages/examples/3d-camera-controls_8.png new file mode 100644 index 00000000000..308f30a50d6 Binary files /dev/null and b/pages/examples/3d-camera-controls_8.png differ diff --git a/pages/examples/3d-camera-controls_9.html b/pages/examples/3d-camera-controls_9.html new file mode 100644 index 00000000000..5a92621aacc --- /dev/null +++ b/pages/examples/3d-camera-controls_9.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-camera-controls_9.png b/pages/examples/3d-camera-controls_9.png new file mode 100644 index 00000000000..c343cf9dd69 Binary files /dev/null and b/pages/examples/3d-camera-controls_9.png differ diff --git a/pages/examples/3d-isosurface-plots.md b/pages/examples/3d-isosurface-plots.md new file mode 100644 index 00000000000..0e2fa211f6d --- /dev/null +++ b/pages/examples/3d-isosurface-plots.md @@ -0,0 +1,294 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.1' + jupytext_version: 1.1.1 + kernelspec: + display_name: Python 3 + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.7.3 + plotly: + description: How to make 3D Isosurface Plots in Python with Plotly. + display_as: 3d_charts + language: python + layout: base + name: 3D Isosurface Plots + order: 10 + page_type: u-guide + permalink: python/3d-isosurface-plots/ + redirect_from: python/isosurfaces-with-marching-cubes/ + thumbnail: thumbnail/isosurface.jpg +--- + +With ``go.Isosurface``, you can plot [isosurface contours](https://en.wikipedia.org/wiki/Isosurface) of a scalar field ``value``, which is defined on ``x``, ``y`` and ``z`` coordinates. + +#### Basic Isosurface + +In this first example, we plot the isocontours of values ``isomin=2`` and ``isomax=6``. In addition, portions of the sides of the coordinate domains for which the value is between ``isomin`` and ``isomax`` (named the ``caps``) are colored. Please rotate the figure to visualize both the internal surfaces and the caps surfaces on the sides. + +```python +import plotly.graph_objects as go + +fig= go.Figure(data=go.Isosurface( + x=[0,0,0,0,1,1,1,1], + y=[1,0,1,0,1,0,1,0], + z=[1,1,0,0,1,1,0,0], + value=[1,2,3,4,5,6,7,8], + isomin=2, + isomax=6, +)) + +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_1.png) + +**Interactive Plot:** + +
+
+ +### Removing caps when visualizing isosurfaces + +For a clearer visualization of internal surfaces, it is possible to remove the caps (color-coded surfaces on the sides of the visualization domain). Caps are visible by default. + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j] + +# ellipsoid +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + isomin=10, + isomax=40, + caps=dict(x_show=False, y_show=False) + )) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_2.png) + +**Interactive Plot:** + +
+
+ +### Modifying the number of isosurfaces + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j] + +# ellipsoid +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + isomin=10, + isomax=50, + surface_count=5, # number of isosurfaces, 2 by default: only min and max + colorbar_nticks=5, # colorbar ticks correspond to isosurface values + caps=dict(x_show=False, y_show=False) + )) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_3.png) + +**Interactive Plot:** + +
+
+ +### Changing the opacity of isosurfaces + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j] + +# ellipsoid +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + opacity=0.6, + isomin=10, + isomax=50, + surface_count=3, + caps=dict(x_show=False, y_show=False) + )) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_4.png) + +**Interactive Plot:** + +
+
+ +#### Isosurface with Additional Slices + +Here we visualize slices parallel to the axes on top of isosurfaces. For a clearer visualization, the `fill` ratio of isosurfaces is decreased below 1 (completely filled). + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j] + +# ellipsoid +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + isomin=5, + isomax=50, + surface_fill=0.4, + caps=dict(x_show=False, y_show=False), + slices_z=dict(show=True, locations=[-1, -3,]), + slices_y=dict(show=True, locations=[0]), + )) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_5.png) + +**Interactive Plot:** + +
+
+ +#### Multiple Isosurfaces with Caps + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, 0:5:20j] + +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + isomin=30, + isomax=50, + surface=dict(count=3, fill=0.7, pattern='odd'), + caps=dict(x_show=True, y_show=True), + )) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_6.png) + +**Interactive Plot:** + +
+
+ +### Changing the default colorscale of isosurfaces + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j] + +# ellipsoid +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + colorscale='BlueRed', + isomin=10, + isomax=50, + surface_count=3, + caps=dict(x_show=False, y_show=False) + )) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_7.png) + +**Interactive Plot:** + +
+
+ +### Customizing the layout and appearance of isosurface plots + +```python +import plotly.graph_objects as go +import numpy as np + +X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, 0:5:20j] + +values = X * X * 0.5 + Y * Y + Z * Z * 2 + +fig = go.Figure(data=go.Isosurface( + x=X.flatten(), + y=Y.flatten(), + z=Z.flatten(), + value=values.flatten(), + isomin=30, + isomax=50, + surface=dict(count=3, fill=0.7, pattern='odd'), + showscale=False, # remove colorbar + caps=dict(x_show=True, y_show=True), + )) + +fig.update_layout( + margin=dict(t=0, l=0, b=0), # tight layout + scene_camera_eye=dict(x=1.86, y=0.61, z=0.98)) +fig.show() +``` + +![Generated Plot](./3d-isosurface-plots_8.png) + +**Interactive Plot:** + +
+
+ +#### Reference +See https://plotly.com/python/reference/isosurface/ for more information and chart attribute options! diff --git a/pages/examples/3d-isosurface-plots_1.html b/pages/examples/3d-isosurface-plots_1.html new file mode 100644 index 00000000000..bcf5f94d7f8 --- /dev/null +++ b/pages/examples/3d-isosurface-plots_1.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_1.png b/pages/examples/3d-isosurface-plots_1.png new file mode 100644 index 00000000000..216af418537 Binary files /dev/null and b/pages/examples/3d-isosurface-plots_1.png differ diff --git a/pages/examples/3d-isosurface-plots_2.html b/pages/examples/3d-isosurface-plots_2.html new file mode 100644 index 00000000000..2523b52a666 --- /dev/null +++ b/pages/examples/3d-isosurface-plots_2.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_2.png b/pages/examples/3d-isosurface-plots_2.png new file mode 100644 index 00000000000..bbe516612d2 Binary files /dev/null and b/pages/examples/3d-isosurface-plots_2.png differ diff --git a/pages/examples/3d-isosurface-plots_3.html b/pages/examples/3d-isosurface-plots_3.html new file mode 100644 index 00000000000..59561e4e1c8 --- /dev/null +++ b/pages/examples/3d-isosurface-plots_3.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_3.png b/pages/examples/3d-isosurface-plots_3.png new file mode 100644 index 00000000000..cb8005cbd22 Binary files /dev/null and b/pages/examples/3d-isosurface-plots_3.png differ diff --git a/pages/examples/3d-isosurface-plots_4.html b/pages/examples/3d-isosurface-plots_4.html new file mode 100644 index 00000000000..8b90146db73 --- /dev/null +++ b/pages/examples/3d-isosurface-plots_4.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_4.png b/pages/examples/3d-isosurface-plots_4.png new file mode 100644 index 00000000000..07282308198 Binary files /dev/null and b/pages/examples/3d-isosurface-plots_4.png differ diff --git a/pages/examples/3d-isosurface-plots_5.html b/pages/examples/3d-isosurface-plots_5.html new file mode 100644 index 00000000000..8d5ca259cfb --- /dev/null +++ b/pages/examples/3d-isosurface-plots_5.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_5.png b/pages/examples/3d-isosurface-plots_5.png new file mode 100644 index 00000000000..15e6ac521ed Binary files /dev/null and b/pages/examples/3d-isosurface-plots_5.png differ diff --git a/pages/examples/3d-isosurface-plots_6.html b/pages/examples/3d-isosurface-plots_6.html new file mode 100644 index 00000000000..997b18913ba --- /dev/null +++ b/pages/examples/3d-isosurface-plots_6.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_6.png b/pages/examples/3d-isosurface-plots_6.png new file mode 100644 index 00000000000..73128a5d7c5 Binary files /dev/null and b/pages/examples/3d-isosurface-plots_6.png differ diff --git a/pages/examples/3d-isosurface-plots_7.html b/pages/examples/3d-isosurface-plots_7.html new file mode 100644 index 00000000000..11a4759e51a --- /dev/null +++ b/pages/examples/3d-isosurface-plots_7.html @@ -0,0 +1,7 @@ + + + +
+
+ + \ No newline at end of file diff --git a/pages/examples/3d-isosurface-plots_7.png b/pages/examples/3d-isosurface-plots_7.png new file mode 100644 index 00000000000..7dcefb69f04 Binary files /dev/null and b/pages/examples/3d-isosurface-plots_7.png differ diff --git a/pages/examples/3d-isosurface-plots_8.html b/pages/examples/3d-isosurface-plots_8.html new file mode 100644 index 00000000000..ff3f395ab07 --- /dev/null +++ b/pages/examples/3d-isosurface-plots_8.html @@ -0,0 +1,7 @@ + + + +
+