Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
47 changed files
with
13,517 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
*.swp | ||
*.swc | ||
*.pyc | ||
docs/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
``compose`` -- easy figure composing | ||
------------------------------------ | ||
|
||
``compose`` module is a wrapper on top of :py:mod:`svgutils.transform` that | ||
simplifies composing SVG figures. Here is a short example of how a figure could | ||
be constructed:: | ||
|
||
Figure( "10cm", "5cm", | ||
SVG('svg_logo.svg').scale(0.2), | ||
Image(120, 120, 'lion.jpeg').move(120, 0) | ||
).save('test.svg') | ||
|
||
.. automodule:: svgutils.compose | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,19 @@ | ||
.. svgutils documentation master file, created by | ||
sphinx-quickstart on Tue Apr 12 21:52:16 2011. | ||
You can adapt this file completely to your liking, but it should at least | ||
contain the root `toctree` directive. | ||
Welcome to svgutils's documentation! | ||
==================================== | ||
|
||
Contents: | ||
Contents | ||
======== | ||
|
||
.. toctree:: | ||
:numbered: | ||
:maxdepth: 2 | ||
|
||
tutorial/tutorial.rst | ||
tutorials | ||
reference | ||
|
||
Indices and tables | ||
================== | ||
|
||
* :ref:`genindex` | ||
* :ref:`modindex` | ||
* :ref:`search` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Reference | ||
--------- | ||
|
||
.. toctree:: | ||
|
||
transform | ||
compose |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
``transform`` -- basic SVG transformations | ||
------------------------------------------ | ||
|
||
This module implements low-level API allowing to open and manipulate SVG files. | ||
An example use is described in the :doc:`tutorials/publication_quality_figures` | ||
tutorial. | ||
|
||
.. automodule:: svgutils.transform | ||
:members: |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Tutorials | ||
--------- | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
tutorials/publication_quality_figures.rst | ||
tutorials/composing_multipanel_figures.rst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
Composing multi-panel figures | ||
============================= | ||
|
||
As I already explained in the previous tutorial, creating figures | ||
programmatically has many advantages. However, obtaining a complex | ||
layout only by scripting can be very time consuming and even | ||
distressing. Therefore, the possible gains can be crippled by the | ||
time spent tweaking the programs to obtain optimal results and under | ||
time pressure many of us resort to visual editors. One way to alleviate | ||
the problem is to use a library with little boilerplate code and which | ||
simplifies the common tasks (such as inserting a new panel and adjusting | ||
its position). That's why I introduced the :doc:`compose` module, which | ||
is a wrapper around the low-level API described in :doc:`publication_quality_figures`. | ||
|
||
Let's take the example from the previous tutorial | ||
|
||
.. figure:: figures/fig_final.png | ||
|
||
To obtain this nicely-formatted final figure we needed a :ref:`considerable <transform-example-code>` amount of code. | ||
The same effect could be achieved in ``compose`` with fewer lines of code: | ||
|
||
.. literalinclude:: scripts/fig_compose.py | ||
|
||
The ``compose`` module offers the same functionality as the ``transform``, but | ||
rather than being based on procedural description of the figure it attempts | ||
declarative approach. The code defining the figure mimics a hierarchical | ||
structure typical of most figures: A figure contains multiple panels; these panels can in | ||
turn contain several graphical elements such as text, markers or other | ||
(sub-)panels. | ||
|
||
Defining a figure | ||
----------------- | ||
|
||
Before we start we need to import the definitions from ``svgutils.compose`` module:: | ||
|
||
from svgutils.compose import * | ||
|
||
In `compose` the top-most element is the ``Figure()`` object. To create a figure we need to specify | ||
its size (width and height) and its contents. For example, to create a figure consisting of a single | ||
imported SVG file we might write:: | ||
|
||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg") | ||
) | ||
|
||
This will create a 16-by-6.5 cm figure with showing the ``sigmoid_fit.svg`` file. | ||
Note that the dimensions can be defined together with units supported by SVG | ||
(so far "px" and "cm" are implemented). If no units are defined it defaults | ||
to "px". ``SVG()`` is another object from ``compose`` module, which simply | ||
parses and pastes the content of a SVG file into the figure. | ||
|
||
The ``Figure()`` object also defines several methods; the ``save()`` method | ||
saves the figure in a SVG file: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex1.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg") | ||
).save("fig1.svg") | ||
.. figure:: figures/composing_multipanel_figures/ex1.svg | ||
|
||
Adding annotations | ||
------------------ | ||
|
||
The simple example of previous section is superfluous, because it does not modify the ``sigmoid_fit.svg`` | ||
file apart from changing its size. Let us try then overlaying some text on top of the figure. | ||
In ``compose`` we can add text using ``Text()`` object: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex1a.svg>` | ||
Figure("16cm", "6.5cm", | ||
Text("A", 25, 20), | ||
SVG("sigmoid_fit.svg") | ||
) | ||
In addition to the text itself we defined the $x$ and $y$ coordinates of the text element in pixel units. | ||
We can also add additional style arguments -- to increase the font size and change to bold letters we can use: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex1b.svg>` | ||
Figure("16cm", "6.5cm", | ||
Text("A", 25, 20, size=12, weight='bold'), | ||
SVG("sigmoid_fit.svg") | ||
) | ||
.. figure:: figures/composing_multipanel_figures/ex1b.svg | ||
|
||
Arranging multiple elements | ||
--------------------------- | ||
|
||
We can combine multiple SVG drawings by simply listing them inside the ``Figure()`` object: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex2.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg"), | ||
SVG("anscombe.svg") | ||
) | ||
The problem with this | ||
figure is that the drawings will overlap and become quite unreadable. To avoid it | ||
we have to move figure elements. To do that automatically you | ||
can use ``tile()`` method of ``Figure()``, which arranges the elements | ||
on a regular two-dimensional grid. For example, to arrange the two SVG elements | ||
in a single row we might use: | ||
|
||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex3.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg"), | ||
SVG("anscombe.svg") | ||
).tile(2, 1) | ||
The second figure (:file:`anscombe.svg`) does not fit entirely in the figure so | ||
we have to scale it down. For this aim each element of the Figure exposes a ``scale()`` | ||
method, which takes the scaling factor as its sole argument: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex3b.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg"), | ||
SVG("anscombe.svg").scale(0.5) | ||
).tile(2, 1) | ||
.. figure:: figures/composing_multipanel_figures/ex3b.svg | ||
|
||
|
||
For more control over the final figure layout we can position the | ||
individual elements using their ``move()`` method: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex4.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg"), | ||
SVG("anscombe.svg").move(280, 0) | ||
) | ||
This will move the ``ansombe.svg`` 280 px horizontally. Methods can be also | ||
chained: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex5.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg"), | ||
SVG("anscombe.svg").scale(0.5) | ||
.move(280, 0) | ||
) | ||
It's often difficult to arrange the figures correctly and it can involve mundane | ||
going back and fro between the code and generated SVG file. To ease the process | ||
``compose`` offers several helper objects: The ``Grid()`` object generates a grid of | ||
horizontal and vertical lines labelled with their position in pixel units. To | ||
add it simply list ``Grid()`` as one of ``Figure()`` elements: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex6.svg>` | ||
Figure("16cm", "6.5cm", | ||
SVG("sigmoid_fit.svg"), | ||
SVG("anscombe.svg").scale(0.5) | ||
.move(280, 0), | ||
Grid(20, 20) | ||
) | ||
The two parameters of ``Grid()`` define the spacing between the vertical and | ||
horizontal lines, respectively. You can use the lines and numerical labels to | ||
quickly estimate the required vertical and horizontal shifts of the figure | ||
elements. | ||
|
||
|
||
Grouping elements into panels | ||
----------------------------- | ||
|
||
Figures prepared for publications often consist of sub-panels, which can | ||
contain multiple elements such as graphs, legends and annotations (text, arrows | ||
etc.). Although it is possible to list all these elements separately in the | ||
``Figure()`` object, it's more convenient to work with all elements belonging to | ||
a single panel as an entire group. In ``compose`` one can group the elements | ||
into panels using ``Panel()`` object: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex7.svg>` | ||
Figure("16cm", "6.5cm", | ||
Panel( | ||
Text("A", 25, 20), | ||
SVG("sigmoid_fit.svg") | ||
), | ||
Panel( | ||
Text("B", 25, 20).move(280, 0), | ||
SVG("anscombe.svg").scale(0.5) | ||
.move(280, 0) | ||
) | ||
) | ||
``Panel()`` just like a ``Figure()`` object takes a list of elements such as | ||
text objects or SVG drawings. However, in contrast to ``Figure()`` it does not | ||
allow to define the size and does not offer ``save()`` method. The two ``Panel()`` | ||
objects of this example contain each a text element and a SVG file. | ||
|
||
In this example the ``Panel()`` | ||
object serve no other role than grouping elements that refer to a single panel | ||
-- it may enhance the readability of the code generating the figure, but it does | ||
not simplify the task of creating the figure. In the second ``Panel()`` we apply | ||
twice the method ``move()`` to position both the text element and the SVG. The | ||
advantage of ``Panel()`` is that we can apply such transforms to the entire | ||
panel: | ||
|
||
.. code-block:: python | ||
:caption: :download:`Figure preview <figures/composing_multipanel_figures/ex8.svg>` | ||
Figure("16cm", "6.5cm", | ||
Panel( | ||
Text("A", 25, 20), | ||
SVG("sigmoid_fit.svg") | ||
), | ||
Panel( | ||
Text("B", 25, 20), | ||
SVG("anscombe.svg").scale(0.5) | ||
).move(280, 0) | ||
) | ||
This way we simplified the code, but also the change allows for easier | ||
arrangement of the panels. An additional advantage is that the ``tile()`` method | ||
will automatically arrange the entire panels not the individual elements. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
all: | ||
python ../scripts/anscombe.py | ||
python ../scripts/sigmoid_fit.py | ||
python ../scripts/fig_final.py | ||
python ../scripts/fig_compose.py |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.