Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize docs and add a quickstart guide #33

Merged
merged 22 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
73eacdf
move notebooks to a docs/ directory, delete pdfs
keithchev Jul 1, 2024
3550fec
don't save figures and other minor edits in style usage notebook
keithchev Jul 1, 2024
38a8d83
revert notebook renaming
keithchev Jul 1, 2024
ed59395
fix formatting
keithchev Jul 1, 2024
540555a
increase title font size and padding
keithchev Jul 1, 2024
bf4bb9a
more edits to style_usage notebook
keithchev Jul 1, 2024
0f33d1e
add missing path to gitignore
keithchev Jul 1, 2024
b8564b5
rename style_axis to style_plot and the color 'lightgrey' to 'gray'
keithchev Jul 1, 2024
ee55508
first draft of quickstart guide
keithchev Jul 1, 2024
aaa88c0
add a readme for the docs directory
keithchev Jul 1, 2024
6cd3a16
edit quickstart, update main readme
keithchev Jul 1, 2024
4b1999d
fix typo
keithchev Jul 2, 2024
5210727
update color_usage notebook
keithchev Jul 2, 2024
caa13ef
update dependencies: remove ipykernel and add numpy
keithchev Jul 2, 2024
512b3bd
fix typo
keithchev Jul 2, 2024
d7d4448
rename brown_shades and grey_shades and use 'gray' instead of 'grey'
keithchev Jul 2, 2024
e91550e
add images to quickstart guide and minor edits
keithchev Jul 2, 2024
5d8387e
add missing lines
keithchev Jul 2, 2024
2ce638c
add more explicit links to the style_usage notebook
keithchev Jul 2, 2024
eaec7a9
add a makefile command to execute all jupyter notebooks in the docs dir
keithchev Jul 2, 2024
306e0ac
fix bugs in notebooks and update all notebook outputs
keithchev Jul 2, 2024
dc72775
add jupyter to dev deps and add section about updating the notebooks …
keithchev Jul 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
docs/output/
/test-outputs/

# packages installed in editable mode
Expand Down
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
include .env

DOCS_DIR := ./docs
JUPYTER_NOTEBOOKS := $(shell find $(DOCS_DIR) -type f -name '*.ipynb')

.PHONY: execute-all-notebooks
execute-all-notebooks:
@for file in $(JUPYTER_NOTEBOOKS); do \
echo "Executing notebook $$file"; \
jupyter execute --inplace $$file; \
done

.PHONY: lint
lint:
ruff check --exit-zero .
Expand Down
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
# arcadia-pycolor

Tools for using the Arcadia color palettes and figure style guide in Python.
This package automatically generate color palettes and color maps for use with Matplotlib.
This repo contains a Python package called `arcadia_pycolor` that provides tools for using the Arcadia color palettes and for styling Matplotlib figures to comply with Arcadia's style guide.

## Installation

TODO: write installation instructions once the package is hosted on PyPI.
The package is hosted on PyPI and can be installed using pip:

```bash
pip install arcadia-pycolor
```

## Usage

See [this notebook](usage_example.ipynb) for examples of how to use the color palettes and color maps in this package.
Please see [the quickstart guide](docs/quickstart.md) for an introduction to the package and how to use it to style Matplotlib and seaborn plots.

For detailed documentation about the package and links to example plots, see the [documentation README](docs/README.md).

## Development

### Environment setup

We use poetry to manage dependencies and packaging. First, create a new conda environment and install poetry:

```bash
Expand All @@ -32,7 +39,7 @@ Finally, install the package in editable mode:
pip install -e .
```

## Testing
### Testing

We use pytest for testing. The tests are found in the `arcadia_pycolor/tests/` subpackage. To run the tests, simply run `pytest` from the root directory of the repository.

Expand All @@ -50,6 +57,12 @@ Hint: you can use pytest's `-k` option to filter the tests that are run if you o
pytest -k barplots --output-dirpath ./test-outputs
```

### Updating the Jupyter notebooks

Some of the documentation is in the form of Jupyter notebooks. The inline graphical outputs of these notebooks are part of the documentation, so these notebooks are committed to the repo with their outputs included. It is therefore important to keep the notebook outputs up-to-date by re-running all of the notebooks when changes are made to the package.

Run the makefile command `execute-all-notebooks` to execute all the notebooks. This 1) ensures that the notebooks execute without errors and 2) updates their outputs in-place. Then, commit any modified notebooks to the repo.

## Releasing the package on PyPI

Releasing a new version of the package on PyPI requires API tokens for the test and real PyPI servers. You can find these tokens in your PyPI account settings. Copy `.env.copy` to `.env` and add your tokens to this file.
Expand Down
4 changes: 2 additions & 2 deletions arcadia_pycolor/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
shell = HexCode("shell", "#EDE0D6")

# Neutral colors
lightgrey = HexCode("lightgrey", "#EBEDE8")
gray = HexCode("gray", "#EBEDE8")
chateau = HexCode("chateau", "#BAB0A8")
bark = HexCode("bark", "#8F8885")
slate = HexCode("slate", "#43413F")
Expand Down Expand Up @@ -84,7 +84,7 @@
redwood = HexCode("redwood", "#52180A")

# Other Arcadia colors
brightgrey = HexCode("brightgrey", "#EAEAEA")
brightgray = HexCode("brightgray", "#EAEAEA")
paper = HexCode("paper", "#FCFCFC")

soil = HexCode("soil", "#4D2500")
Expand Down
8 changes: 4 additions & 4 deletions arcadia_pycolor/mpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ def _arcadia_fonts_found() -> bool:
return len(arcadia_fonts) > 0


def save_figure(context: str = "web", **savefig_kwargs: dict[Any, Any]) -> None:
def save_figure(fname: str, context: str = "web", **savefig_kwargs: dict[Any, Any]) -> None:
"Save the current figure with the default settings for web."
kwargs = SAVEFIG_KWARGS_WEB if context == "web" else SAVEFIG_KWARGS_PRINT
kwargs.update(**savefig_kwargs) # type: ignore
plt.savefig(**kwargs) # type: ignore
plt.savefig(fname=fname, **kwargs) # type: ignore


def set_yticklabel_font(
Expand Down Expand Up @@ -250,7 +250,7 @@ def set_colorbar_ticklabel_monospaced(axis: Union[Axes, None] = None):
set_ticklabel_monospaced(axis=cbar.ax)


def style_axis(
def style_plot(
axis: Union[Axes, None] = None,
monospaced_axes: Literal["x", "y", "both", None] = None,
categorical_axes: Literal["x", "y", "both", None] = None,
Expand Down Expand Up @@ -351,7 +351,7 @@ def add_legend_line(legend: Legend, linewidth: float = LEGEND_SEPARATOR_LINEWIDT

# Check that we haven't already put a drawing area within the legend.
# This should catch if we've already added the legend line
# through a different call to this function, e.g. calling "style_axis".
# through a different call to this function, e.g. calling "style_plot".
# This won't catch if the DrawingArea is added by a user otherwise,
# but most users shouldn't be adding new DrawingAreas to the legend.
if not isinstance(entries[0], DrawingArea):
Expand Down
16 changes: 8 additions & 8 deletions arcadia_pycolor/palettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
neutral = Palette(
"Neutral",
[
colors.lightgrey,
colors.gray,
colors.chateau,
colors.bark,
colors.slate,
Expand Down Expand Up @@ -117,13 +117,13 @@
[colors.azalea, colors.candy, colors.rose, colors.dress, colors.putty],
)

brown_shades = Palette(
"BrownShades",
warm_gray_shades = Palette(
"WarmGrayShades",
[colors.mud, colors.bark, colors.chateau, colors.taupe, colors.stone],
)

grey_shades = Palette(
"GreyShades",
cool_gray_shades = Palette(
"CoolGrayShades",
[colors.steel, colors.marine, colors.cloud, colors.dove, colors.ice],
)

Expand All @@ -136,7 +136,7 @@
"Other",
[
colors.concord,
colors.brightgrey,
colors.brightgray,
colors.paper,
colors.redwood,
colors.depths,
Expand Down Expand Up @@ -180,8 +180,8 @@
+ purple_shades
+ teal_shades
+ pink_shades
+ brown_shades
+ grey_shades
+ warm_gray_shades
+ cool_gray_shades
+ green_shades
)
all_colors = all_colors + Palette(
Expand Down
3 changes: 2 additions & 1 deletion arcadia_pycolor/style_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@
"axes.grid.axis": "both",
"axes.grid.which": "major",
"axes.prop_cycle": plt.cycler(color=palettes.all_ordered.colors), # type: ignore
"axes.titlesize": TITLE_FONT_SIZE,
"axes.titlesize": TITLE_FONT_SIZE + 2,
"axes.titleweight": "medium",
"axes.titlepad": 16,
"axes.labelsize": BASE_FONT_SIZE,
"axes.labelweight": "medium",
"axes.labelcolor": colors.black,
Expand Down
12 changes: 6 additions & 6 deletions arcadia_pycolor/tests/plotting/test_barplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def plot_vertical_barplot_with_matplotlib_with_error_bars(ax):
"""
sample_ids = _word_wrap_sample_ids(BARPLOT_SAMPLE_IDS)
plt.bar(sample_ids, BARPLOT_NUM_READS, color=apc.aster)
apc.mpl.style_axis(ax, monospaced_axes="y")
apc.mpl.style_plot(ax, monospaced_axes="y")
apc.mpl.set_xaxis_categorical()
apc.mpl.add_commas_to_axis_tick_labels(ax.get_yaxis())

Expand All @@ -82,7 +82,7 @@ def plot_horizontal_barplot_with_matplotlib_with_error_bars(ax):
This plot is identical to the vertical version, but with the x and y axes swapped.
"""
plt.barh(BARPLOT_SAMPLE_IDS, BARPLOT_NUM_READS, color=apc.aster)
apc.mpl.style_axis(ax, monospaced_axes="x")
apc.mpl.style_plot(ax, monospaced_axes="x")
apc.mpl.set_yaxis_categorical()
apc.mpl.add_commas_to_axis_tick_labels(ax.get_xaxis())
plt.xticks(rotation=30, ha="right")
Expand Down Expand Up @@ -110,7 +110,7 @@ def plot_vertical_barplot_with_matplotlib_with_categories(ax):
BARPLOT_NUM_READS,
color=colors,
)
apc.mpl.style_axis(ax, monospaced_axes="y")
apc.mpl.style_plot(ax, monospaced_axes="y")
apc.mpl.set_xaxis_categorical()
apc.mpl.add_commas_to_axis_tick_labels(ax.get_yaxis())
plt.ylabel("Number of reads")
Expand All @@ -129,7 +129,7 @@ def plot_vertical_barplot_with_seaborn(ax):
saturation=1,
ax=ax,
)
apc.mpl.style_axis(ax, monospaced_axes="y")
apc.mpl.style_plot(ax, monospaced_axes="y")
apc.mpl.set_xaxis_categorical()
apc.mpl.add_commas_to_axis_tick_labels(ax.get_yaxis())
plt.ylabel("Number of reads")
Expand All @@ -142,7 +142,7 @@ def plot_horizontal_barplot_with_seaborn(ax):
This plot is identical to the vertical version, but with the x and y axes swapped.
"""
sns.barplot(x=BARPLOT_NUM_READS, y=BARPLOT_SAMPLE_IDS, color=apc.aster, saturation=1, ax=ax)
apc.mpl.style_axis(ax, monospaced_axes="x")
apc.mpl.style_plot(ax, monospaced_axes="x")
apc.mpl.set_yaxis_categorical()
apc.mpl.add_commas_to_axis_tick_labels(ax.get_xaxis())
plt.xticks(rotation=30, ha="right")
Expand Down Expand Up @@ -170,7 +170,7 @@ def plot_vertical_barplot_with_seaborn_with_categories(ax):
ax=ax,
)

apc.mpl.style_axis(ax, monospaced_axes="y")
apc.mpl.style_plot(ax, monospaced_axes="y")
apc.mpl.set_xaxis_categorical()
apc.mpl.add_commas_to_axis_tick_labels(ax.get_yaxis())

Expand Down
8 changes: 4 additions & 4 deletions arcadia_pycolor/tests/plotting/test_bespoke_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_plot_stacked_barplot(output_dirpath, figure_size):
assert legend is not None
legend.set_title("Viability")

apc.mpl.style_axis(ax, categorical_axes="x", monospaced_axes="y")
apc.mpl.style_plot(ax, categorical_axes="x", monospaced_axes="y")
apc.mpl.save_figure(fname=(output_dirpath / f"test_plot_stacked_barplot_{figure_size}.pdf"))
plt.close(fig)

Expand All @@ -58,14 +58,14 @@ def test_plot_multiple_line_plot(output_dirpath, figure_size):
figsize=apc.mpl.get_figure_dimensions(figure_size),
)

colors = [apc.aegean, apc.lightgrey, apc.dragon]
colors = [apc.aegean, apc.gray, apc.dragon]
cmap = apc.Gradient(name="", colors=colors).to_mpl_cmap()

for ind, line in enumerate(lines):
ax = axes[ind]
color = cmap(ind / len(lines))
ax.plot(line, color=color)
apc.mpl.style_axis(axis=ax, monospaced_axes="both")
apc.mpl.style_plot(axis=ax, monospaced_axes="both")
ax.set_yticks([])

if ind != len(lines) - 1:
Expand Down Expand Up @@ -108,7 +108,7 @@ def test_plot_heatmaps_with_seaborn(output_dirpath, figure_size):
)

for ax in axs:
apc.mpl.style_axis(
apc.mpl.style_plot(
ax,
categorical_axes="both",
monospaced_axes="both",
Expand Down
4 changes: 2 additions & 2 deletions arcadia_pycolor/tests/plotting/test_seaborn_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def plot_seaborn_scatterplot(ax):
ax=ax,
s=80,
)
apc.mpl.style_axis(monospaced_axes="both")
apc.mpl.style_plot(monospaced_axes="both")


def plot_seaborn_violinplot(ax):
Expand All @@ -56,7 +56,7 @@ def plot_seaborn_violinplot(ax):
palette=colors,
ax=ax,
)
apc.mpl.style_axis(categorical_axes="x", monospaced_axes="y")
apc.mpl.style_plot(categorical_axes="x", monospaced_axes="y")


@pytest.mark.parametrize("figure_size", apc.style_defaults.FIGURE_SIZES.keys())
Expand Down
2 changes: 1 addition & 1 deletion arcadia_pycolor/tests/test_gradients.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_gradient_from_hexcode_list_invalid_values(values):
[0, 0.5, 1],
),
(
[HexCode("white", "#FFFFFF"), HexCode("grey", "#CCCCCC"), HexCode("black", "#000000")],
[HexCode("white", "#FFFFFF"), HexCode("gray", "#CCCCCC"), HexCode("black", "#000000")],
[0, 1],
),
],
Expand Down
Loading
Loading