Thank you for your interest in contributing to plotly.py! We are actively looking for diverse contributors, with diverse background and skills.
This guide starts with a general description of the different ways to contribute to plotly.py, then we explain some technical aspects of preparing your contribution.
Please check out the Code of Conduct. Don't skip it, but the general idea is to be nice.
There are many ways to contribute to plotly.py. To contribute effectively, it is important to first gain an understanding of the structure of the code and of the repository.
-
the
plotly.graph_objects
module (usually imported asgo
) is generated from the Plotly.js schema, so changes to be made in this package need to be contributed to Plotly.js or to thecodegen
system inpackages/python/plotly/codegen
. Most of the codegen code concerns the generation of docstrings from the schema JSON in Plotly.js. Traces and Layout classes have a direct correspondence with their Javascript counterpart. Higher-level methods that work on figures regardless of the current schema (e.g.,BaseFigure.for_each_trace
) are defined inpackages/python/plotly/plotly/basedatatypes.py
. Additional helper methods are defined there for theFigure
object, such asupdate_layout
,add_trace
, etc. -
the
plotly.express
module (usually imported aspx
) is a high-level functional API that usesgraph_objects
under the hood. Its code is inpackages/python/plotly/plotly/express
. Plotly Express functions are designed to be highly consistent with each other, and to do as little computation in Python as possible, generally concerning themselves with formatting data and creating figures out ofplotly.graph_objects
instances. Most functions ofplotly.express
call the same internal_make_figure
function in_core.py
. More generally, the internals ofpx
consist of general functions taking care of building the figure (defining subplots, traces or frames, for example), with special cases for different traces handled within these functions. There is also subsequent code reuse forpx
docstrings, in particular for documenting parameters. -
the
plotly.figure_factory
module (usually imported asff
) provides Python "recipes" for building advanced visualizations with involved computation done in Python, such as Hexbin maps, ternary contour plots, etc. Figure factories are one of the easiest entry points into contributing to plotly.py, since they consist of Python-only code, with standalone, well-separated functions. However, please note that some of the figure factories become less relevant as we are introducing more features intoplotly.express
. Some issues in the tracker are labeled "figure_factory" and can be good issues to work on. More instructions on figure factories are found here. -
other pure-Python submodules are:
plotly.io
(low-level interface for displaying, reading and writing figures),plotly.subplots
(helper function for layout of multi-plot figures) -
tests are found in
packages/python/plotly/plotly/tests
. Different directories correspond to different test jobs (with different dependency sets) run in continuous integration. More is explained about tests in the following "Technical aspects" section. -
the documentation is part of this repository. Its structure and some explanations are described here. The documentation, in particular example-based tutorials, is a great place to start contributing. The contribution process is also more lightweight, since you can modify tutorial notebooks without setting up an environment, etc. We maintain a wishlist of examples to add on #1965. If you have writing skills, the wording of existing examples can also be improved in places.
Contributing code or documentation is not the only way to contribute! You can also contribute to the project by
-
reporting bugs (see below).
-
submitting feature requests (maybe we'll convince you to contribute it as a pull request!).
-
helping other users on the community forum. Join the list of nice people helping other plotly users :-).
We also recommend reading the great how to contribute to open source guide.
Open an issue! Go to https://github.com/plotly/plotly.py/issues. It's possible that your issue was already addressed. If it wasn't, open it. We also accept pull requests; take a look at the steps below for instructions on how to do this.
Check out our Community Forum: https://community.plot.ly/.
Thank you! Instructions on how to contribute to the documentation are given here. Please also read the next section if you need to setup a development environment.
Below we explain the technical aspects of contributing. It is not strictly necessary to follow all points (for example, you will not write tests when writing documentation, most of the time), but we want to make sure that you know how to deal with most cases.
Note that if you are modifying a single documentation page, you can do it directly on Github by clicking on the "Edit this page on GitHub" link, without cloning the repository.
First, you'll need to get our project. This is the appropriate clone command (if you're unfamiliar with this process, https://help.github.com/articles/fork-a-repo):
DO THIS (in the directory where you want the repo to live)
git clone https://github.com/your_github_username/plotly.py.git
cd plotly.py
Note: if you're just getting started with git, there exist great resources to learn and become confident about git, like http://try.github.io/.
You can use either conda or virtualenv to create a virtual environment for plotly development, e.g.:
conda create -n plotly-dev python=3.11
conda activate plotly-dev
As of May 2024 our dependencies have been tested against Python versions 3.8 to 3.11. We will support Python 3.12 and higher versions soon.
(plotly_dev) $ pip install -r packages/python/plotly/requires-optional.txt
Because Windows requires Visual Studio libraries to compile some of the optional dependencies, follow these steps to complete installation and avoid gdal-config errors.
(plotly_dev) $ conda install fiona
(plotly_dev) $ pip install -r packages/python/plotly/requires-optional.txt
(plotly_dev) $ pip install -e packages/python/plotly/
(plotly_dev) $ pip install -e packages/python/chart-studio/
(plotly_dev) $ pip install -e packages/python/plotly-geo/
Note: To test go.FigureWidget
locally, you'll need to generate the javascript bundle as follows:
cd packages/python/plotly/js
npm install && npm run build
Running pip install -e
will ensure that the installed packages links to your local development
directory, meaning that all changes you make reflect directly in your
environment (don't forget to restart the Jupyter kernel though!). For more
information see the
setuptools
and
pip
documentation on development mode.
This repo uses the Black code formatter,
and the pre-commit library to manage a git commit hook to
run Black prior to each commit. Both pre-commit and black are included in the
packages/python/plotly/requires-optional.txt
file, so you should have them
installed already if you've been following along.
To enable the Black formatting git hook, run the following from within your virtual environment.
(plotly_dev) $ pre-commit install
Now, whenever you perform a commit, the Black formatter will run. If the formatter makes no changes, then the commit will proceed. But if the formatter does make changes, then the commit will abort. To proceed, stage the files that the formatter modified and commit again.
If you don't want to use pre-commit
, then you can run black manually prior to making
a PR as follows.
(plotly_dev) $ black .
Third, don't work in the master
branch. As soon as you get your master branch ready, run:
DO THIS (but change the branch name)
git checkout -b my-dev-branch
... where you should give your branch a more descriptive name than my-dev-branch
Once you've made your changes (and hopefully written some tests, see below for more about testing...), make that pull request!
First update the version of the plotly.js
dependency in packages/python/plotly/js/package.json
.
Then run the updateplotlyjs
command with:
$ cd packages/python/plotly
$ python setup.py updateplotlyjs
This will download new versions of plot-schema.json
and plotly.min.js
from
the plotly/plotly.js
GitHub repository (and place them in
plotly/package_data
). It will then regenerate all of the graph_objs
classes based on the new schema.
For dev branches, it is also possible to use updateplotlyjsdev
in two configurations:
If your devbranch is part of the official plotly.js repository, you can use
python setup.py updateplotlyjsdev --devrepo reponame --devbranch branchname
to update to development versions of plotly.js
. This will fetch the plotly.js
in the CircleCI artifact of the branch branchname
of the repo reponame
. If --devrepo
or --devbranch
are omitted, updateplotlyjsdev
defaults using plotly/plotly.js
and master
respectively.
If you have a local repository of plotly.js
you'd like to try, you can run:
# In your plotly.js/ directory, prepare the package:
$ npm run build
$ npm pack
$ mv plotly.js-*.tgz plotly.js.tgz
# In your plotly.py/packages/python/plotly/ directory:
$ python setup.py updateplotlyjsdev --local /path/to/your/plotly.js/
We take advantage of two tools to run tests:
tox
, which is both a virtualenv management and test tool.pytest
, a powerful framework for unit testing.
Since our tests cover all the functionality, to prevent tons of errors from showing up and having to parse through a messy output, you'll need to install requires-optional.txt
as explained above.
After you've done that, go ahead and run the test suite!
pytest packages/python/plotly/plotly/tests/
Or for more verbose output:
pytest -v packages/python/plotly/plotly/tests/
Either of those will run every test we've written for the Python API. You can get more granular by running something like:
pytest packages/python/plotly/plotly/tests/test_core/
... or even more granular by running something like:
pytest plotly/tests/test_plotly/test_plot.py
or for a specific test function
pytest plotly/tests/test_plotly/test_plot.py::test_function
Running tests with tox is much more powerful, but requires a bit more setup.
You'll need to export an environment variable for each tox environment you wish to test with. For example, if you want to test with Python 3.9
and
Python 3.6
, but only care to check the core
specs, you would need to ensure that the following variables are exported:
export PLOTLY_TOX_PYTHON_39=<python binary>
export PLOTLY_TOX_PYTHON_36=<python binary>
Where the <python binary
is going to be specific to your development setup. As a more complete example, you might have this loaded in a .bash_profile
(or equivalent shell loader):
############
# tox envs #
############
export PLOTLY_TOX_PYTHON_39=python3.9
export PLOTLY_TOX_PYTHON_36=python3.6
export TOXENV=py39-core,py36-core
Where TOXENV
is the environment list you want to use when invoking tox
from the command line. Note that the PLOTLY_TOX_*
pattern is used to pass in variables for use in the tox.ini
file. Though this is a little setup, intensive, you'll get the following benefits:
tox
will automatically manage a virtual env for each environment you want to test in.- You only have to run
tox
and know that the module is working in all included Python versions.
Finally, tox
allows you to pass in additional command line arguments that are formatted in (by us) in the tox.ini
file, see {posargs}
. This is setup to help with our configuration of pytest markers, which are set up in packages/python/plotly/pytest.ini
. To run only tests that are not tagged with nodev
, you could use the following command:
tox -- -a '!nodev'
Note that anything after --
is substituted in for {posargs}
in the tox.ini. For completeness, because it's reasonably confusing, if you want to force a match for multiple pytest
marker tags, you comma-separate the tags like so:
tox -- -a '!nodev','!matplotlib'
You're strongly encouraged to write tests that check your added functionality.
When you write a new test anywhere under the tests
directory, if your PR gets accepted, that test will run in a virtual machine to ensure that future changes don't break your contributions!
Test accounts include: PythonTest
, PlotlyImageTest
, and PlotlyStageTest
.