Feel free to report all issues you encounter with plotID in our issue tracker. This will greatly help to improve plotID.
Contributing to plotID via merge requests is also highly appreciated. Please make sure that your code complies with the PEP 8 - Style Guide before creating a merge request. We enforce the black code style. We try to have the whole code of plotID covered by unittests. So if you contribute new code to plotid please also provide unittests that cover the new functionality. Should you be interested in adding another plot engine to be supported by plotID, have a look at the section Implement a new plot engine. There are some hints how to proceed in this case.
Clone the repository and install the dependencies:
git clone https://git.rwth-aachen.de/plotid/plotid_python.git
cd plotid_python
pip install -r requirements.txtOptionally, create a virtual environment as recommended in the README.md.
You can run all the unittests locally by calling the tests/runner_tests.py script. For linting we recommend using flake8 and pylint.
The documentation is automatically built from docstrings in the code. So always document your code properly. The documentation can be built locally and can be found afterwards in docs/build:
cd docs
make htmlIf you want to add another plot engine "$engine" to plotID, this section helps you to do it. For comparison have a look at already supported engines, e.g. in tagplot_matplotlib.py or tagplot_image.py.
Create a new module named "tagplot_$engine.py". Paste the following code and replace every "$engine" with the name of your engine:
"""
Tag your picture with an ID.
Functions:
tagplot_$engine(PlotOptions instance) -> PlotIDTransfer instance
"""
import $engine
from plotid.create_id import create_id
from plotid.plotoptions import PlotOptions, PlotIDTransfer
def tagplot_$engine(plotid_object):
"""
Add IDs to plots with $engine.
The ID is placed visual on the figure window and returned as string in a
list together with the figures.
Parameters
----------
plotid_object : instance of PlotOptions
Returns
-------
PlotIDTransfer object
"""
# Check if plotid_object is a valid instance of PlotOptions
if not isinstance(plotid_object, PlotOptions):
raise TypeError('The given options container is not an instance'
'of PlotOptions.')
# Check if figs is a list of valid figures
for figure in plotid_object.figs:
if not isinstance(figure, $engine_figure_class):
raise TypeError('Figure is not a valid $engine-figure.')
# Loop to create and position the IDs
for fig in plotid_object.figs:
fig_id = create_id(plotid_object.id_method)
fig_id = plotid_object.prefix + fig_id
plotid_object.figure_ids.append(fig_id)
"""
Insert here the tagging with $engine:
Open the figure fig.
Place the string figure_id on it.
Use plotid_object.position and plotid_object.rotation for position and rotation of the ID.
Save the tagged figure to plotid_object.figs.
"""
figs_and_ids = PlotIDTransfer(plotid_object.figs, plotid_object.figure_ids)
return figs_and_idsLast step: Add the following code in tagplot.py:
match engine:
[...]
case '$engine':
return tagplot_$engine(option_container)
case _:
[...]To include a new plot engine in the publish function only save_plot.py has to be touched.
Import the plot engine at the top of the file.
In the beginning of the function save_plot() create the following line:
if isinstance(figures, $engine_figure_class):
figures = [figures]
[...]
if not isinstance(figures, list):
raise TypeError('Figures are not given as list.')This allows to iterate through all figures, even if it is only one. It must be placed before the line that checks if figures is a list.
Create a new elif condition in the for loop:
for i, fig in enumerate(figures):
[...]
elif isinstance(fig, $type_of_figure):
# Read/Open the figure fig if necessary
plot_path.append(plot_names[i] + '.' + extension)
# Save the figure fig to plot_path[i]Additionally, please add some unittests for your code inside the tests directory.
In the end, you can also include a simple example in the examples directory how the newly plot engine can be used with plotID.