Skip to content

Commit 1e10521

Browse files
Add documentation, readme (#1)
* Added readme * added zenodo link * basic documentation --------- Co-authored-by: Christoph Fink <christoph.fink@christophfink.com>
1 parent 038a3ab commit 1e10521

22 files changed

Lines changed: 2455 additions & 8 deletions

.readthedocs.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
version: 2
22

33
build:
4-
os: ubuntu-20.04
4+
os: ubuntu-22.04
55
tools:
6-
python: "3.10"
6+
python: "3.12"
77

88
python:
99
install:
10-
- requirements: docs/requirements.txt
11-
system_packages: true
10+
- method: pip
11+
path: .
12+
extra_requirements:
13+
- docs
1214

1315
sphinx:
1416
configuration: docs/conf.py
17+
fail_on_warning: true

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
- **0.0.1** (2022-04-11):
1+
- **0.0.2** (2024-07-15):
2+
- added documentation
3+
4+
- **0.0.1** (2024-07-15):
25
- very first release

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Compute continous cartograms (anamorphic maps)
2+
3+
This is a Python package to compute cartograms from `geopandas.GeoDataFrames`, using the algorithm presented in [Dougenik et al. (1985)](http://www.tandfonline.com/doi/abs/10.1111/j.0033-0124.1985.00075.x). It is the ‘sister project’ and Python implementation of our [QGIS plugin](https://github.com/austromorph/cartogram3) which continues to be available.
4+
5+
6+
## Installation
7+
8+
`cartogram` is available from the [PyPi package
9+
repository](https://pypi.org/project/cartogram), install it, for instance, using `pip`:
10+
11+
```
12+
pip install cartogram
13+
```
14+
15+
16+
## Quick start
17+
18+
### Input data
19+
20+
You will need a polygon data set [in any format readable by
21+
`geopandas`](https://geopandas.org/en/stable/docs/user_guide/io.html) that
22+
features a numeric attribute column to use as the relative target values to base
23+
the cartogram distortion on.
24+
25+
If you want to have a quick try-out, see the population data for Austrian
26+
provinces in the [`tests/data`](tests/data) directory of this repository.
27+
28+
### Cartogram creation
29+
30+
```
31+
import cartogram
32+
import geopandas
33+
34+
df = geopandas.read_file("input-data.gpkg")
35+
c = cartogram.Cartogram(df, column="population")
36+
37+
c.to_file("output-data.gpkg")
38+
```
39+
40+
## Documentation
41+
42+
Find more detailed examples and an API reference at <https://python-cartogram.readthedocs.io/>.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/usr/bin/env python3
2+
3+
"""Modify the bibliography entries created by sphinxcontrib.bibtex to be sphinx-design cards."""
4+
5+
# The default `:::{bibliography}` blocks are not very nicely formatted.
6+
# In the docutils tree, they look like this:
7+
#
8+
# <citation backrefs="id2" docname="user-guide/user-manual/travel-time-matrices" ids="fink-r5py-2022">
9+
# <label support_smartquotes="False">
10+
# Fink et al., 2022
11+
# </label>
12+
# <paragraph>
13+
# Fink, C., Klumpenhouwer, W., Saraiva, M., Pereira, R., & Tenkanen, H.
14+
# (2022 , September). <emphasis>r5py: Rapid Realistic Routing with R5 in
15+
# Python</emphasis>.
16+
# <reference refuri="https://doi.org/10.5281/ZENODO.7060437">
17+
# DOI:10.5281/ZENODO.7060437
18+
# </reference>
19+
# </paragraph>
20+
# </citation>
21+
#
22+
# After experimenting with `sphinx-design`’s cards in the data-requirements.md
23+
# and also in early versions of the citations.md documents, I started to like
24+
# their look also for the references: They are prominent, cleanly formatted, and
25+
# can be clicked as a whole.
26+
#
27+
# In the docutil tree, they would look like this:
28+
#
29+
# <container classes="sd-card sd-sphinx-override sd-mb-3 sd-shadow-sm sd-card-hover" design_component="card" is_div="True">
30+
# <container classes="sd-card-body" design_component="card-body" is_div="True">
31+
# <paragraph classes="sd-card-text">
32+
# Fink, C., Klumpenhouwer, W., Saraiva, M., Pereira, R., & Tenkanen,
33+
# H., 2022: <emphasis>r5py: Rapid Realistic Routing with R⁵ in Python</emphasis>.
34+
# <reference refuri="https://doi.org/10.5281/zenodo.7060437">
35+
# DOI:10.5281/zenodo.7060437
36+
# </reference>
37+
# </paragraph>
38+
# </container>
39+
# <PassthroughTextElement>
40+
# <reference classes="['sd-stretched-link']" refuri="https://doi.org/10.5281/zenodo.7060437"/>
41+
# </PassthroughTextElement>
42+
# </container>
43+
#
44+
# This sphinx extension triggers at a very late stage of running sphinx,
45+
# searches for all <citations>, and converts them from the above subtree
46+
# to the below format
47+
# It uses the sphinx.transforms.post_transform hook, see
48+
# https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events
49+
50+
51+
import docutils.nodes
52+
import sphinx.transforms.post_transforms
53+
import sphinx_design.shared
54+
55+
56+
__version__ = "0.0.1"
57+
58+
59+
class CitationsToSphinxDesignCardsTransformer(
60+
sphinx.transforms.post_transforms.SphinxPostTransform
61+
):
62+
default_priority = (
63+
198 # before anything from sphinx_design, but after sphinxcontrib.bibtex
64+
)
65+
66+
def apply(self, **kwargs):
67+
for node in self.document.findall(docutils.nodes.citation):
68+
self.handle(node)
69+
70+
def handle(self, node):
71+
new_node = self._create_empty_sdcard_container()
72+
for attribute in ["backrefs", "docname", "ids"]:
73+
new_node[attribute] = node[attribute]
74+
75+
# paragraph (first child of first child), see _create_empty...()
76+
new_paragraph = new_node[0][0]
77+
old_paragraph = node[node.first_child_matching_class(docutils.nodes.paragraph)]
78+
new_paragraph.children = old_paragraph.children
79+
80+
# convert <tt> (docutils.nodes.literal) into more nicely formatted titles
81+
# (see also format_title() in ../_helpers/citation_style.py)
82+
for tt in new_paragraph.findall(docutils.nodes.literal):
83+
span = docutils.nodes.inline(classes=["article-title"])
84+
span += tt.children
85+
new_paragraph.replace(tt, span)
86+
87+
if r := new_paragraph.first_child_matching_class(docutils.nodes.reference):
88+
old_reference = new_paragraph[r]
89+
new_reference = sphinx_design.shared.PassthroughTextElement()
90+
new_reference += docutils.nodes.reference(
91+
classes=["sd-stretched-link"],
92+
refuri=old_reference["refuri"],
93+
)
94+
new_node += new_reference
95+
96+
# node.replace_self(new_node) # <- does not work - why?
97+
node.parent.replace(node, new_node)
98+
99+
@staticmethod
100+
def _create_empty_sdcard_container():
101+
container = docutils.nodes.container(
102+
classes=[
103+
"sd-card",
104+
"sd-sphinx-override",
105+
"sd-mb-3",
106+
"sd-shadow-sm",
107+
"sd-card-hover",
108+
],
109+
design_component="card",
110+
is_div="True",
111+
)
112+
container += docutils.nodes.container(
113+
classes=["sd-card-body"],
114+
design_component="card-body",
115+
is_div="True",
116+
)
117+
container[0] += docutils.nodes.paragraph(
118+
classes=["sd-card-text"],
119+
)
120+
return container
121+
122+
123+
def setup(app):
124+
"""
125+
Register extension with sphinx.
126+
127+
This is a callback function called by sphinx when it loads the extension.
128+
"""
129+
app.add_post_transform(CitationsToSphinxDesignCardsTransformer)
130+
131+
return {
132+
"parallel_read_safe": True,
133+
"parallel_write_safe": False, # not sure, but let’s err on the safe side
134+
}

docs/_extensions/bibliography_as_sphinxdesign_cards/__main__.py

Whitespace-only changes.

docs/_helpers/binder_ref.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python
2+
3+
"""Find a Git reference (branch/commit) to open in Binder."""
4+
5+
# if we are building a stable version,
6+
# point the binder link to branch `stable`,
7+
# otherwise, point to branch `main`
8+
9+
10+
import git
11+
import os
12+
13+
14+
__all__ = ["BINDER_REF"]
15+
16+
17+
def get_binder_ref():
18+
try:
19+
READTHEDOCS_VERSION = os.environ["READTHEDOCS_VERSION"]
20+
except KeyError: # not running on RTD
21+
READTHEDOCS_VERSION = ""
22+
23+
if READTHEDOCS_VERSION == "stable":
24+
binder_ref = "stable" # stable is synced with last version tag/release
25+
elif READTHEDOCS_VERSION == "latest":
26+
binder_ref = "main"
27+
else:
28+
repository = git.Repo(search_parent_directories=True)
29+
binder_ref = repository.git.rev_parse(repository.head.commit.hexsha, short=True)
30+
return binder_ref
31+
32+
33+
BINDER_REF = get_binder_ref()

0 commit comments

Comments
 (0)