Skip to content

Commit

Permalink
Draft README
Browse files Browse the repository at this point in the history
  • Loading branch information
mmore500 committed Dec 29, 2023
1 parent 55462de commit ca2f8ca
Show file tree
Hide file tree
Showing 14 changed files with 279 additions and 40 deletions.
306 changes: 266 additions & 40 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,282 @@
:alt: teeplot wordmark


.. image:: https://img.shields.io/pypi/v/teeplot.svg
:target: https://pypi.python.org/pypi/teeplot
*teeplot* wrangles your data visualizations out of notebooks for you
--------------------------------------------------------------------

.. image:: https://github.com/mmore500/teeplot/actions/workflows/CI.yml/badge.svg
:target: https://github.com/mmore500/teeplot/actions/workflows/CI.yml
|PyPi| |docs| |GitHub stars| |CI|

* Free software: MIT license
* Installation: ``python3 -m pip install teeplot``
* Documentation: https://github.com/mmore500/teeplot/blob/master/README.rst
* Repository: https://github.com/mmore500/teeplot

teeplot organizes saving data visualizations, automatically picking meaningful names based on semantic plotting variables
*teeplot*'s ``tee`` function can wrap your plotting calls to **automatically manage matplotlib file output**, picking meaningful names based on semantic plotting variables.

Usage
-----

* Free software: MIT license
* Documentation: https://teeplot.readthedocs.io.


.. code-block:: python3
from teeplot import teeplot as tp
import seaborn as sns
# adapted from https://seaborn.pydata.org/examples/errorband_lineplots.html
tp.tee(
sns.lineplot,
x='timepoint',
y='signal',
hue='region',
style='event',
data=sns.load_dataset('fmri'),
teeplot_outattrs={
'additional' : 'metadata',
'for' : 'output-filename',
},
)
tp.tee(
sns.catplot,
data=sns.load_dataset('penguins'),
kind='bar',
x='species',
y='body_mass_g',
hue='sex',
ci='sd',
palette='dark',
alpha=.6,
height=6,
)
Example 1
^^^^^^^^^
.. code-block:: python
# adapted from https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.box.html
import pandas as pd
from teeplot import teeplot as tp
age_list = [8, 10, 12, 14, 72, 74, 76, 78, 20, 25, 30, 35, 60, 85]
df = pd.DataFrame({"gender": list("MMMMMMMMFFFFFF"), "age": age_list})
tp.tee(
df.plot.box, # plotter...
column="age", # ...forwarded kwargs
by="gender",
figsize=(4, 3),
)
..
.. code-block:: python
teepots/by=gender+column=age+viz=box+ext=.pdf
teepots/by=gender+column=age+viz=box+ext=.png
.. image:: docs/assets/by=gender+column=age+viz=box+ext=_padded.png

----

Example 2
^^^^^^^^^
.. code-block:: python
# adapted from https://matplotlib.org/stable/tutorials/pyplot.html
from matplotlib import pyplot as plt
import numpy as np
from teeplot import teeplot as tp
data = {'a': np.arange(50),
'c': np.random.randint(0, 50, 50),
'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
saveit, __ = tp.tee(
plt.scatter, # plotter...
data=data, # ...forwarded kwargs
x='a',
y='b',
c='c',
s='d',
teeplot_callback=True,
)
plt.xlabel('entry a')
plt.ylabel('entry b')
plt.gcf().set_size_inches(5, 3)
saveit()
..
.. code-block:: python
teepots/c=c+s=d+viz=scatter+x=a+y=b+ext=.pdf
teepots/c=c+s=d+viz=scatter+x=a+y=b+ext=.png
.. image:: docs/assets/c=c+s=d+viz=scatter+x=a+y=b+ext=_padded.png

----

Example 3
^^^^^^^^^
.. code-block:: python
# adapted from https://seaborn.pydata.org/examples/horizontal_boxplot.html
from matplotlib import pyplot as plt
import seaborn as sns
from teeplot import teeplot as tp
callback, ax = tp.tee(
sns.boxplot, # plotter...
sns.load_dataset("planets"), # ...forwarded kwargs
x="distance",
y="method",
hue="method",
palette="vlag",
whis=[0, 100],
width=.6,
teeplot_callback=True,
teeplot_postprocess="teed.set_xscale('log')",
)
ax.xaxis.grid(True)
ax.set(ylabel="")
sns.despine()
plt.gcf().set_size_inches(10, 4)
callback()
..
.. code-block::
teepots/hue=method+palette=vlag+post=teed-set-xscale-log+viz=boxplot+x=distance+y=method+ext=.pdf
teepots/hue=method+palette=vlag+post=teed-set-xscale-log+viz=boxplot+x=distance+y=method+ext=.png
.. image:: docs/assets/hue=method+palette=vlag+post=teed-set-xscale-log+viz=boxplot+x=distance+y=method+ext=_padded.png

----

Example 4
^^^^^^^^^
.. code-block:: python
# adapted from https://seaborn.pydata.org/generated/seaborn.FacetGrid.html#seaborn.FacetGrid
import seaborn as sns
from teeplot import teeplot as tp
tp.tee(
sns.FacetGrid, # plotter...
sns.load_dataset("tips"), # ...forwarded kwargs
aspect=1.5,
col="time",
hue="sex",
teeplot_postprocess="teed.map_dataframe(sns.scatterplot, x='total_bill', y='tip')",
)
..
.. code-block::
teepots/col=time+hue=sex+post=teed-map-dataframe-sns-scatterplot-x-total-bill-y-tip+viz=facetgrid+ext=.pdf
teepots/col=time+hue=sex+post=teed-map-dataframe-sns-scatterplot-x-total-bill-y-tip+viz=facetgrid+ext=.png
.. image:: docs/assets/col=time+hue=sex+post=teed-map-dataframe-sns-scatterplot-x-total-bill-y-tip+viz=facetgrid+ext=_padded.png

----

Example 5
^^^^^^^^^
.. code-block:: python
# adapted from https://seaborn.pydata.org/generated/seaborn.FacetGrid.html#seaborn.FacetGrid
import seaborn as sns
from teeplot import teeplot as tp
tp.tee(
sns.lmplot, # plotter...
sns.load_dataset("tips"), # ...forwarded kwargs
col="time",
hue="sex",
x="total_bill",
y="tip",
teeplot_postprocess=sns.FacetGrid.add_legend,
)
pass # prevent notebook from echoing last object, if any
..
.. code-block::
teepots/col=time+hue=sex+post=add_legend+viz=lmplot+x=total-bill+y=tip+ext=.pdf
teepots/col=time+hue=sex+post=add_legend+viz=lmplot+x=total-bill+y=tip+ext=.png
.. image:: docs/assets/col=time+hue=sex+post=add_legend+viz=lmplot+x=total-bill+y=tip+ext=_padded.png

----

Example 6
^^^^^^^^^
.. code-block:: python
# adapted from https://seaborn.pydata.org/examples/pairgrid_dotplot.html
import seaborn as sns
def dot_plot(data, x_vars, y_vars):
g = sns.PairGrid(data.sort_values("total", ascending=False),
x_vars=x_vars, y_vars=y_vars,
height=5, aspect=0.66)
g.map(sns.stripplot, size=10, orient="h", jitter=False,
palette="flare_r", linewidth=1, edgecolor="w")
for ax in g.axes.flat:
ax.xaxis.grid(False)
ax.yaxis.grid(True)
data = sns.load_dataset("car_crashes")
tp.tee(
dot_plot,
data[data["abbrev"].str.contains("A")],
x_vars=data.columns[:-3],
y_vars=["abbrev"],
teeplot_outinclude=["x_vars", "y_vars"],
teeplot_save={".eps", ".png"},
)
..
.. code-block::
teeplots/viz=dot-plot+x-vars=index-total-speeding-alcohol-not-distracted-no-previous-dtype-object+y-vars=abbrev+ext=.eps
teeplots/viz=dot-plot+x-vars=index-total-speeding-alcohol-not-distracted-no-previous-dtype-object+y-vars=abbrev+ext=.png


.. image:: docs/assets/viz=dot-plot+x-vars=index-total-speeding-alcohol-not-distracted-no-previous-dtype-object+y-vars=abbrev+ext=_padded.png



API
---

``tee()``
^^^^^^^^^

- Executes a plotting function and saves the resulting plot to specified formats using a descriptive filename automatically generated from plotting function arguments.
- Required parameters:
- ``plotter``: The plotting function to be executed.
- Optional kwargs:
- ``teeplot_dpi``: Resolution for rasterized components of saved plots, default is publication-quality 300 dpi.
- ``teeplot_oncollision``: Strategy for handling filename collisions: "error", "fix", "ignore", or "warn", default "warn"; inferred from environment if not specified.
- ``teeplot_outattrs``: Dict with additional key-value attributes to include in the output filename.
- ``teeplot_outdir``: Base directory for saving plots, default "teeplots".
- ``teeplot_outinclude``: Attribute keys to always include, if present, in the output filename.
- ``teeplot_outexclude``: Attribute keys to always exclude, if present, from the output filename.
- ``teeplot_postprocess``: Actions to perform after plotting but before saving. Can be a string of code to ``exec`` or a callable function. If a string, it's executed with access to ``plt`` and ``sns`` (if installed), and the plotter return value as ``teed``. If a callable, invocation is attempted with the plotter return value then with no arguments (see docstring for full details).
- ``teeplot_save``: File formats to save the plots in. Defaults to global settings if ``True``, all output suppressed if ``False``. Default global setting is ``{".png", ".pdf"}``. Supported: ".eps", ".png", ".pdf", ".ps", ".svg".
- ``teeplot_subdir``: Optionally, subdirectory within the main output directory for plot organization.
- ``teeplot_transparent``: Option to save the plot with a transparent background, default True.
- ``teeplot_verbose``: Toggles printing of saved filenames, default True.
- Args and other kwargs:
- forwarded to the plotting function and used to build the output filename.

Module-Level Configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^

- ``draftmode``: A boolean indicating whether to suppress output to all file formats.
- ``oncollision``: Default strategy for handling filename collisions, with options like 'error', 'fix', 'ignore', or 'warn'.
- ``save``: A dictionary setting the default save behavior for different file formats as ``True`` (always output), ``False`` (never output), or ``None`` (defer to call kwargs).

Environment Variables
^^^^^^^^^^^^^^^^^^^^^

- ``TEEPLOT_ONCOLLISION``: Configures the default collision handling strategy. See ``teeplot_oncollision`` kwarg
- ``TEEPLOT_DRAFTMODE``: If set, enables draft mode globally.
- ``TEEPLOT_<FORMAT>``: Boolean flags that determine default behavior for each format (e.g., ``EPS``, ``PNG``, ``PDF``, ``PS``, ``SVG``); "defer" defers to call kwargs.
- ``CI``, etc.: If a continuous integration environment is detected, default ``teeplot_save`` behavior will output only ``.pdf`` files, instead of ``.pdf`` and ``.png`` files. This can be overridden with ``TEEPLOT_<FORMAT>``.

Credits
-------

Output filenames are constructed using the `keyname <https://github.com/mmore500/keyname>`_ package.

This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage

.. |PyPi| image:: https://img.shields.io/pypi/v/outset.svg
:target: https://pypi.python.org/pypi/outset
.. |CI| image:: https://github.com/mmore500/outset/actions/workflows/CI.yml/badge.svg
:target: https://github.com/mmore500/outset/actions
.. |GitHub stars| image:: https://img.shields.io/github/stars/mmore500/outset.svg?style=round-square&logo=github&label=Stars&logoColor=white
:target: https://github.com/mmore500/outset
.. |docs| image:: https://img.shields.io/badge/docs%20-%20readme%20-%20fedcba?logo=github
:target: https://github.com/mmore500/teeplot/blob/master/README.rst
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/c=c+s=d+viz=scatter+x=a+y=b+ext=.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions docs/assets/pad_images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

for img in *=.png; do
echo "img ${img}"
# Get current dimensions of the image.
height=$(identify -format "%h" "$img") # Height of the current image

# Calculate the desired width for a 4:1 aspect ratio.
desired_width=$((4 * height))

# Add padding to the left and right sides of the image.
convert "$img" -gravity center -background white -extent "${desired_width}x${height}" "${img%.png}_padded.png"
done
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ca2f8ca

Please sign in to comment.