Skip to content

Commit

Permalink
V2.0.0 (#58)
Browse files Browse the repository at this point in the history
* WIP

* Update README

* Update README

* WIP

* WIP

* WIP

* Update docstrings etc

* Update documentation

* Fix bugs and typos

* Update documentation

* Update documentation

* Fix bug
  • Loading branch information
domvwt authored Sep 22, 2021
1 parent 711741f commit 6222017
Show file tree
Hide file tree
Showing 42 changed files with 4,141 additions and 14,771 deletions.
8 changes: 6 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
[flake8]
max-line-length = 120
exclude = scratch.*, docs/
ignore = W503 # line break before binary operator
per-file-ignores = __init__.py:E402, F401
ignore =
W503, # line break before binary operator
E203, # whitespace before ':'
per-file-ignores =
__init__.py:E402, F401
_cdnlinks.py:E501
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ python:

env:
- EXTRA_INSTALLS=""
- EXTRA_INSTALLS="ipython pandas matplotlib bokeh plotly kaleido weasyprint beautifulsoup4 html5lib"
- EXTRA_INSTALLS="ipython pandas matplotlib bokeh plotly kaleido weasyprint<53 beautifulsoup4 html5lib"

install:
- pip install . pytest coverage $EXTRA_INSTALLS
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test-all: ## run tests on every Python version with tox
python -m tests.check_package_version

coverage: ## check code coverage quickly with the default Python
coverage run --source esparto -m pytest
-coverage run --source esparto -m pytest
coverage report -m
coverage html
# $(BROWSER) htmlcov/index.html
Expand Down
123 changes: 45 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,43 @@ esparto


## Introduction
`esparto` is a simple HTML and PDF document generator for Python.
The library takes a fully Pythonic approach to defining documents,
allowing iterative building and modification of the page and its contents.
**esparto** is a Python package for building shareable reports with content
from popular data analysis libraries.
With just a few lines of code, **esparto** turns DataFrames, plots, and
Markdown into an interactive webpage or PDF document.

Documents produced by **esparto** are completely portable - no backend server
is required - and entirely customisable using CSS and Jinja templating.
All content dependencies are declared inline or loaded via a CDN, meaning your
reports can be shared by email, hosted on a standard http server, or made
available as static pages as-is.

### Example Use Cases
* Automated MI reporting
* Collating and sharing data visualisations
* ML model performance and evaluation documents
* Designing simple web pages

## Basic Usage
```python
import esparto as es
page = es.Page(title="My Report")
page["Data Analysis"] = (pandas_dataframe, plotly_figure)
page.save_html("my-report.html")
```


## Main Features
* Lightweight API
* Jupyter Notebook support
* Output self-contained HTML and PDF files
* Responsive layout from [Bootstrap](https://getbootstrap.com/)
* No CSS or HTML required
* Implicit conversion for:
* Automatic and adaptive layout
* Customisable with CSS or Jinja
* Jupyter Notebook friendly
* Output as HTML or PDF
* Built-in adaptors for:
* Markdown
* Images
* Pandas DataFrames
* Matplotlib
* Bokeh
* Plotly
* [Pandas DataFrames][Pandas]
* [Matplotlib][Matplotlib]
* [Bokeh][Bokeh]
* [Plotly][Plotly]


## Installation
`esparto` is available from PyPI:
**esparto** is available from PyPI:
```bash
pip install esparto
```
Expand All @@ -54,7 +62,8 @@ pip install weasyprint
* [jinja2](https://palletsprojects.com/p/jinja/)
* [markdown](https://python-markdown.github.io/)
* [Pillow](https://python-pillow.org/)
* [weasyprint](https://weasyprint.org/) _(optional - for PDF output)_
* [PyYAML](https://pyyaml.org/)
* [weasyprint](https://weasyprint.org/) _(optional - required for PDF output)_


## License
Expand All @@ -64,69 +73,27 @@ pip install weasyprint
## Documentation
Full documentation and examples are available at [domvwt.github.io/esparto/](https://domvwt.github.io/esparto/).


## Basic Usage
```python
import esparto as es

# Instantiating a Page
page = es.Page(title="Research")

# Page layout hierarchy:
# Page -> Section -> Row -> Column -> Content

# Add or update content
# Keys are used as titles
page["Introduction"]["Part One"]["Item A"] = "./text/content.md"
page["Introduction"]["Part One"]["Item B"] = "./pictures/image1.jpg"

# Add content without a title
page["Introduction"]["Part One"][""] = "Hello, Wolrd!"

# Replace child at index - useful if no title given
page["Introduction"]["Part One"][-1] = "Hello, World!"

# Set content and return input object
# Useful in Jupyter Notebook as it will be displayed in cell output
page["Methodology"]["Part One"]["Item A"] << "dolor sit amet"
# >>> "dolor sit amet"

# Set content and return new layout
page["Methodology"]["Part Two"]["Item B"] >> "foobar"
# >>> {'Item B': ['Markdown']}

# Show document structure
page.tree()
# >>> {'Research': [{'Introduction': [{'Part One': [{'Item A': ['Markdown']},
# {'Item B': ['Image']}]}]},
# {'Methodology': [{'Part One': [{'Item A': ['Markdown']}]},
# {'Part Two': [{'Item A': ['Markdown']}]}]}]}

# Remove content
del page["Methodology"]["Part One"]["Item A"]
del page.methodology.part_two.item_b

# Access existing content as an attribute
page.introduction.part_one.item_a = "./pictures/image2.jpg"
page.introduction.part_one.tree()
# >>> {'Part One': [{'Item A': ['Image']},
# {'Item B': ['Image']},
# {'Column 2': ['Markdown']}]}

# Save the document
page.save_html("my-page.html")
page.save_pdf("my-page.pdf")
```
## Contributions, Issues, and Requests
All feedback and contributions are welcome - please raise an issue or pull request on [GitHub][GitHub].


## Example Output
Iris Report - [HTML](https://domvwt.github.io/esparto/examples/iris-report.html) |
## Examples
Iris Report - [Webpage](https://domvwt.github.io/esparto/examples/iris-report.html) |
[PDF](https://domvwt.github.io/esparto/examples/iris-report.pdf)

Bokeh and Plotly - [HTML](https://domvwt.github.io/esparto/examples/interactive-plots.html) |
Bokeh and Plotly - [Webpage](https://domvwt.github.io/esparto/examples/interactive-plots.html) |
[PDF](https://domvwt.github.io/esparto/examples/interactive-plots.pdf)

<br>

<img width=600 src="https://github.com/domvwt/esparto/blob/fdc0e787c0bc013d16667773e82e21c647b71d91/docs/images/iris-report-compressed.png?raw=true"
alt="example page" style="border-radius:0.5%;">
<p width=100%>
<img width=80% src="https://github.com/domvwt/esparto/blob/fdc0e787c0bc013d16667773e82e21c647b71d91/docs/images/iris-report-compressed.png?raw=true" alt="example page" style="border-radius:0.5%;">
</p>

<!-- Links -->
[Bootstrap]: https://getbootstrap.com/docs/4.6/getting-started/introduction/
[Pandas]: https://pandas.pydata.org/
[Matplotlib]: https://matplotlib.org/
[Bokeh]: https://docs.bokeh.org/en/latest/index.html
[Plotly]: https://plotly.com/
[GitHub]: https://github.com/domvwt/esparto
2 changes: 1 addition & 1 deletion docs/01-getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ my_page.save_html("esparto-quick.html")
```
<br>

The rendered HTML document:
The rendered web document:

<img src='../esparto-quickstart-screenshot.png' style='border: 1px dotted lightgrey; width: 60%; height: auto'>

Expand Down
9 changes: 9 additions & 0 deletions docs/02-user-guide/customisation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### Jinja

### CSS

#### Bootstrap Themes

### Layout Classes

### Content Classes
49 changes: 26 additions & 23 deletions docs/02-user-guide/examples.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,56 @@
# Examples
# Guides

These examples demonstrate recommended ways of working with `esparto`.
Note that Jupyter Notebooks do not preserve the formatting of rendered
content between sessions - be sure to re-run the examples in order to
view the output as intended.


## Getting Started

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/domvwt/esparto/blob/main/docs/examples/getting-started.ipynb)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/domvwt/esparto/main?filepath=docs%2Fexamples%2Fgetting-started.ipynb)
[![GitHub](https://img.shields.io/badge/view%20on-GitHub-lightgrey)](https://github.com/domvwt/esparto/blob/main/docs/examples/getting-started.ipynb)

A guided tour of the `esparto` API. This notebook covers:

* Working with different Content types
* Layout and formatting
* Page options
* Saving your work

---


## Data Analysis

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/domvwt/esparto/blob/main/docs/examples/iris-report.ipynb)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/domvwt/esparto/main?filepath=docs%2Fexamples%2Firis-report.ipynb)
[![GitHub](https://img.shields.io/badge/view%20on-GitHub-lightgrey)](https://github.com/domvwt/esparto/blob/main/docs/examples/iris-report.ipynb)

The iris dataset is one of the most well known datasets in statistics and
data science. This notebook shows how we can put together a simple
data analysis report in `esparto`.
This notebook shows how we can put together a simple data analysis in `esparto`.

This example covers:

* Text content with markdown formatting
* Text content with Markdown formatting
* Including images from files
* Converting a Pandas DataFrame to a table
* Adding plots from Matplotlib and Seaborn

Output: [HTML](../examples/iris-report.html) | [PDF](../examples/iris-report.pdf)
Output: [Webpage](../examples/iris-report.html) | [PDF](../examples/iris-report.pdf)

----



## Interactive Plotting
## Interactive Plots

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/domvwt/esparto/blob/main/docs/examples/interactive-plots.ipynb)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/domvwt/esparto/main?filepath=docs%2Fexamples%2Finteractive-plots.ipynb)
[![GitHub](https://img.shields.io/badge/view%20on-GitHub-lightgrey)](https://github.com/domvwt/esparto/blob/main/docs/examples/interactive-plots.ipynb)

The [pandas-bokeh](https://github.com/PatrikHlobil/Pandas-Bokeh) library
offers convenient functions for producing interactive Bokeh plots with
few lines of code.

With the [Plotly backend for Pandas](https://plotly.com/python/pandas-backend/)
we can access the Plotly Express API directly from the `.plot()` method of
any DataFrame or Series.

This notebook shows basic examples from each library:
This notebook shows basic examples from interactive plotting libraries:

* Interactive plotting with Bokeh and Plotly
* Adding interactive content to the page
* Bokeh
* Plotly

Output: [HTML](../examples/interactive-plots.html) | [PDF](../examples/interactive-plots.pdf)
Output: [Webpage](../examples/interactive-plots.html) | [PDF](../examples/interactive-plots.pdf)

!!! note
PDF output is not officially supported for `Bokeh` at this time.
Expand Down
75 changes: 75 additions & 0 deletions docs/02-user-guide/general-usage-old.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## Offline Mode
When working in an environment with no internet connection it is necessary to
use inline content dependencies rather than the preferred Content Distribution Network (CDN).


Offline mode can be activated by changing the relevant `esparto.options` attribute:
```python
import esparto as es

es.options.offline_mode = True
```

## Matplotlib Output
To produce sharp and scalable images, esparto defaults to SVG format for
static plots.
This can cause a significant drain on resources when plotting a high number
of data points and so PNG format may be preferred.

PNG format can be selected for all Matplotlib plots:
```python
es.options.matplotlib_output_format = "png"
```

Or configured on a case by case basis:
```python
fig = df.plot()
esparto_fig = es.FigureMpl(fig, output_format="png")
```

Options provided directly to `FigureMpl` will override the global configuration.

## PDF Output

### From the API
Saving a page to PDF is achieved through the API by calling the `.save_pdf()`
method from a `Page` object:

```python
import esparto as es

my_page = es.Page(title="My Page")
my_page += "image.jpg"
my_page.save_pdf("my-page.pdf)
```

In order to render plots for PDF output, they must be rendered to SVG. While
this leads to consistent and attractive results for Matplotlib figures, it is
less predictable and requires additional system configuration for Bokeh and
Plotly objects.

#### Plotly
The preferred approach with Plotly is to use the Kaleido library, which is installable
with pip:
```bash
pip install kaleido
```
Esparto will automatically handle the conversion, provided Kaleido is available.

Make sure to inspect results for unusual cropping and other artifacts.

#### Bokeh
The approach taken by Bokeh is to use a browser and webdriver combination.
I have not been able to make this work during testing but the functionality
has been retained in esparto should you have more luck with it.

See the Bokeh documenation on [additional dependencies for exporting plots.](https://docs.bokeh.org/en/latest/docs/user_guide/export.html#additional-dependencies)

Conversion should be handled by esparto, provided the Bokeh dependencies
are satisfied.

### Saving from a Browser
Alternatively, it is possible to save any HTML page as a PDF through the print
menu in your web browser. This method should work with all content types.

<br>
Loading

0 comments on commit 6222017

Please sign in to comment.