├── .bumpversion.cfg
├── .circleci
└── config.yml
├── .flake8
├── .github
├── dependabot.yml
└── workflows
│ └── main.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE.txt
├── Makefile
├── README.md
├── cheatsheets.tex
├── check-diffs.py
├── check-links.py
├── check-matplotlib-version.py
├── check-num-pages.sh
├── docs
├── Makefile
├── _static
│ └── favicon.ico
├── conf.py
└── index.rst
├── figures
├── legend.pdf
└── legend.svg
├── fonts
├── .gitignore
└── Makefile
├── handout-beginner.tex
├── handout-intermediate.tex
├── handout-tips.tex
├── logos
├── logo2.png
├── mpl-logos2.py
└── numfocus.png
├── requirements
├── Makefile
├── requirements.in
└── requirements.txt
├── scripts
├── adjustements.py
├── advanced-plots.py
├── anatomy.py
├── animation.py
├── annotate.py
├── annotation-arrow-styles.py
├── annotation-connection-styles.py
├── basic-plots.py
├── colorbar.py
├── colormaps.py
├── colornames.py
├── colors.py
├── extents.py
├── fonts.py
├── interpolations.py
├── layouts.py
├── legend.py
├── linestyles.py
├── markers.py
├── performance-tips.py
├── plot-variations.py
├── projections.py
├── scales.py
├── sine.py
├── styles.py
├── text-alignments.py
├── tick-formatters.py
├── tick-locators.py
├── tick-multiple-locator.py
├── tip-color-range.py
├── tip-colorbar.py
├── tip-dotted.py
├── tip-dual-axis.py
├── tip-font-family.py
├── tip-hatched.py
├── tip-multiline.py
├── tip-outline.py
├── tip-post-processing.py
└── tip-transparency.py
└── styles
├── base.mplstyle
├── plotlet-grid.mplstyle
├── plotlet.mplstyle
├── sine-plot.mplstyle
└── ticks.mplstyle
/.bumpversion.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | current_version = 3.8.2
3 |
4 | [bumpversion:file:./check-matplotlib-version.py]
5 | search = __version__ == '{current_version}'
6 | replace = __version__ == '{new_version}'
7 |
8 | [bumpversion:glob:./handout-*.tex]
9 | search = Matplotlib {current_version}
10 | replace = Matplotlib {new_version}
11 |
12 | [bumpversion:file:./Makefile]
13 | search = v{current_version}
14 | replace = v{new_version}
15 |
16 | [bumpversion:file:./cheatsheets.tex]
17 | search = Version {current_version}
18 | replace = Version {new_version}
19 |
20 | [bumpversion:file:./requirements/requirements.in]
21 | search = matplotlib=={current_version}
22 | replace = matplotlib=={new_version}
23 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | orbs:
4 | python: circleci/python@0.2.1
5 |
6 | jobs:
7 | build_docs:
8 | docker:
9 | - image: cimg/python:3.9
10 | steps:
11 | - checkout
12 | - run:
13 | command: echo "placeholder"
14 |
15 | workflows:
16 | main:
17 | jobs:
18 | - build_docs
19 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E20,E22,E501,E701,F401,W
3 |
4 | [pep8]
5 | select = E12,E231,E241,E251,E26,E30
6 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: 2
3 | updates:
4 | - package-ecosystem: "github-actions"
5 | directory: "/"
6 | schedule:
7 | interval: "weekly"
8 | groups:
9 | actions:
10 | patterns:
11 | - "*"
12 |
--------------------------------------------------------------------------------
/.github/workflows/main.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | pre-commit:
7 | runs-on: ubuntu-20.04
8 | steps:
9 | - uses: actions/checkout@v4
10 | - uses: actions/setup-python@v5
11 | - uses: pre-commit/action@v3.0.1
12 | build:
13 | runs-on: ubuntu-20.04
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: actions/setup-python@v5
17 | with:
18 | python-version: "3.10"
19 | - name: Install dependencies
20 | run: |
21 | sudo apt update
22 | sudo apt install \
23 | fontconfig \
24 | imagemagick \
25 | poppler-utils
26 | python -m pip install --upgrade pip
27 | pip install -r requirements/requirements.txt
28 | - name: Install Tex Live
29 | run: |
30 | sudo apt update
31 | sudo apt install \
32 | texlive-base \
33 | texlive-extra-utils \
34 | texlive-fonts-extra \
35 | texlive-fonts-recommended \
36 | texlive-latex-base \
37 | texlive-latex-extra \
38 | texlive-latex-recommended \
39 | texlive-xetex
40 | - name: Build artifacts
41 | run: |
42 | # adjust the ImageMagick policies to convert PDF to PNG
43 | # remove all policies restricting Ghostscript ability to process files
44 | # https://stackoverflow.com/q/52998331
45 | # https://stackoverflow.com/a/59193253
46 | sudo sed -i '/disable ghostscript format types/,+6d' /etc/ImageMagick-6/policy.xml
47 | #
48 | make -C fonts/
49 | cp -r fonts/ /usr/share/fonts/
50 | fc-cache
51 | make all
52 | - name: Run checks
53 | run: |
54 | make check
55 | - uses: actions/upload-artifact@v4
56 | if: ${{ always() }}
57 | with:
58 | name: build
59 | path: |
60 | cheatsheets.pdf
61 | handout-*.pdf
62 | ./docs/_build/html/
63 | - uses: actions/upload-artifact@v4
64 | id: diffs-artifact-upload
65 | if: ${{ always() }}
66 | with:
67 | name: diffs
68 | path: |
69 | diffs/
70 | - name: Output artifacts URL
71 | run: |
72 | echo 'Artifact URL:' \
73 | '${{ steps.diffs-artifact-upload.outputs.artifact-url }}' \
74 | >> $GITHUB_STEP_SUMMARY
75 | - name: Publish cheatsheets and handouts
76 | if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
77 | uses: peaceiris/actions-gh-pages@v4
78 | with:
79 | github_token: ${{ secrets.GITHUB_TOKEN }}
80 | publish_dir: ./docs/_build/html/
81 | force_orphan: true
82 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built cheatsheets and handouts
2 | # ----------------------------------
3 | cheatsheets*.pdf
4 | cheatsheets*.png
5 | handout-*.pdf
6 | handout-*.png
7 |
8 | # TeX auxiliary files
9 | # ----------------------------------
10 | *.aux
11 | *.log
12 | *.out
13 | *.upa
14 |
15 | # generated figures
16 | # ----------------------------------
17 | figures/*.pdf
18 | fonts/**/*.[ot]tf
19 |
20 | # html build
21 | docs/_build/*
22 |
23 | # OS specific
24 | .DS_Store
25 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | exclude: |
2 | (?x)^(
3 | .+[.]svg|
4 | )$
5 | repos:
6 | - repo: https://github.com/pre-commit/pre-commit-hooks
7 | rev: v4.0.1
8 | hooks:
9 | - id: check-yaml
10 | - id: end-of-file-fixer
11 | - id: trailing-whitespace
12 | - repo: https://github.com/pycqa/flake8
13 | rev: 4.0.1
14 | hooks:
15 | - id: flake8
16 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020, Nicolas P. Rougier
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright notice,
9 | this list of conditions and the following disclaimer in the documentation
10 | and/or other materials provided with the distribution.
11 |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SRC := $(wildcard *.tex)
2 | CONVERTFLAGS = -density 150 -alpha remove -depth 8
3 |
4 | .PHONY: default
5 | default: all
6 |
7 | .PHONY: all
8 | all: figures cheatsheets handouts docs
9 |
10 | .PHONY: figures
11 | figures:
12 | # generate the figures
13 | cd scripts && for script in *.py; do echo $$script; MPLBACKEND="agg" python $$script; done
14 | # crop some of the figures
15 | cd figures && pdfcrop adjustments.pdf adjustments.pdf
16 | cd figures && pdfcrop annotate.pdf annotate.pdf
17 | cd figures && pdfcrop annotation-arrow-styles.pdf annotation-arrow-styles.pdf
18 | cd figures && pdfcrop anatomy.pdf anatomy.pdf
19 | cd figures && pdfcrop colornames.pdf colornames.pdf
20 | cd figures && pdfcrop fonts.pdf fonts.pdf
21 | cd figures && pdfcrop markers.pdf markers.pdf
22 | cd figures && pdfcrop text-alignments.pdf text-alignments.pdf
23 | cd figures && pdfcrop tick-formatters.pdf tick-formatters.pdf
24 | cd figures && pdfcrop tick-locators.pdf tick-locators.pdf
25 | cd figures && pdfcrop tip-font-family.pdf tip-font-family.pdf
26 | cd figures && pdfcrop tip-hatched.pdf tip-hatched.pdf
27 |
28 | .PHONY: cheatsheets
29 | cheatsheets:
30 | xelatex cheatsheets.tex
31 | convert $(CONVERTFLAGS) cheatsheets.pdf -scene 1 cheatsheets.png
32 |
33 | .PHONY: handouts
34 | handouts:
35 | xelatex handout-beginner.tex
36 | xelatex handout-intermediate.tex
37 | xelatex handout-tips.tex
38 | convert $(CONVERTFLAGS) handout-tips.pdf handout-tips.png
39 | convert $(CONVERTFLAGS) handout-beginner.pdf handout-beginner.png
40 | convert $(CONVERTFLAGS) handout-intermediate.pdf handout-intermediate.png
41 |
42 | .PHONY: check
43 | check:
44 | ./check-matplotlib-version.py
45 | ./check-num-pages.sh cheatsheets.pdf 2
46 | ./check-num-pages.sh handout-tips.pdf 1
47 | ./check-num-pages.sh handout-beginner.pdf 1
48 | ./check-num-pages.sh handout-intermediate.pdf 1
49 | ./check-diffs.py
50 | ./check-links.py cheatsheets.pdf
51 |
52 | .PHONY: docs
53 | docs:
54 | make -C docs/ html
55 | cp ./cheatsheets*.p* ./docs/_build/html
56 | cp ./handout-*.p* ./docs/_build/html
57 |
58 |
59 | .PHONY: fonts
60 | fonts:
61 | make -C fonts/
62 |
63 | .PHONY: clean
64 | clean: $(SRC)
65 | latexmk -c $^
66 | - rm -rf ./build/
67 |
68 | .PHONY: clean-all
69 | clean-all: clean
70 | - rm ./logos/mpl-logo2.pdf
71 | git clean -f -X ./figures/
72 | git clean -f ./scripts/*.pdf
73 |
74 | .PHONY: requirements
75 | requirements:
76 | $(MAKE) -C ./requirements/
77 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cheatsheets for Matplotlib users
2 |
3 | ## Cheatsheets
4 | Cheatsheet [(download pdf)](https://matplotlib.org/cheatsheets/cheatsheets.pdf) | |
5 | :------------------------------------------------------------------------------:|:----------------------------------------------------------:
6 |  | 
7 |
8 | ## Handouts
9 |
10 | Beginner handout [(download pdf)](https://matplotlib.org/cheatsheets/handout-beginner.pdf) | Intermediate handout [(download pdf)](https://matplotlib.org/cheatsheets/handout-intermediate.pdf) | Tips handout [(download pdf)](https://matplotlib.org/cheatsheets/handout-tips.pdf)
11 | :-----------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------:
12 |  |  | 
13 |
14 | # For contributors to the cheatsheets
15 |
16 | ## How to compile
17 |
18 | 1. You need to create a `fonts` repository with:
19 |
20 | * `fonts/roboto/*` : See https://fonts.google.com/specimen/Roboto
21 | or https://github.com/googlefonts/roboto/tree/master/src/hinted
22 | * `fonts/roboto-slab/*` : See https://fonts.google.com/specimen/Roboto+Slab
23 | or https://github.com/googlefonts/robotoslab/tree/master/fonts/static
24 | * `fonts/source-code-pro/*` : See https://fonts.google.com/specimen/Source+Code+Pro
25 | or https://github.com/adobe-fonts/source-code-pro/tree/release/OTF
26 | * `fonts/source-sans-pro/*` : See https://fonts.google.com/specimen/Source+Sans+Pro
27 | or https://github.com/adobe-fonts/source-sans-pro/tree/release/OTF
28 | * `fonts/source-serif-pro/*` : See https://fonts.google.com/specimen/Source+Serif+Pro
29 | or https://github.com/adobe-fonts/source-serif-pro/tree/release/OTF
30 | * `fonts/eb-garamond/*` : See https://bitbucket.org/georgd/eb-garamond/src/master
31 | * `fonts/pacifico/*` : See https://fonts.google.com/download?family=Pacifico
32 |
33 | On Linux, with `make` installed, the fonts can be set up with the following command:
34 | ```shell
35 | make -C fonts
36 | ```
37 |
38 | The fonts can be made discoverable by `matplotlib` (through `fontconfig`) by creating the following in `$HOME/.config/fontconfig/fonts.conf` (see [here](https://www.freedesktop.org/software/fontconfig/fontconfig-user.html)):
39 |
40 | ```xml
41 |
42 |
43 |
44 | /path/to/cheatsheets/fonts/
45 | ...
46 |
47 | ```
48 |
49 |
50 | 2. You need to generate all the figures:
51 |
52 | ```
53 | $ cd scripts
54 | $ for script in *.py; do python $script; done
55 | $ cd ..
56 | ```
57 |
58 | 3. Compile the sheet
59 | ```
60 | $ xelatex cheatsheets.tex
61 | $ xelatex cheatsheets.tex
62 | ```
63 |
--------------------------------------------------------------------------------
/check-diffs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import os
4 | import subprocess
5 | import sys
6 | from pathlib import Path
7 |
8 |
9 | ROOT_DIR = Path(__file__).parent
10 |
11 | if os.environ.get('GITHUB_ACTIONS', '') == '':
12 | print('Not running when not in GitHub Actions.')
13 | sys.exit()
14 | summary_file = os.environ.get('GITHUB_STEP_SUMMARY')
15 | if summary_file is None:
16 | sys.exit('$GITHUB_STEP_SUMMARY is not set')
17 |
18 | gh_pages = ROOT_DIR.parent / 'pages'
19 | subprocess.run(['git', 'fetch', 'https://github.com/matplotlib/cheatsheets.git',
20 | 'gh-pages:upstream-gh-pages'], check=True)
21 | subprocess.run(['git', 'worktree', 'add', gh_pages, 'upstream-gh-pages'],
22 | check=True)
23 |
24 | diff_dir = ROOT_DIR / 'diffs'
25 | diff_dir.mkdir(exist_ok=True)
26 |
27 | hashes = {}
28 | for original in gh_pages.glob('*.png'):
29 | result = subprocess.run(
30 | ['compare', '-metric', 'PHASH',
31 | original,
32 | ROOT_DIR / 'docs/_build/html' / original.name,
33 | diff_dir / f'{original.stem}-diff.png'],
34 | text=True, stderr=subprocess.PIPE)
35 | if result.returncode == 2: # Some kind of IO or similar error.
36 | hashes[original] = (float('nan'), result.stderr)
37 | elif result.stderr: # Images were different.
38 | hashes[original] = (float(result.stderr), '')
39 | else: # No differences.
40 | hashes[original] = (0.0, '')
41 |
42 | with open(summary_file, 'w+') as summary:
43 | print('# Cheatsheet image comparison', file=summary)
44 | print('| Filename | Perceptual Hash Difference | Error message |', file=summary)
45 | print('| -------- | -------------------------- | ------------- |', file=summary)
46 | for filename, (hash, message) in sorted(hashes.items()):
47 | message = message.replace('\n', ' ').replace('|', '\\|')
48 | print(f'| {filename.name} | {hash:.05f} | {message}', file=summary)
49 | print(file=summary)
50 |
51 | subprocess.run(['git', 'worktree', 'remove', gh_pages])
52 |
--------------------------------------------------------------------------------
/check-links.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 |
4 | import pdfx
5 |
6 |
7 | pdf = pdfx.PDFx(sys.argv[1])
8 |
9 | refs = [ref for ref in pdf.get_references() if ref.reftype == 'url']
10 |
11 | status_codes = [pdfx.downloader.get_status_code(ref.ref) for ref in refs]
12 |
13 | broken_links = [(ref.ref, code) for ref, code in zip(refs, status_codes) if code != 200]
14 |
15 | # it seems that Twitter does not respond well to the link checker and throws a 400
16 | if all(['twitter.com' in url for url, _ in broken_links]):
17 | sys.exit(0)
18 | else:
19 | print('Broken links:', broken_links)
20 | sys.exit(1)
21 |
--------------------------------------------------------------------------------
/check-matplotlib-version.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import matplotlib as mpl
3 |
4 |
5 | assert mpl.__version__ == '3.8.2'
6 |
--------------------------------------------------------------------------------
/check-num-pages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Check that a given pdf has a certain number of pages.
4 | # Usage:
5 | # check-num-pages.sh [pdffile] [num_pages]
6 |
7 | set -x
8 | pdffile=$1
9 | num_pages=$2
10 | [[ "$(pdfinfo $pdffile | grep Pages | awk '{print $2}')" == "$num_pages" ]] || exit 1
11 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?= -W
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | show:
16 | @python -c "import webbrowser; webbrowser.open_new_tab('file://$(shell pwd)/build/html/index.html')"
17 |
18 | .PHONY: help Makefile
19 |
20 | # Catch-all target: route all unknown targets to Sphinx using the new
21 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
22 | %: Makefile
23 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
24 |
--------------------------------------------------------------------------------
/docs/_static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matplotlib/cheatsheets/f02ebb5f02abd3c5d5b02bb1f22737ab87e92a08/docs/_static/favicon.ico
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | # -- Project information -----------------------------------------------------
4 |
5 | html_title = 'Visualization with Python'
6 | project = "Matplotlib cheatsheets"
7 | copyright = (
8 | f"2012 - {datetime.datetime.now().year} The Matplotlib development team"
9 | )
10 | author = "Matplotlib Developers"
11 |
12 | # -- General configuration ---------------------------------------------------
13 |
14 | # Add any Sphinx extension module names here, as strings. They can be
15 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
16 | # ones.
17 | extensions = ["sphinx_design"]
18 |
19 | # Add any paths that contain templates here, relative to this directory.
20 |
21 | templates_path = []
22 |
23 | # List of patterns, relative to source directory, that match files and
24 | # directories to ignore when looking for source files.
25 | # This pattern also affects html_static_path and html_extra_path.
26 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
27 |
28 | # -- Options for HTML output -------------------------------------------------
29 |
30 | html_css_files = ['css/normalize.css', 'css/landing.css']
31 | html_theme = "mpl_sphinx_theme"
32 | html_favicon = "_static/favicon.ico"
33 | html_theme_options = {
34 | "navbar_links": ("absolute", "server-stable"),
35 | }
36 | html_sidebars = {
37 | "**": []
38 | }
39 | # Add any paths that contain custom static files (such as style sheets) here,
40 | # relative to this directory. They are copied after the theme static files,
41 | # so a file named "default.css" will overwrite the theme's "default.css".
42 | html_static_path = ["_static"]
43 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. title:: Matplotlib cheatsheets
2 |
3 | ***********************************
4 | Matplotlib cheatsheets and handouts
5 | ***********************************
6 |
7 | Cheatsheets
8 | ***********
9 |
10 | .. grid:: 2
11 |
12 | .. grid-item::
13 |
14 | .. image:: ../cheatsheets-1.png
15 | :width: 270px
16 | :align: center
17 | :alt: image of first page of cheatsheets
18 |
19 | .. grid-item::
20 |
21 | .. image:: ../cheatsheets-2.png
22 | :width: 270px
23 | :align: center
24 | :alt: image of second page of cheatsheets
25 |
26 | `Cheatsheets [pdf] <./cheatsheets.pdf>`_
27 |
28 |
29 |
30 | Handouts
31 | ********
32 |
33 | .. grid:: 1 2 3 3
34 |
35 | .. grid-item::
36 |
37 | .. image:: ../handout-beginner.png
38 | :width: 270px
39 | :align: center
40 | :alt: image of beginner handout
41 |
42 | `Beginner [pdf] <./handout-beginner.pdf>`_
43 |
44 | .. grid-item::
45 |
46 | .. image:: ../handout-intermediate.png
47 | :width: 270px
48 | :align: center
49 | :alt: image of intermediate handout
50 |
51 | `Intermediate [pdf] <./handout-intermediate.pdf>`_
52 |
53 | .. grid-item::
54 |
55 | .. image:: ../handout-tips.png
56 | :width: 270px
57 | :align: center
58 | :alt: image of tips handout
59 |
60 | `Tips [pdf] <./handout-tips.pdf>`_
61 |
62 | Contribute
63 | **********
64 |
65 | Issues, suggestions, or pull-requests gratefully accepted at
66 | `matplotlib/cheatsheets `_
67 |
--------------------------------------------------------------------------------
/figures/legend.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matplotlib/cheatsheets/f02ebb5f02abd3c5d5b02bb1f22737ab87e92a08/figures/legend.pdf
--------------------------------------------------------------------------------
/figures/legend.svg:
--------------------------------------------------------------------------------
1 |
2 |
1135 |
--------------------------------------------------------------------------------
/fonts/.gitignore:
--------------------------------------------------------------------------------
1 | .uuid
2 |
--------------------------------------------------------------------------------
/fonts/Makefile:
--------------------------------------------------------------------------------
1 | FONT_DIRS := eb-garamond roboto roboto-mono roboto-slab source-code-pro source-sans-pro source-serif-pro pacifico
2 |
3 | EB_GARAMOND_ZIP := https://bitbucket.org/georgd/eb-garamond/downloads/EBGaramond-0.016.zip
4 | ROBOTO_ZIP := https://github.com/googlefonts/roboto/releases/download/v2.138/roboto-unhinted.zip
5 | ROBOTO_MONO_ZIP := https://github.com/googlefonts/RobotoMono/archive/8f651634e746da6df6c2c0be73255721d24f2372.zip
6 | ROBOTO_SLAB_ZIP := https://github.com/googlefonts/robotoslab/archive/a65e6d00d8e3e7ee2fabef844e58fa12690384d2.zip
7 | SOURCE_CODE_PRO_ZIP := https://github.com/adobe-fonts/source-code-pro/releases/download/2.038R-ro%2F1.058R-it%2F1.018R-VAR/OTF-source-code-pro-2.038R-ro-1.058R-it.zip
8 | SOURCE_SANS_PRO_ZIP := https://github.com/adobe-fonts/source-sans/releases/download/2.045R-ro%2F1.095R-it/source-sans-pro-2.045R-ro-1.095R-it.zip
9 | SOURCE_SERIF_PRO_ZIP := https://github.com/adobe-fonts/source-serif/releases/download/3.001R/source-serif-pro-3.001R.zip
10 | PACIFICO := https://raw.githubusercontent.com/googlefonts/Pacifico/refs/heads/main/fonts/ttf/Pacifico-Regular.ttf
11 |
12 | UNZIP_FLAGS := -x "__MACOSX/*"
13 |
14 |
15 | .PHONY: default
16 | default: all
17 |
18 | .PHONY: all
19 | all: sources
20 | mkdir -p $(FONT_DIRS)
21 | cd eb-garamond && unzip -j /tmp/eb-garamond.zip "EBGaramond-0.016/otf/*.otf" $(UNZIP_FLAGS)
22 | cd roboto && unzip -j /tmp/roboto.zip "*.ttf" $(UNZIP_FLAGS)
23 | cd roboto-mono && unzip -j /tmp/roboto-mono.zip "RobotoMono-8f651634e746da6df6c2c0be73255721d24f2372/fonts/ttf/*.ttf" $(UNZIP_FLAGS)
24 | cd roboto-slab && unzip -j /tmp/roboto-slab.zip "robotoslab-a65e6d00d8e3e7ee2fabef844e58fa12690384d2/fonts/static/*.ttf" $(UNZIP_FLAGS)
25 | cd source-code-pro && unzip -j /tmp/source-code-pro.zip "*.otf" $(UNZIP_FLAGS)
26 | cd source-sans-pro && unzip -j /tmp/source-sans-pro.zip "source-sans-pro-2.045R-ro-1.095R-it/OTF/*.otf" $(UNZIP_FLAGS)
27 | cd source-serif-pro && unzip -j /tmp/source-serif-pro.zip "source-serif-pro-3.001R/OTF/*.otf" $(UNZIP_FLAGS)
28 | cd pacifico && cp /tmp/pacifico.ttf .
29 |
30 | .PHONY: sources
31 | sources:
32 | wget $(EB_GARAMOND_ZIP) -O /tmp/eb-garamond.zip
33 | wget $(ROBOTO_ZIP) -O /tmp/roboto.zip
34 | wget $(ROBOTO_MONO_ZIP) -O /tmp/roboto-mono.zip
35 | wget $(ROBOTO_SLAB_ZIP) -O /tmp/roboto-slab.zip
36 | wget $(SOURCE_CODE_PRO_ZIP) -O /tmp/source-code-pro.zip
37 | wget $(SOURCE_SANS_PRO_ZIP) -O /tmp/source-sans-pro.zip
38 | wget $(SOURCE_SERIF_PRO_ZIP) -O /tmp/source-serif-pro.zip
39 | wget $(PACIFICO) -O /tmp/pacifico.ttf
40 |
41 | .PHONY: clean
42 | clean:
43 | - rm $(HOME)/.cache/matplotlib/fontlist*
44 | - rm -rf $(FONT_DIRS)
45 |
--------------------------------------------------------------------------------
/handout-beginner.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pt,landscape,a4paper]{article}
2 | \usepackage[right=10mm, left=10mm, top=10mm, bottom=10mm]{geometry}
3 | \usepackage[utf8]{inputenc}
4 | \usepackage[T1]{fontenc}
5 | \usepackage[english]{babel}
6 | \usepackage[rm,light]{roboto}
7 | \usepackage{xcolor}
8 | \usepackage{graphicx}
9 | \graphicspath{{./figures/}}
10 | \usepackage{multicol}
11 | \usepackage{colortbl}
12 | \usepackage{array}
13 | \setlength\parindent{0pt}
14 | \setlength{\tabcolsep}{2pt}
15 | \baselineskip=0pt
16 | \setlength\columnsep{1em}
17 | \definecolor{Gray}{gray}{0.85}
18 |
19 | % --- Listing -----------------------------------------------------------------
20 | \usepackage{listings}
21 | \lstset{
22 | frame=tb, framesep=4pt, framerule=0pt,
23 | backgroundcolor=\color{black!5},
24 | basicstyle=\ttfamily,
25 | commentstyle=\ttfamily\color{black!50},
26 | breakatwhitespace=false,
27 | breaklines=true,
28 | extendedchars=true,
29 | keepspaces=true,
30 | language=Python,
31 | rulecolor=\color{black},
32 | showspaces=false,
33 | showstringspaces=false,
34 | showtabs=false,
35 | tabsize=2,
36 | %
37 | emph = { plot, scatter, imshow, bar, contourf, pie, subplots, show, savefig,
38 | errorbar, boxplot, hist, set_title, set_xlabel, set_ylabel, suptitle, },
39 | emphstyle = {\ttfamily\bfseries}
40 | }
41 |
42 | % --- Fonts -------------------------------------------------------------------
43 | \usepackage{fontspec}
44 | \usepackage[babel=true]{microtype}
45 | \defaultfontfeatures{Ligatures = TeX, Mapping = tex-text}
46 | \setsansfont{Roboto} [ Path = fonts/roboto/Roboto-,
47 | Extension = .ttf,
48 | UprightFont = Light,
49 | ItalicFont = LightItalic,
50 | BoldFont = Regular,
51 | BoldItalicFont = Italic ]
52 | \setromanfont{RobotoSlab} [ Path = fonts/roboto-slab/RobotoSlab-,
53 | Extension = .ttf,
54 | UprightFont = Light,
55 | BoldFont = Bold ]
56 | \setmonofont{RobotoMono} [ Path = fonts/roboto-mono/RobotoMono-,
57 | Extension = .ttf,
58 | Scale = 0.90,
59 | UprightFont = Light,
60 | ItalicFont = LightItalic,
61 | BoldFont = Regular,
62 | BoldItalicFont = Italic ]
63 | \renewcommand{\familydefault}{\sfdefault}
64 |
65 | % -----------------------------------------------------------------------------
66 | \begin{document}
67 | \thispagestyle{empty}
68 |
69 | \section*{\LARGE \rmfamily
70 | Matplotlib \textcolor{orange}{\mdseries for beginners}}
71 |
72 | \begin{multicols*}{3}
73 |
74 | Matplotlib is a library for making 2D plots in Python. It is designed
75 | with the philosophy that you should be able to create simple plots
76 | with just a few commands:\\
77 |
78 | \fbox{1} \textbf{Initialize}
79 | \begin{lstlisting}
80 | import numpy as np
81 | import matplotlib.pyplot as plt
82 | \end{lstlisting}
83 | %
84 | \fbox{2} \textbf{Prepare}
85 | \begin{lstlisting}
86 | X = np.linspace(0, 10*np.pi, 1000)
87 | Y = np.sin(X)
88 | \end{lstlisting}
89 | %
90 | \fbox{3} \textbf{Render}
91 | \begin{lstlisting}
92 | fig, ax = plt.subplots()
93 | ax.plot(X, Y)
94 | plt.show()
95 | \end{lstlisting}
96 | %
97 | \fbox{4} \textbf{Observe} \medskip\\
98 | \includegraphics[width=\linewidth]{sine.pdf}
99 |
100 | % -----------------------------------------------------------------------------
101 | \subsection*{\rmfamily Choose}
102 | % -----------------------------------------------------------------------------
103 |
104 | Matplotlib offers several kind of plots (see Gallery): \medskip
105 |
106 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
107 | \begin{lstlisting}[belowskip=-\baselineskip]
108 | X = np.random.uniform(0, 1, 100)
109 | Y = np.random.uniform(0, 1, 100)
110 | ax.scatter(X, Y)
111 | \end{lstlisting}
112 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{basic-scatter.pdf}}
113 | \end{tabular}
114 | % -----------------------------------------------------------------------------
115 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
116 | \begin{lstlisting}[belowskip=-\baselineskip]
117 | X = np.arange(10)
118 | Y = np.random.uniform(1, 10, 10)
119 | ax.bar(X, Y)
120 | \end{lstlisting}
121 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{basic-bar.pdf}}
122 | \end{tabular}
123 | % -----------------------------------------------------------------------------
124 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
125 | \begin{lstlisting}[belowskip=-\baselineskip]
126 | Z = np.random.uniform(0, 1, (8, 8))
127 |
128 | ax.imshow(Z)
129 | \end{lstlisting}
130 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{basic-imshow.pdf}}
131 | \end{tabular}
132 | % -----------------------------------------------------------------------------
133 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
134 | \begin{lstlisting}[belowskip=-\baselineskip]
135 | Z = np.random.uniform(0, 1, (8, 8))
136 |
137 | ax.contourf(Z)
138 | \end{lstlisting}
139 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{basic-contour.pdf}}
140 | \end{tabular}
141 | % -----------------------------------------------------------------------------
142 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
143 | \begin{lstlisting}[belowskip=-\baselineskip]
144 | Z = np.random.uniform(0, 1, 4)
145 |
146 | ax.pie(Z)
147 | \end{lstlisting}
148 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{basic-pie.pdf}}
149 | \end{tabular}
150 | % -----------------------------------------------------------------------------
151 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
152 | \begin{lstlisting}[belowskip=-\baselineskip]
153 | Z = np.random.normal(0, 1, 100)
154 |
155 | ax.hist(Z)
156 | \end{lstlisting}
157 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{advanced-hist.pdf}}
158 | \end{tabular}
159 | % -----------------------------------------------------------------------------
160 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
161 | \begin{lstlisting}[belowskip=-\baselineskip]
162 | X = np.arange(5)
163 | Y = np.random.uniform(0, 1, 5)
164 | ax.errorbar(X, Y, Y/4)
165 | \end{lstlisting}
166 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{advanced-errorbar.pdf}}
167 | \end{tabular}
168 | % -----------------------------------------------------------------------------
169 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
170 | \begin{lstlisting}[belowskip=-\baselineskip]
171 | Z = np.random.normal(0, 1, (100, 3))
172 |
173 | ax.boxplot(Z)
174 | \end{lstlisting}
175 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{advanced-boxplot.pdf}}
176 | \end{tabular}
177 |
178 |
179 | % -----------------------------------------------------------------------------
180 | \subsection*{\rmfamily Tweak}
181 | % -----------------------------------------------------------------------------
182 | You can modify pretty much anything in a plot, including limits,
183 | colors, markers, line width and styles, ticks and ticks labels,
184 | titles, etc. \medskip
185 |
186 | % -----------------------------------------------------------------------------
187 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
188 | \begin{lstlisting}[belowskip=-\baselineskip]
189 | X = np.linspace(0, 10, 100)
190 | Y = np.sin(X)
191 | ax.plot(X, Y, color="black")
192 | \end{lstlisting}
193 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-color.pdf}}
194 | \end{tabular}
195 | % -----------------------------------------------------------------------------
196 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
197 | \begin{lstlisting}[belowskip=-\baselineskip]
198 | X = np.linspace(0, 10, 100)
199 | Y = np.sin(X)
200 | ax.plot(X, Y, linestyle="--")
201 | \end{lstlisting}
202 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-linestyle.pdf}}
203 | \end{tabular}
204 | % -----------------------------------------------------------------------------
205 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
206 | \begin{lstlisting}[belowskip=-\baselineskip]
207 | X = np.linspace(0, 10, 100)
208 | Y = np.sin(X)
209 | ax.plot(X, Y, linewidth=5)
210 | \end{lstlisting}
211 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-linewidth.pdf}}
212 | \end{tabular}
213 | % -----------------------------------------------------------------------------
214 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
215 | \begin{lstlisting}[belowskip=-\baselineskip]
216 | X = np.linspace(0, 10, 100)
217 | Y = np.sin(X)
218 | ax.plot(X, Y, marker="o")
219 | \end{lstlisting}
220 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-marker.pdf}}
221 | \end{tabular}
222 |
223 |
224 | % -----------------------------------------------------------------------------
225 | \subsection*{\rmfamily Organize}
226 | % -----------------------------------------------------------------------------
227 |
228 | You can plot several data on the same figure, but you can also split a figure
229 | in several subplots (named {\em Axes}): \medskip
230 |
231 | % -----------------------------------------------------------------------------
232 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
233 | \begin{lstlisting}[belowskip=-\baselineskip]
234 | X = np.linspace(0, 10, 100)
235 | Y1, Y2 = np.sin(X), np.cos(X)
236 | ax.plot(X, Y1, X, Y2)
237 | \end{lstlisting}
238 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-multi.pdf}}
239 | \end{tabular}
240 | % -----------------------------------------------------------------------------
241 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
242 | \begin{lstlisting}[belowskip=-\baselineskip]
243 | fig, (ax1, ax2) = plt.subplots(2, 1)
244 | ax1.plot(X, Y1, color="C1")
245 | ax2.plot(X, Y2, color="C0")
246 | \end{lstlisting}
247 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-vsplit.pdf}}
248 | \end{tabular}
249 | % -----------------------------------------------------------------------------
250 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
251 | \begin{lstlisting}[belowskip=-\baselineskip]
252 | fig, (ax1, ax2) = plt.subplots(1, 2)
253 | ax1.plot(Y1, X, color="C1")
254 | ax2.plot(Y2, X, color="C0")
255 | \end{lstlisting}
256 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-hsplit.pdf}}
257 | \end{tabular}
258 |
259 | % -----------------------------------------------------------------------------
260 | \subsection*{\rmfamily Label \mdseries (everything)}
261 | % -----------------------------------------------------------------------------
262 | % -----------------------------------------------------------------------------
263 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
264 | \begin{lstlisting}[belowskip=-\baselineskip]
265 | ax.plot(X, Y)
266 | fig.suptitle(None)
267 | ax.set_title("A Sine wave")
268 | \end{lstlisting}
269 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-title.pdf}}
270 | \end{tabular}
271 | % -----------------------------------------------------------------------------
272 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
273 | \begin{lstlisting}[belowskip=-\baselineskip]
274 | ax.plot(X, Y)
275 | ax.set_ylabel(None)
276 | ax.set_xlabel("Time")
277 | \end{lstlisting}
278 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{plot-xlabel.pdf}}
279 | \end{tabular}
280 |
281 | % -----------------------------------------------------------------------------
282 | \subsection*{\rmfamily Explore}
283 | % -----------------------------------------------------------------------------
284 |
285 | Figures are shown with a graphical user interface that allows to zoom
286 | and pan the figure, to navigate between the different views and to
287 | show the value under the mouse.
288 |
289 | % -----------------------------------------------------------------------------
290 | \subsection*{\rmfamily Save \mdseries (bitmap or vector format)}
291 | % -----------------------------------------------------------------------------
292 | \begin{lstlisting}[belowskip=-\baselineskip]
293 | fig.savefig("my-first-figure.png", dpi=300)
294 | fig.savefig("my-first-figure.pdf")
295 | \end{lstlisting}
296 | %
297 | \vfill
298 | %
299 | {\scriptsize
300 | Matplotlib 3.8.2 handout for beginners.
301 | Copyright (c) 2021 Matplotlib Development Team.
302 | Released under a CC-BY 4.0 International License.
303 | Supported by NumFOCUS.
304 | \par}
305 |
306 | \end{multicols*}
307 | \end{document}
308 |
--------------------------------------------------------------------------------
/handout-intermediate.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pt,landscape,a4paper]{article}
2 | \usepackage[right=10mm, left=10mm, top=10mm, bottom=10mm]{geometry}
3 | \usepackage[utf8]{inputenc}
4 | \usepackage[T1]{fontenc}
5 | \usepackage[english]{babel}
6 | \usepackage[rm,light]{roboto}
7 | \usepackage{xcolor}
8 | \usepackage{graphicx}
9 | \graphicspath{{./figures/}}
10 | \usepackage{multicol}
11 | \usepackage{colortbl}
12 | \usepackage{array}
13 | \setlength\parindent{0pt}
14 | \setlength{\tabcolsep}{2pt}
15 | \baselineskip=0pt
16 | \setlength\columnsep{1em}
17 | \definecolor{Gray}{gray}{0.85}
18 |
19 | % --- Listing -----------------------------------------------------------------
20 | \usepackage{listings}
21 | \lstset{
22 | frame=tb, framesep=4pt, framerule=0pt,
23 | backgroundcolor=\color{black!5},
24 | basicstyle=\ttfamily,
25 | commentstyle=\ttfamily\color{black!50},
26 | breakatwhitespace=false,
27 | breaklines=true,
28 | extendedchars=true,
29 | keepspaces=true,
30 | language=Python,
31 | rulecolor=\color{black},
32 | showspaces=false,
33 | showstringspaces=false,
34 | showtabs=false,
35 | tabsize=2,
36 | %
37 | emph = { plot, scatter, imshow, bar, contourf, pie, subplots, spines,
38 | add_gridspec, add_subplot, set_xscale, set_minor_locator,
39 | annotate, set_minor_formatter, tick_params, fill_betweenx, text, legend,
40 | errorbar, boxplot, hist, title, xlabel, ylabel, suptitle },
41 | emphstyle = {\ttfamily\bfseries}
42 | }
43 |
44 | % --- Fonts -------------------------------------------------------------------
45 | \usepackage{fontspec}
46 | \usepackage[babel=true]{microtype}
47 | \defaultfontfeatures{Ligatures = TeX, Mapping = tex-text}
48 | \setsansfont{Roboto} [ Path = fonts/roboto/Roboto-,
49 | Extension = .ttf,
50 | UprightFont = Light,
51 | ItalicFont = LightItalic,
52 | BoldFont = Regular,
53 | BoldItalicFont = Italic ]
54 | \setromanfont{RobotoSlab} [ Path = fonts/roboto-slab/RobotoSlab-,
55 | Extension = .ttf,
56 | UprightFont = Light,
57 | BoldFont = Bold ]
58 | \setmonofont{RobotoMono} [ Path = fonts/roboto-mono/RobotoMono-,
59 | Extension = .ttf,
60 | Scale = 0.90,
61 | UprightFont = Light,
62 | ItalicFont = LightItalic,
63 | BoldFont = Regular,
64 | BoldItalicFont = Italic ]
65 | \renewcommand{\familydefault}{\sfdefault}
66 |
67 | % -----------------------------------------------------------------------------
68 | \begin{document}
69 | \thispagestyle{empty}
70 |
71 | \section*{\LARGE \rmfamily
72 | Matplotlib \textcolor{orange}{\mdseries for intermediate users}}
73 |
74 | \begin{multicols*}{3}
75 |
76 | A matplotlib figure is composed of a hierarchy of elements that forms
77 | the actual figure. Each element can be modified. \medskip
78 |
79 | \includegraphics[width=\linewidth]{anatomy.pdf}
80 |
81 | \subsection*{\rmfamily Figure, axes \& spines}
82 |
83 | % -----------------------------------------------------------------------------
84 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
85 | \begin{lstlisting}[belowskip=-\baselineskip]
86 | fig, axs = plt.subplots(3, 3)
87 | axs[0, 0].set_facecolor("#ddddff")
88 | axs[2, 2].set_facecolor("#ffffdd")
89 | \end{lstlisting}
90 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{layout-subplot-color.pdf}}
91 | \end{tabular}
92 |
93 | % -----------------------------------------------------------------------------
94 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
95 | \begin{lstlisting}[belowskip=-\baselineskip]
96 | gs = fig.add_gridspec(3, 3)
97 | ax = fig.add_subplot(gs[0, :])
98 | ax.set_facecolor("#ddddff")
99 | \end{lstlisting}
100 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{layout-gridspec-color.pdf}}
101 | \end{tabular}
102 |
103 | % -----------------------------------------------------------------------------
104 | \begin{tabular}{@{}m{.821\linewidth}m{.169\linewidth}}
105 | \begin{lstlisting}[belowskip=-\baselineskip]
106 | fig, ax = plt.subplots()
107 | ax.spines["top"].set_color("None")
108 | ax.spines["right"].set_color("None")
109 | \end{lstlisting}
110 | & \raisebox{-0.75em}{\includegraphics[width=\linewidth]{layout-spines.pdf}}
111 | \end{tabular}
112 |
113 |
114 |
115 | % -----------------------------------------------------------------------------
116 | \subsection*{\rmfamily Ticks \& labels}
117 |
118 | \begin{lstlisting}[basicstyle=\ttfamily\small]
119 | from mpl.ticker import MultipleLocator as ML
120 | from mpl.ticker import ScalarFormatter as SF
121 | ax.xaxis.set_minor_locator(ML(0.2))
122 | ax.xaxis.set_minor_formatter(SF())
123 | ax.tick_params(axis='x',which='minor',rotation=90)
124 | \end{lstlisting}
125 | \includegraphics[width=\linewidth]{tick-multiple-locator.pdf}
126 |
127 | % -----------------------------------------------------------------------------
128 | \subsection*{\rmfamily Lines \& markers}
129 |
130 | \begin{lstlisting}
131 | X = np.linspace(0.1, 10*np.pi, 1000)
132 | Y = np.sin(X)
133 | ax.plot(X, Y, "C1o:", markevery=50, mec="1.0")
134 | \end{lstlisting}
135 | \includegraphics[width=\linewidth]{sine-marker.pdf}
136 |
137 | % -----------------------------------------------------------------------------
138 | \subsection*{\rmfamily Scales \& projections}
139 |
140 | \begin{lstlisting}
141 | fig, ax = plt.subplots()
142 | ax.set_xscale("log")
143 | ax.plot(X, Y, "C1o-", markevery=50, mec="1.0")
144 | \end{lstlisting}
145 | \includegraphics[width=\linewidth]{sine-logscale.pdf}
146 |
147 | \subsection*{\rmfamily Text \& ornaments}
148 | \begin{lstlisting}[]
149 | ax.fill_betweenx([-1, 1], [0], [2*np.pi])
150 | ax.text(0, -1, r" Period $\Phi$")
151 | \end{lstlisting}
152 | \includegraphics[width=\linewidth]{sine-period.pdf}
153 |
154 |
155 | % -----------------------------------------------------------------------------
156 | \subsection*{\rmfamily Legend}
157 | \begin{lstlisting}[]
158 | ax.plot(X, np.sin(X), "C0", label="Sine")
159 | ax.plot(X, np.cos(X), "C1", label="Cosine")
160 | ax.legend(bbox_to_anchor=(0,1,1,.1), ncol=2,
161 | mode="expand", loc="lower left")
162 | \end{lstlisting}
163 | \includegraphics[width=\linewidth]{sine-legend.pdf}
164 |
165 | % -----------------------------------------------------------------------------
166 | \subsection*{\rmfamily Annotation}
167 | \begin{lstlisting}[]
168 | ax.annotate("A", (X[250],Y[250]), (X[250],-1),
169 | ha="center", va="center", arrowprops={
170 | "arrowstyle": "->", "color": "C1"})
171 | \end{lstlisting}
172 | \includegraphics[width=\linewidth]{sine-annotate.pdf}
173 |
174 | % -----------------------------------------------------------------------------
175 | \subsection*{\rmfamily Colors}
176 |
177 | Any color can be used, but Matplotlib offers sets of colors:\\
178 | \includegraphics[width=\linewidth]{colors-cycle.pdf} \smallskip
179 | \includegraphics[width=\linewidth]{colors-grey.pdf}\\
180 | %As well as nice colormaps (viridis an magma):\\
181 | %\includegraphics[width=\linewidth]{colormap-viridis.pdf} \smallskip
182 | %\includegraphics[width=\linewidth]{colormap-magma.pdf} \medskip
183 |
184 | % -----------------------------------------------------------------------------
185 | \vspace{-1em}
186 | \subsection*{\rmfamily Size \& DPI}
187 |
188 | Consider a square figure to be included in a two-column A4 paper with
189 | 2\,cm margins on each side and a column separation of 1\,cm. The width of
190 | a figure is (21 - 2*2 - 1)/2 = 8\,cm. One inch being 2.54\,cm, figure size
191 | should be 3.15$\times$3.15\,in.
192 | \begin{lstlisting}[]
193 | fig = plt.figure(figsize=(3.15, 3.15), dpi=50)
194 | plt.savefig("figure.pdf", dpi=600)
195 | \end{lstlisting}
196 |
197 |
198 | \vfill
199 | %
200 | {\scriptsize
201 | Matplotlib 3.8.2 handout for intermediate users.
202 | Copyright (c) 2021 Matplotlib Development Team.
203 | Released under a CC-BY 4.0 International License.
204 | Supported by NumFOCUS.
205 | \par}
206 |
207 |
208 |
209 | \end{multicols*}
210 | \end{document}
211 |
--------------------------------------------------------------------------------
/handout-tips.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pt,landscape,a4paper]{article}
2 | \usepackage[right=10mm, left=10mm, top=10mm, bottom=10mm]{geometry}
3 | \usepackage[utf8]{inputenc}
4 | \usepackage[T1]{fontenc}
5 | \usepackage[english]{babel}
6 | \usepackage[rm,light]{roboto}
7 | \usepackage{xcolor}
8 | \usepackage{graphicx}
9 | \graphicspath{{./figures/}}
10 | \usepackage{multicol}
11 | \usepackage{colortbl}
12 | \usepackage{array}
13 | \setlength\parindent{0pt}
14 | \setlength{\tabcolsep}{2pt}
15 | \baselineskip=0pt
16 | \setlength\columnsep{1em}
17 | \definecolor{Gray}{gray}{0.85}
18 |
19 | % --- Listing -----------------------------------------------------------------
20 | \usepackage{listings}
21 | \lstset{
22 | frame=tb, framesep=4pt, framerule=0pt,
23 | backgroundcolor=\color{black!5},
24 | basicstyle=\ttfamily\footnotesize,
25 | commentstyle=\ttfamily\color{black!50},
26 | breakatwhitespace=false,
27 | breaklines=true,
28 | extendedchars=true,
29 | keepspaces=true,
30 | language=Python,
31 | rulecolor=\color{black},
32 | showspaces=false,
33 | showstringspaces=false,
34 | showtabs=false,
35 | tabsize=2,
36 | %
37 | emph = {
38 | plot, scatter, imshow, bar, contourf, pie, subplots, spines,
39 | add_gridspec, add_subplot, set_xscale, set_minor_locator, linestyle,
40 | dash_capstyle, projection, Stroke, Normal, add_axes, label, savefig,
41 | get_cmap, histtype, annotate, set_minor_formatter, tick_params,
42 | fill_betweenx, text, legend, errorbar, boxplot, hist, title, xlabel,
43 | ylabel, suptitle, fraction, pad, set_fontname, get_xticklabels},
44 | emphstyle = {\ttfamily\bfseries}
45 | }
46 |
47 | % --- Fonts -------------------------------------------------------------------
48 | \usepackage{fontspec}
49 | \usepackage[babel=true]{microtype}
50 | \defaultfontfeatures{Ligatures = TeX, Mapping = tex-text}
51 | \setsansfont{Roboto} [ Path = fonts/roboto/Roboto-,
52 | Extension = .ttf,
53 | UprightFont = Light,
54 | ItalicFont = LightItalic,
55 | BoldFont = Regular,
56 | BoldItalicFont = Italic ]
57 | \setromanfont{RobotoSlab} [ Path = fonts/roboto-slab/RobotoSlab-,
58 | Extension = .ttf,
59 | UprightFont = Light,
60 | BoldFont = Bold ]
61 | \setmonofont{RobotoMono} [ Path = fonts/roboto-mono/RobotoMono-,
62 | Extension = .ttf,
63 | Scale = 0.90,
64 | UprightFont = Light,
65 | ItalicFont = LightItalic,
66 | BoldFont = Regular,
67 | BoldItalicFont = Italic ]
68 | \renewcommand{\familydefault}{\sfdefault}
69 |
70 | % -----------------------------------------------------------------------------
71 | \begin{document}
72 | \thispagestyle{empty}
73 |
74 | \section*{\LARGE \rmfamily
75 | Matplotlib \textcolor{orange}{\mdseries tips \& tricks}}
76 |
77 | \begin{multicols*}{3}
78 |
79 |
80 | % -----------------------------------------------------------------------------
81 | \subsection*{\rmfamily Transparency}
82 |
83 | Scatter plots can be enhanced by using transparency (alpha) in order
84 | to show area with higher density. Multiple scatter plots can be
85 | used to delineate a frontier.
86 |
87 | \begin{tabular}{@{}m{.774\linewidth}m{.216\linewidth}}
88 | \begin{lstlisting}[belowskip=-\baselineskip]
89 | X = np.random.normal(-1, 1, 500)
90 | Y = np.random.normal(-1, 1, 500)
91 | ax.scatter(X, Y, 50, "0.0", lw=2) # optional
92 | ax.scatter(X, Y, 50, "1.0", lw=0) # optional
93 | ax.scatter(X, Y, 40, "C1", lw=0, alpha=0.1)
94 | \end{lstlisting} &
95 | \raisebox{-0.75em}{\includegraphics[width=\linewidth]{tip-transparency.pdf}}
96 | \end{tabular}
97 |
98 | % -----------------------------------------------------------------------------
99 | \subsection*{\rmfamily Rasterization}
100 | If your figure has many graphical elements, such as a huge
101 | scatter, you can rasterize them to save memory and keep other elements
102 | in vector format.
103 | \begin{lstlisting}
104 | X = np.random.normal(-1, 1, 10_000)
105 | Y = np.random.normal(-1, 1, 10_000)
106 | ax.scatter(X, Y, rasterized=True)
107 | fig.savefig("rasterized-figure.pdf", dpi=600)
108 | \end{lstlisting}
109 |
110 | % -----------------------------------------------------------------------------
111 | \subsection*{\rmfamily Offline rendering}
112 |
113 | Use the Agg backend to render a figure directly in an array.
114 | \begin{lstlisting}
115 | from matplotlib.backends.backend_agg import FigureCanvas
116 | canvas = FigureCanvas(Figure()))
117 | ... # draw some stuff
118 | canvas.draw()
119 | Z = np.array(canvas.renderer.buffer_rgba())
120 | \end{lstlisting}
121 |
122 | % -----------------------------------------------------------------------------
123 | \subsection*{\rmfamily Range of continuous colors}
124 |
125 | You can use colormap to pick from a range of continuous colors.
126 |
127 | \begin{tabular}{@{}m{.774\linewidth}m{.216\linewidth}}
128 | \begin{lstlisting}[belowskip=-\baselineskip]
129 | X = np.random.randn(1000, 4)
130 | cmap = plt.get_cmap("Oranges")
131 | colors = cmap([0.2, 0.4, 0.6, 0.8])
132 |
133 | ax.hist(X, 2, histtype='bar', color=colors)
134 | \end{lstlisting} &
135 | \raisebox{-0.75em}{\includegraphics[width=\linewidth]{tip-color-range.pdf}}
136 | \end{tabular}
137 |
138 | % -----------------------------------------------------------------------------
139 | \subsection*{\rmfamily Text outline}
140 | Use text outline to make text more visible.
141 |
142 | \begin{tabular}{@{}m{.774\linewidth}m{.216\linewidth}}
143 | \begin{lstlisting}[belowskip=-\baselineskip]
144 | import matplotlib.patheffects as fx
145 | text = ax.text(0.5, 0.1, "Label")
146 | text.set_path_effects([
147 | fx.Stroke(linewidth=3, foreground='1.0'),
148 | fx.Normal()])
149 | \end{lstlisting} &
150 | \raisebox{-0.75em}{\includegraphics[width=\linewidth]{tip-outline.pdf}}
151 | \end{tabular}
152 |
153 |
154 | % -----------------------------------------------------------------------------
155 | \subsection*{\rmfamily Multiline plot}
156 | You can plot several lines at once using {\em None} as separator.
157 |
158 | \begin{lstlisting}
159 | X,Y = [], []
160 | for x in np.linspace(0, 10*np.pi, 100):
161 | X.extend([x, x, None]), Y.extend([0, sin(x), None])
162 | ax.plot(X, Y, "black")
163 | \end{lstlisting}
164 | \includegraphics[width=\linewidth]{tip-multiline.pdf}
165 |
166 | % -----------------------------------------------------------------------------
167 | \subsection*{\rmfamily Dotted lines}
168 | To have rounded dotted lines, use a custom {\ttfamily linestyle} and
169 | modify {\ttfamily dash\_capstyle}.
170 | \begin{lstlisting}
171 | ax.plot([0, 1], [0, 0], "C1",
172 | linestyle=(0, (0.01, 1)), dash_capstyle="round")
173 | ax.plot([0, 1], [1, 1], "C1",
174 | linestyle=(0, (0.01, 2)), dash_capstyle="round")
175 | \end{lstlisting}
176 | \includegraphics[width=\linewidth]{tip-dotted.pdf}
177 |
178 | % -----------------------------------------------------------------------------
179 | \subsection*{\rmfamily Combining axes}
180 | You can use overlaid axes with different projections.
181 |
182 | \begin{tabular}{@{}m{.774\linewidth}m{.216\linewidth}}
183 | \begin{lstlisting}[belowskip=-\baselineskip]
184 | ax1 = fig.add_axes([0, 0, 1, 1],
185 | label="cartesian")
186 | ax2 = fig.add_axes([0, 0, 1, 1],
187 | label="polar",
188 | projection="polar")
189 | \end{lstlisting} &
190 | \raisebox{-0.75em}{\includegraphics[width=\linewidth]{tip-dual-axis.pdf}}
191 | \end{tabular}
192 |
193 | \subsection*{\rmfamily Colorbar adjustment}
194 | You can adjust a colorbar's size when adding it.
195 |
196 | \begin{tabular}{@{}m{.754\linewidth}m{.236\linewidth}}
197 | \begin{lstlisting}[belowskip=-\baselineskip]
198 | im = ax.imshow(Z)
199 |
200 | cb = plt.colorbar(im,
201 | fraction=0.046, pad=0.04)
202 | cb.set_ticks([])
203 | \end{lstlisting} &
204 | \raisebox{-0.75em}{\includegraphics[width=\linewidth]{tip-colorbar.pdf}}
205 | \end{tabular}
206 |
207 | \subsection*{\rmfamily Taking advantage of typography}
208 | You can use a condensed font such as Roboto
209 | Condensed to save space on tick labels.
210 | \begin{lstlisting}
211 | for tick in ax.get_xticklabels(which='both'):
212 | tick.set_fontname("Roboto Condensed")
213 | \end{lstlisting}
214 | \includegraphics[width=\linewidth]{tip-font-family.pdf}
215 |
216 | \subsection*{\rmfamily Getting rid of margins}
217 | Once your figure is finished, you can call {\ttfamily tight\_layout()}
218 | to remove white margins. If there are remaining margins, you can use
219 | the {\ttfamily pdfcrop} utility (comes with TeX live).
220 |
221 |
222 | \subsection*{\rmfamily Hatching}
223 | You can achieve a nice visual effect with thick hatch patterns.
224 |
225 | \begin{tabular}{@{}m{.774\linewidth}m{.216\linewidth}}
226 | \begin{lstlisting}[belowskip=-\baselineskip]
227 | cmap = plt.get_cmap("Oranges")
228 | plt.rcParams['hatch.color'] = cmap(0.2)
229 | plt.rcParams['hatch.linewidth'] = 8
230 | ax.bar(X, Y, color=cmap(0.6), hatch="/")
231 | \end{lstlisting} &
232 | \raisebox{-0.75em}{\includegraphics[width=\linewidth]{tip-hatched.pdf}}
233 | \end{tabular}
234 |
235 |
236 | \subsection*{\rmfamily Read the documentation}
237 |
238 | Matplotlib comes with an extensive documentation explaining the
239 | details of each command and is generally accompanied by examples.
240 | Together with the huge online gallery, this documentation is a
241 | gold-mine.
242 |
243 | \vfill
244 | %
245 | {\scriptsize
246 | Matplotlib 3.8.2 handout for tips \& tricks.
247 | Copyright (c) 2021 Matplotlib Development Team.
248 | Released under a CC-BY 4.0 International License.
249 | Supported by NumFOCUS.
250 | \par}
251 |
252 |
253 |
254 | \end{multicols*}
255 | \end{document}
256 |
--------------------------------------------------------------------------------
/logos/logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matplotlib/cheatsheets/f02ebb5f02abd3c5d5b02bb1f22737ab87e92a08/logos/logo2.png
--------------------------------------------------------------------------------
/logos/mpl-logos2.py:
--------------------------------------------------------------------------------
1 | """
2 | ===============
3 | Matplotlib logo
4 | ===============
5 |
6 | This example generates the current matplotlib logo.
7 | """
8 |
9 | import numpy as np
10 | import matplotlib.pyplot as plt
11 | import matplotlib.cm as cm
12 | import matplotlib.font_manager
13 | from matplotlib.patches import Rectangle, PathPatch
14 | from matplotlib.textpath import TextPath
15 | import matplotlib.transforms as mtrans
16 |
17 | MPL_BLUE = '#11557c'
18 |
19 |
20 | def get_font_properties():
21 | # The original font is Calibri, if that is not installed, we fall back
22 | # to Carlito, which is metrically equivalent.
23 | if 'Calibri' in matplotlib.font_manager.findfont('Calibri:bold'):
24 | return matplotlib.font_manager.FontProperties(family='Calibri',
25 | weight='bold')
26 | if 'Carlito' in matplotlib.font_manager.findfont('Carlito:bold'):
27 | print('Original font not found. Falling back to Carlito. '
28 | 'The logo text will not be in the correct font.')
29 | return matplotlib.font_manager.FontProperties(family='Carlito',
30 | weight='bold')
31 | print('Original font not found. '
32 | 'The logo text will not be in the correct font.')
33 | return None
34 |
35 |
36 | def create_icon_axes(fig, ax_position, lw_bars, lw_grid, lw_border, rgrid):
37 | """
38 | Create a polar axes containing the matplotlib radar plot.
39 |
40 | Parameters
41 | ----------
42 | fig : matplotlib.figure.Figure
43 | The figure to draw into.
44 | ax_position : (float, float, float, float)
45 | The position of the created Axes in figure coordinates as
46 | (x, y, width, height).
47 | lw_bars : float
48 | The linewidth of the bars.
49 | lw_grid : float
50 | The linewidth of the grid.
51 | lw_border : float
52 | The linewidth of the Axes border.
53 | rgrid : array-like
54 | Positions of the radial grid.
55 |
56 | Returns
57 | -------
58 | ax : matplotlib.axes.Axes
59 | The created Axes.
60 | """
61 | with plt.rc_context({'axes.edgecolor': MPL_BLUE,
62 | 'axes.linewidth': lw_border}):
63 | ax = fig.add_axes(ax_position, projection='polar')
64 | ax.set_axisbelow(True)
65 |
66 | N = 7
67 | arc = 2. * np.pi
68 | theta = np.arange(0.0, arc, arc / N)
69 | radii = np.array([2, 6, 8, 7, 4, 5, 8])
70 | width = np.pi / 4 * np.array([0.4, 0.4, 0.6, 0.8, 0.2, 0.5, 0.3])
71 | bars = ax.bar(theta, radii, width=width, bottom=0.0, align='edge',
72 | edgecolor='0.3', lw=lw_bars)
73 | for r, bar in zip(radii, bars):
74 | color = *cm.jet(r / 10.)[:3], 0.6 # color from jet with alpha=0.6
75 | bar.set_facecolor(color)
76 |
77 | ax.tick_params(labelbottom=False, labeltop=False,
78 | labelleft=False, labelright=False)
79 |
80 | ax.grid(lw=lw_grid, color='0.9')
81 | ax.set_rmax(9)
82 | ax.set_yticks(rgrid)
83 |
84 | # the actual visible background - extends a bit beyond the axis
85 | ax.add_patch(Rectangle((0, 0), arc, 9.58,
86 | facecolor='white', zorder=0,
87 | clip_on=False, in_layout=False))
88 | return ax
89 |
90 |
91 | def create_text_axes(fig, height_px):
92 | """Create an axes in *fig* that contains 'matplotlib' as Text."""
93 | ax = fig.add_axes((0, 0, 1, 1))
94 | ax.set_aspect("equal")
95 | ax.set_axis_off()
96 |
97 | path = TextPath((0, 0), "matplotlib", size=height_px * 0.8,
98 | prop=get_font_properties())
99 |
100 | fp = get_font_properties()
101 | fp.set_weight('light')
102 | path1 = TextPath((80, -13), 'Cheat sheet', size=height_px * 0.12,
103 | prop=fp)
104 | path2 = TextPath((310, -13), f'Version {matplotlib. __version__}',
105 | size=height_px * 0.12,
106 | prop=fp)
107 |
108 | angle = 4.25 # degrees
109 | trans = mtrans.Affine2D().skew_deg(angle, 0)
110 |
111 | patch = PathPatch(path, transform=trans + ax.transData, color=MPL_BLUE,
112 | lw=0)
113 | patch1 = PathPatch(path1, transform=trans + ax.transData, color=MPL_BLUE,
114 | lw=0)
115 | patch2 = PathPatch(path2, color=MPL_BLUE,
116 | lw=0)
117 |
118 | ax.add_patch(patch)
119 | ax.add_patch(patch1)
120 | ax.add_patch(patch2)
121 | ax.autoscale()
122 |
123 |
124 | def make_logo(height_px, lw_bars, lw_grid, lw_border, rgrid, with_text=False):
125 | """
126 | Create a full figure with the Matplotlib logo.
127 |
128 | Parameters
129 | ----------
130 | height_px : int
131 | Height of the figure in pixel.
132 | lw_bars : float
133 | The linewidth of the bar border.
134 | lw_grid : float
135 | The linewidth of the grid.
136 | lw_border : float
137 | The linewidth of icon border.
138 | rgrid : sequence of float
139 | The radial grid positions.
140 | with_text : bool
141 | Whether to draw only the icon or to include 'matplotlib' as text.
142 | """
143 | dpi = 100
144 | height = height_px / dpi
145 | figsize = (5 * height, height) if with_text else (height, height)
146 | fig = plt.figure(figsize=figsize, dpi=dpi)
147 | fig.patch.set_alpha(0)
148 |
149 | if with_text:
150 | create_text_axes(fig, height_px)
151 | ax_pos = (0.535, 0.12, .17, 0.75) if with_text else (0.03, 0.03, .94, .94)
152 | ax = create_icon_axes(fig, ax_pos, lw_bars, lw_grid, lw_border, rgrid)
153 |
154 | fig.savefig('mpl-logo2.pdf')
155 |
156 | return fig, ax
157 |
158 |
159 | ##############################################################################
160 | # A large logo:
161 |
162 | make_logo(height_px=110, lw_bars=0.7, lw_grid=0.5, lw_border=1,
163 | rgrid=[1, 3, 5, 7])
164 |
165 | ##############################################################################
166 | # A small 32px logo:
167 |
168 | make_logo(height_px=32, lw_bars=0.3, lw_grid=0.3, lw_border=0.3, rgrid=[5])
169 |
170 | ##############################################################################
171 | # A large logo including text, as used on the matplotlib website.
172 |
173 | make_logo(height_px=110, lw_bars=0.7, lw_grid=0.5, lw_border=1,
174 | rgrid=[1, 3, 5, 7], with_text=True)
175 | # plt.show()
176 |
--------------------------------------------------------------------------------
/logos/numfocus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matplotlib/cheatsheets/f02ebb5f02abd3c5d5b02bb1f22737ab87e92a08/logos/numfocus.png
--------------------------------------------------------------------------------
/requirements/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: default
2 | default: all
3 |
4 | .PHONY: all
5 | all: requirements.txt
6 |
7 | .PHONY: install
8 | install: requirements.txt
9 | pip-sync $^
10 |
11 | %.txt: %.in
12 | pip-compile $<
13 |
--------------------------------------------------------------------------------
/requirements/requirements.in:
--------------------------------------------------------------------------------
1 | autopep8
2 | bump2version
3 | cartopy==0.22.0
4 | flake8
5 | matplotlib==3.8.2
6 | pillow>=9
7 | pdfx
8 | pip-tools
9 | pre-commit
10 | scipy
11 | # Docs
12 | mpl-sphinx-theme~=3.8.0
13 | pydata-sphinx-theme==0.13.3
14 | sphinx
15 | sphinx-design
16 |
--------------------------------------------------------------------------------
/requirements/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.10
3 | # by the following command:
4 | #
5 | # pip-compile requirements.in
6 | #
7 | accessible-pygments==0.0.4
8 | # via pydata-sphinx-theme
9 | alabaster==0.7.16
10 | # via sphinx
11 | autopep8==2.0.4
12 | # via -r requirements.in
13 | babel==2.14.0
14 | # via
15 | # pydata-sphinx-theme
16 | # sphinx
17 | beautifulsoup4==4.12.3
18 | # via pydata-sphinx-theme
19 | build==1.0.3
20 | # via pip-tools
21 | bump2version==1.0.1
22 | # via -r requirements.in
23 | cartopy==0.22.0
24 | # via -r requirements.in
25 | certifi==2024.7.4
26 | # via
27 | # pyproj
28 | # requests
29 | cffi==1.16.0
30 | # via cryptography
31 | cfgv==3.4.0
32 | # via pre-commit
33 | chardet==4.0.0
34 | # via
35 | # pdfminer-six
36 | # pdfx
37 | charset-normalizer==3.3.2
38 | # via requests
39 | click==8.1.7
40 | # via pip-tools
41 | contourpy==1.2.0
42 | # via matplotlib
43 | cryptography==44.0.1
44 | # via pdfminer-six
45 | cycler==0.12.1
46 | # via matplotlib
47 | distlib==0.3.8
48 | # via virtualenv
49 | docutils==0.20.1
50 | # via
51 | # pydata-sphinx-theme
52 | # sphinx
53 | filelock==3.13.1
54 | # via virtualenv
55 | flake8==7.0.0
56 | # via -r requirements.in
57 | fonttools==4.47.2
58 | # via matplotlib
59 | identify==2.5.33
60 | # via pre-commit
61 | idna==3.7
62 | # via requests
63 | imagesize==1.4.1
64 | # via sphinx
65 | jinja2==3.1.5
66 | # via sphinx
67 | kiwisolver==1.4.5
68 | # via matplotlib
69 | markupsafe==2.1.4
70 | # via jinja2
71 | matplotlib==3.8.2
72 | # via
73 | # -r requirements.in
74 | # cartopy
75 | # mpl-sphinx-theme
76 | mccabe==0.7.0
77 | # via flake8
78 | mpl-sphinx-theme==3.8.0
79 | # via -r requirements.in
80 | nodeenv==1.8.0
81 | # via pre-commit
82 | numpy==1.26.3
83 | # via
84 | # cartopy
85 | # contourpy
86 | # matplotlib
87 | # scipy
88 | # shapely
89 | packaging==23.2
90 | # via
91 | # build
92 | # cartopy
93 | # matplotlib
94 | # pydata-sphinx-theme
95 | # sphinx
96 | pdfminer-six==20201018
97 | # via pdfx
98 | pdfx==1.4.1
99 | # via -r requirements.in
100 | pillow==10.3.0
101 | # via
102 | # -r requirements.in
103 | # matplotlib
104 | pip-tools==7.3.0
105 | # via -r requirements.in
106 | platformdirs==4.2.0
107 | # via virtualenv
108 | pre-commit==3.6.0
109 | # via -r requirements.in
110 | pycodestyle==2.11.1
111 | # via
112 | # autopep8
113 | # flake8
114 | pycparser==2.21
115 | # via cffi
116 | pydata-sphinx-theme==0.13.3
117 | # via
118 | # -r requirements.in
119 | # mpl-sphinx-theme
120 | pyflakes==3.2.0
121 | # via flake8
122 | pygments==2.17.2
123 | # via
124 | # accessible-pygments
125 | # pydata-sphinx-theme
126 | # sphinx
127 | pyparsing==3.1.1
128 | # via matplotlib
129 | pyproj==3.6.1
130 | # via cartopy
131 | pyproject-hooks==1.0.0
132 | # via build
133 | pyshp==2.3.1
134 | # via cartopy
135 | python-dateutil==2.8.2
136 | # via matplotlib
137 | pyyaml==6.0.1
138 | # via pre-commit
139 | requests==2.32.2
140 | # via sphinx
141 | scipy==1.12.0
142 | # via -r requirements.in
143 | shapely==2.0.2
144 | # via cartopy
145 | six==1.16.0
146 | # via python-dateutil
147 | snowballstemmer==2.2.0
148 | # via sphinx
149 | sortedcontainers==2.4.0
150 | # via pdfminer-six
151 | soupsieve==2.5
152 | # via beautifulsoup4
153 | sphinx==7.2.6
154 | # via
155 | # -r requirements.in
156 | # pydata-sphinx-theme
157 | # sphinx-design
158 | sphinx-design==0.5.0
159 | # via -r requirements.in
160 | sphinxcontrib-applehelp==1.0.8
161 | # via sphinx
162 | sphinxcontrib-devhelp==1.0.6
163 | # via sphinx
164 | sphinxcontrib-htmlhelp==2.0.5
165 | # via sphinx
166 | sphinxcontrib-jsmath==1.0.1
167 | # via sphinx
168 | sphinxcontrib-qthelp==1.0.7
169 | # via sphinx
170 | sphinxcontrib-serializinghtml==1.1.10
171 | # via sphinx
172 | tomli==2.0.1
173 | # via
174 | # autopep8
175 | # build
176 | # pip-tools
177 | # pyproject-hooks
178 | typing-extensions==4.9.0
179 | # via pydata-sphinx-theme
180 | urllib3==2.2.2
181 | # via requests
182 | virtualenv==20.26.6
183 | # via pre-commit
184 | wheel==0.42.0
185 | # via pip-tools
186 |
187 | # The following packages are considered to be unsafe in a requirements file:
188 | # pip
189 | # setuptools
190 |
--------------------------------------------------------------------------------
/scripts/adjustements.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 | import matplotlib.patches as mpatches
11 | from matplotlib.collections import PatchCollection
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | mpl.style.use([
17 | ROOT_DIR / 'styles/base.mplstyle',
18 | ])
19 | mpl.rc('font', size=4)
20 | mpl.rc('lines', linewidth=0.5)
21 | mpl.rc('patch', linewidth=0.5)
22 |
23 |
24 | subplots_kw = dict(
25 | figsize=(5.7/2.54, 5.7/2.54 * 95/115),
26 | subplot_kw=dict(
27 | frameon=False,
28 | aspect=1,
29 | xlim=(0-5, 100+10),
30 | ylim=(-10, 80+5),
31 | xticks=[],
32 | yticks=[],
33 | ),
34 | )
35 |
36 | (fig, ax) = plt.subplots(**subplots_kw)
37 |
38 | box = mpatches.FancyBboxPatch(
39 | (0, 0), 100, 83, mpatches.BoxStyle("Round", pad=0, rounding_size=2),
40 | facecolor="0.9", edgecolor="black")
41 | ax.add_artist(box)
42 |
43 | box = mpatches.FancyBboxPatch(
44 | (0, 0), 100, 75, mpatches.BoxStyle("Round", pad=0, rounding_size=0),
45 | facecolor="white", edgecolor="black")
46 | ax.add_artist(box)
47 |
48 |
49 | box = mpatches.Rectangle(
50 | (5, 5), 45, 30, zorder=10,
51 | facecolor="white", edgecolor="black")
52 | ax.add_artist(box)
53 |
54 | box = mpatches.Rectangle(
55 | (5, 40), 45, 30, zorder=10,
56 | facecolor="white", edgecolor="black")
57 | ax.add_artist(box)
58 |
59 | box = mpatches.Rectangle(
60 | (55, 5), 40, 65, zorder=10,
61 | facecolor="white", edgecolor="black")
62 | ax.add_artist(box)
63 |
64 | # Window button
65 | X, Y = [5, 10, 15], [79, 79, 79]
66 | plt.scatter(X, Y, s=20, zorder=10,
67 | edgecolor="black", facecolor="white")
68 |
69 |
70 | # Window size extension
71 | X, Y = [0, 0], [0, -8]
72 | plt.plot(X, Y, color="black", linestyle=":", clip_on=False)
73 |
74 | X, Y = [100, 100], [0, -8]
75 | plt.plot(X, Y, color="black", linestyle=":", clip_on=False)
76 |
77 | X, Y = [100, 108], [0, 0]
78 | plt.plot(X, Y, color="black", linestyle=":", clip_on=False)
79 |
80 | X, Y = [100, 108], [75, 75]
81 | plt.plot(X, Y, color="black", linestyle=":", clip_on=False)
82 |
83 |
84 | def ext_arrow(p0, p1, p2, p3):
85 | p0, p1 = np.asarray(p0), np.asarray(p1)
86 | p2, p3 = np.asarray(p2), np.asarray(p3)
87 | ax.arrow(*p0, *(p1-p0), zorder=20, linewidth=0,
88 | length_includes_head=True, width=.4,
89 | head_width=2, head_length=2, color="black")
90 | ax.arrow(*p3, *(p2-p3), zorder=20, linewidth=0,
91 | length_includes_head=True, width=.4,
92 | head_width=2, head_length=2, color="black")
93 | plt.plot([p1[0], p2[0]], [p1[1], p2[1]], linewidth=.5, color="black")
94 |
95 |
96 | def int_arrow(p0, p1):
97 | p0, p1 = np.asarray(p0), np.asarray(p1)
98 | ax.arrow(*((p0+p1)/2), *((p1-p0)/2), zorder=20, linewidth=0,
99 | length_includes_head=True, width=.4,
100 | head_width=2, head_length=2, color="black")
101 | ax.arrow(*((p0+p1)/2), *(-(p1-p0)/2), zorder=20, linewidth=0,
102 | length_includes_head=True, width=.4,
103 | head_width=2, head_length=2, color="black")
104 |
105 |
106 | x = 0
107 | y = 10
108 | ext_arrow( (x-4, y), (x, y), (x+5, y), (x+9, y) )
109 | ax.text(x+9.5, y, "left", ha="left", va="center", zorder=20)
110 |
111 | x += 50
112 | ext_arrow( (x-4, y), (x, y), (x+5, y), (x+9, y) )
113 | ax.text(x-4.5, y, "wspace", ha="right", va="center", zorder=20)
114 |
115 | x += 45
116 | ext_arrow( (x-4, y), (x, y), (x+5, y), (x+9, y) )
117 | ax.text(x-4.5, y, "right", ha="right", va="center", zorder=20)
118 |
119 | y = 0
120 | x = 25
121 | ext_arrow( (x, y-4), (x, y), (x, y+5), (x, y+9) )
122 | ax.text(x, y+9.5, "bottom", ha="center", va="bottom", zorder=20)
123 |
124 | y += 35
125 | ext_arrow( (x, y-4), (x, y), (x, y+5), (x, y+9) )
126 | ax.text(x, y-4.5, "hspace", ha="center", va="top", zorder=20)
127 |
128 | y += 35
129 | ext_arrow( (x, y-4), (x, y), (x, y+5), (x, y+9) )
130 | ax.text(x, y-4.5, "top", ha="center", va="top", zorder=20)
131 |
132 | int_arrow((0, -5), (100, -5))
133 | ax.text(50, -5, "figure width", backgroundcolor="white", zorder=30,
134 | ha="center", va="center")
135 |
136 | int_arrow((105, 0), (105, 75))
137 | ax.text(105, 75/2, "figure height", backgroundcolor="white", zorder=30,
138 | rotation="vertical", ha="center", va="center")
139 |
140 | int_arrow((55, 62.5), (95, 62.5))
141 | ax.text(75, 62.5, "axes width", backgroundcolor="white", zorder=30,
142 | ha="center", va="center")
143 |
144 | int_arrow((62.5, 5), (62.5, 70))
145 | ax.text(62.5, 35, "axes height", backgroundcolor="white", zorder=30,
146 | rotation="vertical", ha="center", va="center")
147 |
148 |
149 | fig.savefig(ROOT_DIR / "figures/adjustments.pdf")
150 |
--------------------------------------------------------------------------------
/scripts/advanced-plots.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | # Script to generate all the advanced plots
7 | import pathlib
8 |
9 | import numpy as np
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | mpl.style.use([
17 | ROOT_DIR / 'styles/base.mplstyle',
18 | ROOT_DIR / 'styles/plotlet.mplstyle',
19 | ])
20 |
21 |
22 | subplot_kw = dict(
23 | xlim=(0, 8), xticks=np.arange(1, 8),
24 | ylim=(0, 8), yticks=np.arange(1, 8),
25 | )
26 |
27 | # Step plot
28 | # -----------------------------------------------------------------------------
29 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
30 | X = np.linspace(0, 10, 16)
31 | Y = 4 + 2*np.sin(2*X)
32 | ax.step(X, Y, color="C1")
33 | ax.grid()
34 | fig.savefig(ROOT_DIR / "figures/advanced-step.pdf")
35 |
36 | # Violin plot
37 | # -----------------------------------------------------------------------------
38 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
39 | np.random.seed(10)
40 | D = np.random.normal((3, 5, 4), (0.75, 1.00, 0.75), (200, 3))
41 | VP = ax.violinplot(D, [2, 4, 6], widths=1.5,
42 | showmeans=False, showmedians=False, showextrema=False)
43 | for body in VP['bodies']:
44 | body.set_facecolor('C1')
45 | body.set_alpha(1)
46 | ax.set_axisbelow(True)
47 | ax.grid()
48 | fig.savefig(ROOT_DIR / "figures/advanced-violin.pdf")
49 |
50 | # Boxplot
51 | # -----------------------------------------------------------------------------
52 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
53 | np.random.seed(10)
54 | D = np.random.normal((3, 5, 4), (1.25, 1.00, 1.25), (100, 3))
55 | VP = ax.boxplot(D, positions=[2, 4, 6], widths=1.5, patch_artist=True,
56 | showmeans=False, showfliers=False,
57 | medianprops={"color": "white",
58 | "linewidth": 0.25},
59 | boxprops={"facecolor": "C1",
60 | "edgecolor": "white",
61 | "linewidth": 0.25},
62 | whiskerprops={"color": "C1",
63 | "linewidth": 0.75},
64 | capprops={"color": "C1",
65 | "linewidth": 0.75})
66 | ax.set_axisbelow(True)
67 | ax.grid()
68 | fig.savefig(ROOT_DIR / "figures/advanced-boxplot.pdf")
69 |
70 | # Barbs plot
71 | # -----------------------------------------------------------------------------
72 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
73 | np.random.seed(1)
74 | X = [[2, 4, 6]]
75 | Y = [[1.5, 3, 2]]
76 | U = -np.ones((1, 3)) * 0
77 | V = -np.ones((1, 3)) * np.linspace(50, 100, 3)
78 | ax.barbs(X, Y, U, V, barbcolor="C1", flagcolor="C1", length=5, linewidth=0.5)
79 | ax.set_axisbelow(True)
80 | ax.grid()
81 | fig.savefig(ROOT_DIR / "figures/advanced-barbs.pdf")
82 |
83 | # Event plot
84 | # -----------------------------------------------------------------------------
85 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
86 | np.random.seed(1)
87 | X = [2, 4, 6]
88 | D = np.random.gamma(4, size=(3, 50))
89 | ax.eventplot(D, colors="C1", orientation="vertical", lineoffsets=X,
90 | linewidth=0.25)
91 | ax.set_axisbelow(True)
92 | ax.grid()
93 | fig.savefig(ROOT_DIR / "figures/advanced-event.pdf")
94 |
95 | # Errorbar plot
96 | # -----------------------------------------------------------------------------
97 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
98 | np.random.seed(1)
99 | X = [2, 4, 6]
100 | Y = [4, 5, 4]
101 | E = np.random.uniform(0.5, 1.5, 3)
102 | ax.errorbar(X, Y, E, color="C1", linewidth=0.75, capsize=1)
103 | ax.set_axisbelow(True)
104 | ax.grid()
105 | fig.savefig(ROOT_DIR / "figures/advanced-errorbar.pdf")
106 |
107 | # Hexbin plot
108 | # -----------------------------------------------------------------------------
109 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
110 | np.random.seed(1)
111 | X = np.random.uniform(1.5, 6.5, 100)
112 | Y = np.random.uniform(1.5, 6.5, 100)
113 | C = np.random.uniform(0, 1, 10000)
114 | ax.hexbin(X, Y, C, gridsize=4, linewidth=0.25, edgecolor="white",
115 | cmap=plt.get_cmap("Wistia"), alpha=1.0)
116 | ax.set_axisbelow(True)
117 | ax.grid()
118 | fig.savefig(ROOT_DIR / "figures/advanced-hexbin.pdf")
119 |
120 | # Hist plot
121 | # -----------------------------------------------------------------------------
122 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
123 | np.random.seed(1)
124 | X = 4 + np.random.normal(0, 1.5, 200)
125 | ax.hist(X, bins=8, facecolor="C1", linewidth=0.25, edgecolor="white")
126 | ax.set_ylim(0, 80), ax.set_yticks(np.arange(1, 80, 10))
127 | ax.set_axisbelow(True)
128 | ax.grid()
129 | fig.savefig(ROOT_DIR / "figures/advanced-hist.pdf")
130 |
131 | # Xcorr plot
132 | # -----------------------------------------------------------------------------
133 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
134 | np.random.seed(3)
135 | Y = np.random.uniform(-4, 4, 250)
136 | X = np.random.uniform(-4, 4, 250)
137 | ax.xcorr(X, Y, usevlines=True, maxlags=6, normed=True, lw=1,
138 | color="C1")
139 | ax.set_xlim(-8, 8), ax.set_xticks(np.arange(-8, 8, 2))
140 | ax.set_ylim(-.25, .25), ax.set_yticks(np.linspace(-.25, .25, 9))
141 | ax.set_axisbelow(True)
142 | ax.grid()
143 | fig.savefig(ROOT_DIR / "figures/advanced-xcorr.pdf")
144 |
--------------------------------------------------------------------------------
/scripts/anatomy.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Title: Scientific Visualisation - Python & Matplotlib
3 | # Author: Nicolas P. Rougier
4 | # License: BSD
5 | # ----------------------------------------------------------------------------
6 | import pathlib
7 |
8 | import numpy as np
9 | import matplotlib as mpl
10 | import matplotlib.pyplot as plt
11 | from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | mpl.style.use([
17 | ROOT_DIR / 'styles/base.mplstyle',
18 | ])
19 |
20 | np.random.seed(123)
21 |
22 | X = np.linspace(0.5, 3.5, 100)
23 | Y1 = 3+np.cos(X)
24 | Y2 = 1+np.cos(1+X/0.75)/2
25 | Y3 = np.random.uniform(Y1, Y2, len(X))
26 |
27 | (fig, ax) = plt.subplots(figsize=(8, 8), subplot_kw=dict(aspect=1))
28 |
29 |
30 | def minor_tick(x, pos):
31 | if not x % 1.0:
32 | return ""
33 | return "%.2f" % x
34 |
35 |
36 | ax.xaxis.set_major_locator(MultipleLocator(1.000))
37 | ax.xaxis.set_minor_locator(AutoMinorLocator(4))
38 | ax.yaxis.set_major_locator(MultipleLocator(1.000))
39 | ax.yaxis.set_minor_locator(AutoMinorLocator(4))
40 | ax.xaxis.set_minor_formatter(FuncFormatter(minor_tick))
41 |
42 | ax.set_xlim(0, 4)
43 | ax.set_ylim(0, 4)
44 |
45 | ax.tick_params(which='major', width=1.0)
46 | ax.tick_params(which='major', length=10)
47 | ax.tick_params(which='minor', width=1.0, labelsize=10)
48 | ax.tick_params(which='minor', length=5, labelsize=10, labelcolor='0.25')
49 |
50 | ax.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)
51 |
52 | ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label="Blue signal", zorder=10)
53 | ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label="Red signal")
54 | ax.plot(X, Y3, linewidth=0,
55 | marker='o', markerfacecolor='w', markeredgecolor='k')
56 |
57 | ax.set_title("Anatomy of a figure", fontsize=20, verticalalignment='bottom')
58 | ax.set_xlabel("X axis label")
59 | ax.set_ylabel("Y axis label")
60 |
61 | ax.legend(loc="upper right")
62 |
63 |
64 | def circle(x, y, radius=0.15):
65 | from matplotlib.patches import Circle
66 | from matplotlib.patheffects import withStroke
67 | circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,
68 | edgecolor='black', facecolor=(0, 0, 0, .0125),
69 | path_effects=[withStroke(linewidth=5, foreground='w')])
70 | ax.add_artist(circle)
71 |
72 |
73 | def text(x, y, text):
74 | ax.text(x, y, text, backgroundcolor="white",
75 | # fontname="Yanone Kaffeesatz", fontsize="large",
76 | ha='center', va='top', weight="regular", color='#000099')
77 |
78 |
79 | # Minor tick
80 | circle(0.50, -0.10)
81 | text(0.50, -0.32, "Minor tick label")
82 |
83 | # Major tick
84 | circle(-0.03, 4.00)
85 | text(0.03, 3.80, "Major tick")
86 |
87 | # Minor tick
88 | circle(0.00, 3.50)
89 | text(0.00, 3.30, "Minor tick")
90 |
91 | # Major tick label
92 | circle(-0.15, 3.00)
93 | text(-0.15, 2.80, "Major tick label")
94 |
95 | # X Label
96 | circle(1.80, -0.27)
97 | text(1.80, -0.45, "X axis label")
98 |
99 | # Y Label
100 | circle(-0.27, 1.80)
101 | text(-0.27, 1.6, "Y axis label")
102 |
103 | # Title
104 | circle(1.60, 4.13)
105 | text(1.60, 3.93, "Title")
106 |
107 | # Blue plot
108 | circle(1.75, 2.80)
109 | text(1.75, 2.60, "Line\n(line plot)")
110 |
111 | # Red plot
112 | circle(1.20, 0.60)
113 | text(1.20, 0.40, "Line\n(line plot)")
114 |
115 | # Scatter plot
116 | circle(3.20, 1.75)
117 | text(3.20, 1.55, "Markers\n(scatter plot)")
118 |
119 | # Grid
120 | circle(3.00, 3.00)
121 | text(3.00, 2.80, "Grid")
122 |
123 | # Legend
124 | circle(3.70, 3.80)
125 | text(3.70, 3.60, "Legend")
126 |
127 | # Axes
128 | circle(0.5, 0.5)
129 | text(0.5, 0.3, "Axes")
130 |
131 | # Figure
132 | circle(-0.3, 0.65)
133 | text(-0.3, 0.45, "Figure")
134 |
135 | color = '#000099'
136 | ax.annotate('Spines', xy=(4.0, 0.35), xytext=(3.3, 0.5), color=color,
137 | weight='regular', # fontsize="large", fontname="Yanone Kaffeesatz",
138 | arrowprops=dict(arrowstyle='->',
139 | connectionstyle="arc3",
140 | color=color))
141 |
142 | ax.annotate('', xy=(3.15, 0.0), xytext=(3.45, 0.45), color=color,
143 | weight='regular', # fontsize="large", fontname="Yanone Kaffeesatz",
144 | arrowprops=dict(arrowstyle='->',
145 | connectionstyle="arc3",
146 | color=color))
147 |
148 | fig.savefig(ROOT_DIR / "figures/anatomy.pdf")
149 | # plt.show()
150 |
--------------------------------------------------------------------------------
/scripts/animation.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | import matplotlib.animation as animation
4 |
5 | T = np.linspace(0, 2*np.pi, 100)
6 | S = np.sin(T)
7 | line, = plt.plot(T, S)
8 |
9 |
10 | def animate(i):
11 | line.set_ydata(np.sin(T+i/50))
12 |
13 |
14 | a=animation.FuncAnimation(
15 | plt.gcf(), animate, interval=5)
16 | # plt.show()
17 |
--------------------------------------------------------------------------------
/scripts/annotate.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 | fig = plt.figure(figsize=(6, 1))
15 | # ax = plt.subplot(111, frameon=False, aspect=.1)
16 | # b = 0.0
17 | ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1)
18 |
19 |
20 | plt.scatter([5.5], [0.75], s=100, c="k")
21 | plt.xlim(0, 6), plt.ylim(0, 1)
22 | plt.xticks([]), plt.yticks([])
23 |
24 | plt.annotate("text", (5.5, .75), (0.75, .75), size=16, va="center", ha="center",
25 | arrowprops=dict(facecolor='black', shrink=0.05))
26 |
27 | plt.text( 5.5, 0.6, "xy\nxycoords", size=10, va="top", ha="center", color=".5")
28 | plt.text( .75, 0.6, "xytext\ntextcoords", size=10, va="top", ha="center", color=".5")
29 |
30 | fig.savefig(ROOT_DIR / "figures/annotate.pdf")
31 | # plt.show()
32 |
--------------------------------------------------------------------------------
/scripts/annotation-arrow-styles.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import matplotlib.pyplot as plt
4 | import matplotlib.patches as mpatches
5 |
6 |
7 | ROOT_DIR = pathlib.Path(__file__).parent.parent
8 |
9 | styles = mpatches.ArrowStyle.get_styles()
10 |
11 |
12 | def demo_con_style(ax, connectionstyle):
13 | ax.text(.05, .95, connectionstyle.replace(",", ",\n"),
14 | family="Source Code Pro",
15 | transform=ax.transAxes, ha="left", va="top", size="x-small")
16 |
17 |
18 | (fig, axes) = plt.subplots(4, 4, figsize=(4, 2.5), frameon=False)
19 | for ax in axes.flatten():
20 | ax.axis("off")
21 | for i, (ax, style) in enumerate(zip(axes.flatten(), mpatches.ArrowStyle.get_styles())):
22 | x0, y0 = 0.8, 0.5
23 | x1, y1 = 0.2, 0.5
24 | ax.plot([x0, x1], [y0, y1], ".", color="0.25")
25 | ax.annotate("",
26 | xy=(x0, y0), xycoords='data',
27 | xytext=(x1, y1), textcoords='data',
28 | arrowprops=dict(arrowstyle=style,
29 | color="black",
30 | shrinkA=5, shrinkB=5,
31 | patchA=None, patchB=None,
32 | connectionstyle="arc3,rad=0"))
33 | ax.text( (x1+x0)/2, y0-0.2, style,
34 | transform=ax.transAxes,
35 | family="Source Code Pro", ha="center", va="top")
36 |
37 | fig.savefig(ROOT_DIR / "figures/annotation-arrow-styles.pdf")
38 | # plt.show()
39 |
--------------------------------------------------------------------------------
/scripts/annotation-connection-styles.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import matplotlib as mpl
4 | import matplotlib.pyplot as plt
5 |
6 |
7 | ROOT_DIR = pathlib.Path(__file__).parent.parent
8 |
9 | mpl.style.use([
10 | ROOT_DIR / 'styles/base.mplstyle',
11 | ROOT_DIR / 'styles/plotlet-grid.mplstyle',
12 | ])
13 | mpl.rc('lines', markersize=3)
14 |
15 |
16 | def demo_con_style(ax, connectionstyle):
17 | x1, y1 = 0.3, 0.2
18 | x2, y2 = 0.8, 0.6
19 | ax.plot([x1, x2], [y1, y2], ".")
20 | ax.annotate("",
21 | xy=(x1, y1), xycoords='data',
22 | xytext=(x2, y2), textcoords='data',
23 | arrowprops=dict(arrowstyle="->", lw=0.5, color="0.5",
24 | shrinkA=3, shrinkB=3,
25 | patchA=None, patchB=None,
26 | connectionstyle=connectionstyle),
27 | )
28 | ax.text(.05, .95, connectionstyle.replace(",", ",\n"),
29 | transform=ax.transAxes, ha="left", va="top", size=4)
30 |
31 |
32 | fig, axs = plt.subplots(3, 3, figsize=(5.7/2.54, 5.7/2.54))
33 | demo_con_style(axs[0, 0], "arc3,rad=0")
34 | demo_con_style(axs[0, 1], "arc3,rad=0.3")
35 | demo_con_style(axs[0, 2], "angle3,angleA=0,angleB=90")
36 | demo_con_style(axs[1, 0], "angle,angleA=-90,angleB=180,rad=0")
37 | demo_con_style(axs[1, 1], "angle,angleA=-90,angleB=180,rad=10")
38 | demo_con_style(axs[1, 2], "arc,angleA=-90,angleB=0,armA=0,armB=20,rad=0")
39 | demo_con_style(axs[2, 0], "bar,fraction=0.3")
40 | demo_con_style(axs[2, 1], "bar,fraction=-0.3")
41 | demo_con_style(axs[2, 2], "bar,angle=180,fraction=-0.2")
42 |
43 | for ax in axs.flat:
44 | ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1)
45 |
46 | fig.savefig(ROOT_DIR / "figures/annotation-connection-styles.pdf")
47 |
--------------------------------------------------------------------------------
/scripts/basic-plots.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | # Script to generate all the basic plots
7 | import pathlib
8 |
9 | import numpy as np
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | mpl.style.use([
17 | ROOT_DIR / 'styles/base.mplstyle',
18 | ROOT_DIR / 'styles/plotlet.mplstyle',
19 | ])
20 |
21 |
22 | subplot_kw = dict(
23 | xlim=(0, 8), xticks=np.arange(1, 8),
24 | ylim=(0, 8), yticks=np.arange(1, 8),
25 | )
26 |
27 | # Basic line plot
28 | # -----------------------------------------------------------------------------
29 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
30 | X = np.linspace(0, 10, 100)
31 | Y = 4 + 2*np.sin(2*X)
32 | ax.plot(X, Y, color="C1")
33 | ax.grid()
34 | fig.savefig(ROOT_DIR / "figures/basic-plot.pdf")
35 |
36 | # Basic line plot (color)
37 | # -----------------------------------------------------------------------------
38 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
39 | X = np.linspace(0, 10, 100)
40 | Y = 4 + 2*np.sin(2*X)
41 | ax.plot(X, Y, color="black")
42 | ax.grid()
43 | fig.savefig(ROOT_DIR / "figures/basic-plot-color.pdf")
44 |
45 | # Basic scatter plot
46 | # -----------------------------------------------------------------------------
47 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
48 | np.random.seed(3)
49 | X = 4 + np.random.normal(0, 1.25, 24)
50 | Y = 4 + np.random.normal(0, 1.25, len(X))
51 | ax.scatter(X, Y, 5, zorder=10,
52 | edgecolor="white", facecolor="C1", linewidth=0.25)
53 | ax.grid()
54 | fig.savefig(ROOT_DIR / "figures/basic-scatter.pdf")
55 |
56 | # Basic bar plot
57 | # -----------------------------------------------------------------------------
58 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
59 | np.random.seed(3)
60 | X = 0.5 + np.arange(8)
61 | Y = np.random.uniform(2, 7, len(X))
62 | ax.bar(X, Y, bottom=0, width=1,
63 | edgecolor="white", facecolor="C1", linewidth=0.25)
64 | ax.set_axisbelow(True)
65 | ax.grid()
66 | fig.savefig(ROOT_DIR / "figures/basic-bar.pdf")
67 |
68 | # Basic imshow plot
69 | # -----------------------------------------------------------------------------
70 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
71 | np.random.seed(3)
72 | Z = np.zeros((8, 8, 4))
73 | Z[:, :] = mpl.colors.to_rgba("C1")
74 | Z[..., 3] = np.random.uniform(0.25, 1.0, (8, 8))
75 | ax.imshow(Z, extent=[0, 8, 0, 8], interpolation="nearest")
76 | ax.grid(linewidth=0.25, color="white")
77 | fig.savefig(ROOT_DIR / "figures/basic-imshow.pdf")
78 |
79 | # Basic pcolormesh plot
80 | # -----------------------------------------------------------------------------
81 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
82 | np.random.seed(1)
83 | X, Y = np.meshgrid(np.linspace(-3, 3, 256), np.linspace(-3, 3, 256))
84 | Z = (1 - X/2. + X**5 + Y**3) * np.exp(-X**2 - Y**2)
85 | Z = Z - Z.min()
86 | plt.pcolormesh(X, Y, Z, cmap='Oranges', shading='auto')
87 | ax.set_xlim(-3, 3), ax.set_xticks(np.arange(-3, 4))
88 | ax.set_ylim(-3, 3), ax.set_yticks(np.arange(-3, 4))
89 | fig.savefig(ROOT_DIR / "figures/basic-pcolormesh.pdf")
90 |
91 | # Basic contour plot
92 | # -----------------------------------------------------------------------------
93 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
94 | colors = np.zeros((5, 4))
95 | colors[:] = mpl.colors.to_rgba("C1")
96 | colors[:, 3] = np.linspace(0.15, 0.85, len(colors))
97 | plt.contourf(Z, len(colors), extent=[0, 8, 0, 8], colors=colors)
98 | plt.contour(Z, len(colors), extent=[0, 8, 0, 8], colors="white",
99 | linewidths=0.125, nchunk=10)
100 | fig.savefig(ROOT_DIR / "figures/basic-contour.pdf")
101 |
102 | # Basic pie plot
103 | # -----------------------------------------------------------------------------
104 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
105 | X = [1, 2, 3, 4]
106 | colors = np.zeros((len(X), 4))
107 | colors[:] = mpl.colors.to_rgba("C1")
108 | colors[:, 3] = np.linspace(0.25, 0.75, len(X))
109 | ax.set_axisbelow(True)
110 | ax.grid(linewidth=0.25, color="0.75")
111 | ax.pie(X, colors=["white"] * len(X), radius=3, center=(4, 4),
112 | wedgeprops={"linewidth": 0.25, "edgecolor": "white"}, frame=True)
113 | ax.pie(X, colors=colors, radius=3, center=(4, 4),
114 | wedgeprops={"linewidth": 0.25, "edgecolor": "white"}, frame=True)
115 | fig.savefig(ROOT_DIR / "figures/basic-pie.pdf")
116 |
117 | # Basic text plot
118 | # -----------------------------------------------------------------------------
119 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
120 | ax.set_axisbelow(True)
121 | ax.grid(linewidth=0.25, color="0.75")
122 | ax.text(4, 4, "TEXT", color="C1", size=8, weight="bold",
123 | ha="center", va="center", rotation=25)
124 | fig.savefig(ROOT_DIR / "figures/basic-text.pdf")
125 |
126 | # Basic fill plot
127 | # -----------------------------------------------------------------------------
128 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
129 | np.random.seed(1)
130 | X = np.linspace(0, 8, 16)
131 | Y1 = 3 + 4*X/8 + np.random.uniform(0.0, 0.5, len(X))
132 | Y2 = 1 + 2*X/8 + np.random.uniform(0.0, 0.5, len(X))
133 | plt.fill_between(X, Y1, Y2, color="C1", alpha=.5, linewidth=0)
134 | plt.plot(X, (Y1+Y2)/2, color="C1", linewidth=0.5)
135 | ax.set_axisbelow(True)
136 | ax.grid(color="0.75")
137 | fig.savefig(ROOT_DIR / "figures/basic-fill.pdf")
138 |
139 | # Basic quiver plot
140 | # -----------------------------------------------------------------------------
141 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
142 | np.random.seed(1)
143 | T = np.linspace(0, 2*np.pi, 8)
144 | X, Y = 4 + np.cos(T), 4 + np.sin(T)
145 | U, V = 1.5*np.cos(T), 1.5*np.sin(T)
146 | plt.quiver(X, Y, U, V, color="C1",
147 | angles='xy', scale_units='xy', scale=0.5, width=.05)
148 | ax.set_axisbelow(True)
149 | ax.grid(color="0.75")
150 | fig.savefig(ROOT_DIR / "figures/basic-quiver.pdf")
151 |
--------------------------------------------------------------------------------
/scripts/colorbar.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | import pathlib
7 |
8 | import numpy as np
9 | import matplotlib as mpl
10 | import matplotlib.pyplot as plt
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 | fig = plt.figure(figsize=(6, .65))
16 | # ax = plt.subplot(111, frameon=False, aspect=.1)
17 | b = 0.025
18 | ax = fig.add_axes([b, 10*b, 1-2*b, 1-10*b], frameon=False, aspect=0.05)
19 |
20 | cmap = plt.get_cmap("Oranges")
21 | norm = mpl.colors.Normalize(vmin=0, vmax=1)
22 | sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
23 | sm.set_array([])
24 | plt.colorbar(sm, cax=ax, ticks=np.linspace(0, 1, 11),
25 | orientation="horizontal")
26 |
27 | fig.savefig(ROOT_DIR / "figures/colorbar.pdf")
28 | # plt.show()
29 |
--------------------------------------------------------------------------------
/scripts/colormaps.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import numpy as np
4 | import matplotlib.pyplot as plt
5 |
6 |
7 | ROOT_DIR = pathlib.Path(__file__).parent.parent
8 |
9 | figsize = 4.0, 0.25
10 | fig = plt.figure(figsize=figsize)
11 | ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1)
12 | ymin, ymax= 0, 1
13 | xmin, xmax = 0, figsize[0]/figsize[1]
14 |
15 | # Uniform colormaps
16 | # -----------------------------------------------------------------------------
17 | cmaps = ('viridis', 'plasma', 'inferno', 'magma', 'cividis',
18 |
19 | 'PRGn', 'PiYG', 'RdYlGn', 'BrBG', 'RdGy', 'PuOr', 'RdBu',
20 | 'RdYlBu', 'Spectral', 'coolwarm', 'bwr', 'seismic',
21 |
22 | 'tab10', 'tab20', 'tab20b', 'tab20c',
23 | 'Pastel1', 'Pastel2', 'Paired',
24 | 'Set1', 'Set2', 'Set3', 'Accent', 'Dark2',
25 |
26 | 'Greys', 'Reds', 'Oranges', 'YlOrBr', 'YlOrRd', 'OrRd',
27 | 'PuRd', 'RdPu', 'BuPu', 'Purples', 'YlGnBu', 'Blues',
28 | 'PuBu', 'GnBu', 'PuBuGn', 'BuGn', 'Greens', 'YlGn',
29 |
30 | 'bone', 'gray', 'pink', 'afmhot', 'hot', 'gist_heat', 'copper',
31 | 'Wistia', 'autumn', 'summer', 'spring', 'cool', 'winter',
32 |
33 | 'twilight', 'twilight_shifted', 'hsv',
34 |
35 | 'terrain', 'ocean', 'gist_earth', 'cubehelix', 'rainbow'
36 | )
37 |
38 | for name in cmaps:
39 | # The maximum number of segments in a cmap is 256, and for anything smaller,
40 | # the cmap will map as a suitably discrete set of colours.
41 | Z = np.linspace(0, 1, 256).reshape(1, 256)
42 |
43 | ax.imshow(Z, extent=[xmin, xmax, ymin, ymax], cmap=name)
44 | ax.set_xlim(xmin, xmax), ax.set_xticks([])
45 | ax.set_ylim(ymin, ymax), ax.set_yticks([])
46 |
47 | fig.savefig(ROOT_DIR / f"figures/colormap-{name}.pdf")
48 | ax.clear()
49 |
--------------------------------------------------------------------------------
/scripts/colornames.py:
--------------------------------------------------------------------------------
1 | """
2 | ========================
3 | Visualizing named colors
4 | ========================
5 |
6 | Simple plot example with the named colors and its visual representation.
7 | """
8 | import pathlib
9 |
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | mpl.style.use([
17 | ROOT_DIR / 'styles/base.mplstyle',
18 | ])
19 | mpl.rc('figure.constrained_layout', h_pad=0, w_pad=0, hspace=0, wspace=0)
20 |
21 | colors = dict(mpl.colors.BASE_COLORS, **mpl.colors.CSS4_COLORS)
22 |
23 | # Sort colors by hue, saturation, value and name.
24 | by_hsv = sorted((tuple(mpl.colors.rgb_to_hsv(mpl.colors.to_rgba(color)[:3])), name)
25 | for name, color in colors.items())
26 | sorted_names = [name for hsv, name in by_hsv]
27 |
28 | n = len(sorted_names)
29 | ncols = 3
30 | nrows = n // ncols
31 |
32 | fig, ax = plt.subplots(figsize=(4.5, 6))
33 |
34 | # Get height and width
35 | X, Y = fig.get_dpi() * fig.get_size_inches()
36 | h = Y / (nrows + 1)
37 | w = X / ncols
38 |
39 | for i, name in enumerate(sorted_names):
40 | col = i // nrows
41 | row = i % nrows
42 | y = Y - (row * h) - h
43 |
44 | xi_line = w * (col + 0.05)
45 | xf_line = w * (col + 0.25)
46 | xi_text = w * (col + 0.3)
47 |
48 | ax.text(xi_text, y, name, fontsize=7,
49 | horizontalalignment='left',
50 | verticalalignment='center')
51 |
52 | ax.hlines(y + h * 0.1, xi_line, xf_line,
53 | color=colors[name], linewidth=(h * 0.6))
54 |
55 | ax.set_xlim(0, X)
56 | ax.set_ylim(0, Y)
57 | ax.set_axis_off()
58 |
59 | fig.savefig(ROOT_DIR / "figures/colornames.pdf")
60 |
--------------------------------------------------------------------------------
/scripts/colors.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | import pathlib
7 |
8 | import numpy as np
9 | import matplotlib as mpl
10 | import matplotlib.pyplot as plt
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 | figsize = 4.0, 0.25
16 | fig = plt.figure(figsize=figsize)
17 | ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1)
18 | ymin, ymax= 0, 1
19 | xmin, xmax = 0, figsize[0]/figsize[1]
20 | ax.set_xlim(xmin, xmax), ax.set_xticks([])
21 | ax.set_ylim(ymin, ymax), ax.set_yticks([])
22 |
23 | # Uniform colormaps
24 | # -----------------------------------------------------------------------------
25 | palettes = {
26 | 'raw' : ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'],
27 | 'rgba' : [(1, 0, 0), (1, 0, 0, 0.75), (1, 0, 0, 0.50), (1, 0, 0, 0.25)],
28 | 'HexRGBA' : ["#FF0000", "#FF0000BB", "#FF000088", "#FF000044"],
29 | 'cycle' : ["C%d" % i for i in range(10)],
30 | 'grey' : ["%1.1f" % (i/10) for i in range(11)],
31 | 'name' : ["DarkRed", "Firebrick", "Crimson", "IndianRed", "Salmon" ] }
32 |
33 | for name, colors in palettes.items():
34 | C = mpl.colors.to_rgba_array(colors).reshape((1, len(colors), 4))
35 | ax.imshow(C, extent=[xmin, xmax, ymin, ymax])
36 |
37 | # Drop alpha by assuming we're on a white background PDF.
38 | alpha = C[0, :, 3]
39 | rgb = C[0, :, :3] * alpha[:, np.newaxis] + (1 - alpha[:, np.newaxis])
40 | # Same calculation for luminance as
41 | # https://matplotlib.org/stable/users/explain/colors/colors.html#comparison-between-x11-css4-and-xkcd-colors
42 | luma = 0.299 * rgb[:, 0] + 0.587 * rgb[:, 1] + 0.114 * rgb[:, 2]
43 |
44 | dx = (xmax-xmin)/len(colors)
45 | for i in range(len(colors)):
46 | text_color = "black" if luma[i] > 0.5 else "white"
47 | text = str(colors[i]).replace(' ', '')
48 | ax.text((i+0.5)*dx, (ymin+ymax)/2, text, color=text_color, zorder=10,
49 | family="Source Code Pro", size=9, ha="center", va="center")
50 |
51 | fig.savefig(ROOT_DIR / f"figures/colors-{name}.pdf")
52 | ax.clear()
53 |
--------------------------------------------------------------------------------
/scripts/extents.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 | mpl.style.use([
15 | ROOT_DIR / 'styles/base.mplstyle',
16 | ])
17 | mpl.rc('figure.constrained_layout', wspace=0.05)
18 |
19 | Z = np.arange(5*5).reshape(5, 5)
20 |
21 | (fig, axs) = plt.subplots(figsize=(8, 5), nrows=2, ncols=2)
22 |
23 | ax = axs[0, 0]
24 | ax.imshow(Z, extent=[0, 10, 0, 5], interpolation="nearest", origin="upper")
25 | ax.set_xlim(-1, 11), ax.set_xticks([])
26 | ax.set_ylim(-1, 6), ax.set_yticks([0, 5])
27 | ax.text(1, 4.5, "(0,0)", ha="center", va="center", color="white", size="large")
28 | ax.text(9, 0.5, "(4,4)", ha="center", va="center", color="black", size="large")
29 | ax.text(5.0, 5.5, 'origin="upper"',
30 | ha="center", va="center", color="black", size="large")
31 | ax.text(5.0, -0.5, "extent=[0,10,0,5]",
32 | ha="center", va="center", color="black", size="large")
33 |
34 | ax = axs[1, 0]
35 | ax.imshow(Z, extent=[0, 10, 0, 5], interpolation="nearest", origin="lower")
36 | ax.set_xlim(-1, 11), ax.set_xticks([0, 10])
37 | ax.set_ylim(-1, 6), ax.set_yticks([0, 5])
38 | ax.text(1, 0.5, "(0,0)", ha="center", va="center", color="white", size="large")
39 | ax.text(9, 4.5, "(4,4)", ha="center", va="center", color="black", size="large")
40 |
41 | ax.text(5.0, 5.5, 'origin="lower"',
42 | ha="center", va="center", color="black", size="large")
43 | ax.text(5.0, -0.5, "extent=[0,10,0,5]",
44 | ha="center", va="center", color="black", size="large")
45 |
46 | ax = axs[1, 1]
47 | ax.imshow(Z, extent=[10, 0, 0, 5], interpolation="nearest", origin="lower")
48 | ax.set_xlim(-1, 11), ax.set_xticks([0, 10])
49 | ax.set_ylim(-1, 6), ax.set_yticks([])
50 | ax.text(9, 0.5, "(0,0)", ha="center", va="center", color="white", size="large")
51 | ax.text(1, 4.5, "(4,4)", ha="center", va="center", color="black", size="large")
52 | ax.text(5.0, 5.5, 'origin="lower"',
53 | ha="center", va="center", color="black", size="large")
54 | ax.text(5.0, -0.5, "extent=[10,0,0,5]",
55 | ha="center", va="center", color="black", size="large")
56 |
57 | ax = axs[0, 1]
58 | ax.imshow(Z, extent=[10, 0, 0, 5], interpolation="nearest", origin="upper")
59 | ax.set_xlim(-1, 11), ax.set_xticks([])
60 | ax.set_ylim(-1, 6), ax.set_yticks([])
61 | ax.text(9, 4.5, "(0,0)", ha="center", va="center", color="white", size="large")
62 | ax.text(1, 0.5, "(4,4)", ha="center", va="center", color="black", size="large")
63 | ax.text(5.0, 5.5, 'origin="upper"',
64 | ha="center", va="center", color="black", size="large")
65 | ax.text(5.0, -0.5, "extent=[10,0,0,5]",
66 | ha="center", va="center", color="black", size="large")
67 |
68 | fig.savefig(ROOT_DIR / "figures/extents.pdf", dpi=600)
69 |
--------------------------------------------------------------------------------
/scripts/fonts.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import matplotlib.pyplot as plt
8 |
9 |
10 | ROOT_DIR = pathlib.Path(__file__).parent.parent
11 |
12 | fig = plt.figure(figsize=(4.25, 3.8))
13 | ax = fig.add_axes([0, 0, 1, 1], frameon=False, xticks=[], yticks=[],
14 | xlim=[0, 40], ylim=[0, 38])
15 |
16 | y = 1
17 |
18 | # -----------------------------------------------------------------------------
19 | variants = {
20 | "normal" : "../fonts/eb-garamond/EBGaramond08-Regular.otf",
21 | "small-caps" : "../fonts/eb-garamond/EBGaramondSC08-Regular.otf"
22 | }
23 |
24 | text = "The quick brown fox jumps over the lazy dog"
25 | for i, (variant, file) in enumerate(variants.items()):
26 | ax.text(1, y, text, size=9, va="center", font=pathlib.Path(file).resolve())
27 |
28 | ax.text(39, y, variant,
29 | color="0.25", va="center", ha="right",
30 | size="small", family="Source Code Pro", weight=400)
31 | y += 1.65
32 | y += 1
33 |
34 | # -----------------------------------------------------------------------------
35 | styles = ["normal", "italic"]
36 |
37 | text = "The quick brown fox jumps over the lazy dog"
38 | for i, style in enumerate(styles):
39 | ax.text(1, y, text, size=9, va="center", style=style,
40 | family="Source Sans Pro")
41 |
42 | ax.text(39, y, style,
43 | color="0.25", va="center", ha="right",
44 | size="small", family="Source Code Pro", weight=400)
45 | y += 1.65
46 | y += 1
47 |
48 |
49 | # -----------------------------------------------------------------------------
50 | families = {
51 | "Pacifico" : "cursive",
52 | "Source Sans Pro" : "sans",
53 | "Source Serif Pro": "serif",
54 | "Source Code Pro" : "monospace" }
55 |
56 | text = "The quick brown fox jumps over the lazy dog"
57 | for i, (family, label) in enumerate(families.items()):
58 | ax.text(1, y, text,
59 | va="center", size=9, family=family, weight="regular")
60 |
61 | ax.text(39, y, label,
62 | color="0.25", va="center", ha="right",
63 | size="small", family="Source Code Pro", weight=400)
64 | y += 1.65
65 | y += 1
66 |
67 |
68 | # -----------------------------------------------------------------------------
69 | weights = {
70 | 'ultralight' : 100,
71 | 'light' : 200,
72 | 'normal' : 400, 'regular' : 400, 'book' : 400,
73 | 'medium' : 500, 'roman' : 500,
74 | 'semibold' : 600, 'demibold' : 600, 'demi' : 600,
75 | 'bold' : 700,
76 | 'heavy' : 800, 'extra bold' : 800,
77 | 'black' : 900 }
78 |
79 | text = "The quick brown fox jumps over the lazy dog"
80 | for i, weight in enumerate(["ultralight", "normal", "semibold", "bold", "black"]):
81 | ax.text(1, y, text, size=9,
82 | va="center", family="Source Sans Pro", weight=weight)
83 |
84 | ax.text(39, y, f"{weight} ({weights[weight]:d})",
85 | color="0.25", va="center", ha="right",
86 | size="small", family="Source Code Pro", weight=400)
87 | y += 1.65
88 | y += 1
89 |
90 | # -----------------------------------------------------------------------------
91 | sizes = { "xx-small" : 0.579,
92 | "x-small" : 0.694,
93 | "small" : 0.833,
94 | "medium" : 1.0,
95 | "large" : 1.200,
96 | "x-large" : 1.440,
97 | "xx-large" : 1.728 }
98 |
99 | text = "The quick brown fox"
100 | for i, (size, scaling) in enumerate(sizes.items()):
101 | ax.text(1, y, text, size=size,
102 | ha="left", va="center", family="Source Sans Pro", weight="light")
103 |
104 | ax.text(39, y, f"{size} ({scaling:.2f})",
105 | color="0.25", va="center", ha="right",
106 | size="small", family="Source Code Pro", weight=400)
107 | y += 1.65* max(sizes[size], sizes["small"])
108 |
109 |
110 | fig.savefig(ROOT_DIR / "figures/fonts.pdf")
111 | # plt.show()
112 |
--------------------------------------------------------------------------------
/scripts/interpolations.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import matplotlib as mpl
4 | import matplotlib.pyplot as plt
5 | import numpy as np
6 |
7 |
8 | ROOT_DIR = pathlib.Path(__file__).parent.parent
9 |
10 | mpl.style.use([
11 | ROOT_DIR / 'styles/base.mplstyle',
12 | ROOT_DIR / 'styles/plotlet-grid.mplstyle',
13 | ])
14 |
15 | methods = [None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16',
16 | 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric',
17 | 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos']
18 |
19 | np.random.seed(1)
20 | Z = np.random.uniform(0, 1, (3, 3))
21 |
22 |
23 | fig, axs = plt.subplots(nrows=6, ncols=3, figsize=(5.7/2.54, 5.7/2.54*2),
24 | # fig, axs = plt.subplots(nrows=6, ncols=3, figsize=(4.5,9),
25 | subplot_kw={'xticks': [], 'yticks': []})
26 | for ax, interp_method in zip(axs.flat, methods):
27 | ax.imshow(Z, interpolation=interp_method, cmap='viridis',
28 | extent=[0, 1, 0, 1], rasterized=True)
29 | ax.text(0.5, 0.1, str(interp_method), weight="bold", color="white", size=6,
30 | ha="center", va="center")
31 |
32 | fig.savefig(ROOT_DIR / "figures/interpolations.pdf", dpi=600)
33 | # plt.show()
34 |
--------------------------------------------------------------------------------
/scripts/layouts.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 | from mpl_toolkits.axes_grid1 import make_axes_locatable
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 | fig = plt.figure(figsize=(0.4, 0.4))
16 | margin = 0.01
17 | fig.subplots_adjust(left=margin, right=1-margin, top=1-margin, bottom=margin)
18 | mpl.rc('axes', linewidth=.5)
19 |
20 | # Subplots
21 | # -----------------------------------------------------------------------------
22 | nrows, ncols = 3, 3
23 | for i in range(nrows*ncols):
24 | ax = plt.subplot(ncols, nrows, i+1)
25 | ax.set_xticks([]), ax.set_yticks([])
26 | fig.savefig(ROOT_DIR / "figures/layout-subplot.pdf")
27 | fig.clear()
28 |
29 | # Subplots (colored)
30 | # -----------------------------------------------------------------------------
31 | nrows, ncols = 3, 3
32 | for i in range(nrows*ncols):
33 | ax = plt.subplot(ncols, nrows, i+1)
34 | ax.set_xticks([]), ax.set_yticks([])
35 | if i == 0: ax.set_facecolor("#ddddff")
36 | if i == 8: ax.set_facecolor("#ffdddd")
37 | fig.savefig(ROOT_DIR / "figures/layout-subplot-color.pdf")
38 | fig.clear()
39 |
40 | # Spines
41 | # -----------------------------------------------------------------------------
42 | ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[])
43 | ax.spines["top"].set_color("None")
44 | ax.spines["right"].set_color("None")
45 | fig.savefig(ROOT_DIR / "figures/layout-spines.pdf")
46 | fig.clear()
47 |
48 |
49 | # Gridspec
50 | # -----------------------------------------------------------------------------
51 | gs = fig.add_gridspec(3, 3)
52 | ax1 = fig.add_subplot(gs[0, :], xticks=[], yticks=[])
53 | ax2 = fig.add_subplot(gs[1, :-1], xticks=[], yticks=[])
54 | ax3 = fig.add_subplot(gs[1:, -1], xticks=[], yticks=[])
55 | ax4 = fig.add_subplot(gs[-1, 0], xticks=[], yticks=[])
56 | ax5 = fig.add_subplot(gs[-1, -2], xticks=[], yticks=[])
57 | fig.savefig(ROOT_DIR / "figures/layout-gridspec.pdf")
58 | fig.clear()
59 |
60 | # Gridspec (colored)
61 | # -----------------------------------------------------------------------------
62 | gs = fig.add_gridspec(3, 3)
63 | ax1 = fig.add_subplot(gs[0, :], xticks=[], yticks=[])
64 | ax1.set_facecolor("#ddddff")
65 | ax2 = fig.add_subplot(gs[1, :-1], xticks=[], yticks=[])
66 | ax3 = fig.add_subplot(gs[1:, -1], xticks=[], yticks=[])
67 | ax4 = fig.add_subplot(gs[-1, 0], xticks=[], yticks=[])
68 | ax5 = fig.add_subplot(gs[-1, -2], xticks=[], yticks=[])
69 | fig.savefig(ROOT_DIR / "figures/layout-gridspec-color.pdf")
70 | fig.clear()
71 |
72 | # Inset axes
73 | # -----------------------------------------------------------------------------
74 | mpl.rc('axes', linewidth=.5)
75 | margin = 0.0125
76 | ax1 = fig.add_axes([margin, margin, 1-2*margin, 1-2*margin], xticks=[], yticks=[])
77 | ax2 = ax1.inset_axes([0.5, 0.5, 0.4, 0.4], xticks=[], yticks=[])
78 | fig.savefig(ROOT_DIR / "figures/layout-inset.pdf")
79 | fig.clear()
80 |
81 |
82 | # Axes divider
83 | # -----------------------------------------------------------------------------
84 | margin = 0.0125
85 | ax = fig.add_axes([margin, margin, 1-2*margin, 1-2*margin], xticks=[], yticks=[])
86 | divider = make_axes_locatable(ax)
87 | cax = divider.new_horizontal(size="10%", pad=0.025)
88 | fig.add_axes(cax)
89 | cax.set_xticks([]), cax.set_yticks([])
90 | fig.savefig(ROOT_DIR / "figures/layout-divider.pdf")
91 |
--------------------------------------------------------------------------------
/scripts/legend.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 | mpl.style.use([
15 | ROOT_DIR / 'styles/base.mplstyle',
16 | ])
17 | mpl.rc('font', size=6)
18 | mpl.rc('lines', markersize=4)
19 |
20 |
21 | subplots_kw = dict(
22 | figsize=(5.7/2.54, 5.7/2.54),
23 | subplot_kw=dict(
24 | aspect=1, frameon=True,
25 | xlim=(0, 1), ylim=(0, 1),
26 | xticks=[], yticks=[],
27 | ),
28 | )
29 |
30 | (fig, ax) = plt.subplots(**subplots_kw)
31 |
32 |
33 | def text(x, y, _text):
34 | color= "C1"
35 | if not 0 < x < 1 or not 0 < y < 1: color = "C0"
36 | size = 0.15
37 | ax.text(x, y, _text, color="white", # bbox={"color": "C1"},
38 | size="xx-large", weight="bold", ha="center", va="center")
39 | rect = plt.Rectangle((x-size/2, y-size/2), size, size, facecolor=color,
40 | zorder=-10, clip_on=False)
41 | ax.add_patch(rect)
42 |
43 |
44 | def point(x, y):
45 | ax.scatter([x], [y], facecolor="C0", edgecolor="white",
46 | zorder=10, clip_on=False)
47 |
48 |
49 | d = .1
50 | e = .15/2
51 |
52 | text( d, d, "3"), text( 0.5, d, "8"), text(1-d, d, "4")
53 | text( d, 0.5, "6"), text( 0.5, 0.5, "10"), text(1-d, 0.5, "7")
54 | text( d, 1-d, "2"), text( 0.5, 1-d, "9"), text(1-d, 1-d, "1")
55 |
56 | text( -d, 1-d, "A"), text( -d, 0.5, "B"), text( -d, d, "C")
57 | point(-d+e, 1-d+e), point(-d+e, 0.5), point(-d+e, d-e),
58 |
59 | text( d, -d, "D"), text(0.5, -d, "E"), text( 1-d, -d, "F")
60 | point(d-e, -d+e), point(0.5, -d+e), point(1-d+e, -d+e),
61 |
62 | text(1+d, d, "G"), text(1+d, 0.5, "H"), text( 1+d, 1-d, "I")
63 | point(1+d-e, d-e), point(1+d-e, .5), point(1+d-e, 1-d+e),
64 |
65 | text(1-d, 1+d, "J"), text(0.5, 1+d, "K"), text( d, 1+d, "L")
66 | point(1-d+e, 1+d-e), point(0.5, 1+d-e), point(d-e, 1+d-e),
67 |
68 | fig.savefig(ROOT_DIR / "figures/legend-placement.pdf")
69 |
--------------------------------------------------------------------------------
/scripts/linestyles.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 |
10 |
11 | ROOT_DIR = pathlib.Path(__file__).parent.parent
12 |
13 | fig = plt.figure(figsize=(4.25, 2*.55))
14 | ax = fig.add_axes([0, 0, 1, 1], xlim=[0.75, 10.25], ylim=[0.5, 2.5], frameon=False,
15 | xticks=[], yticks=[])
16 | y = 2
17 |
18 |
19 | def split(n_segment):
20 | width = 9
21 | segment_width = 0.75*(width/n_segment)
22 | segment_pad = (width - n_segment*segment_width)/(n_segment-1)
23 | X0 = 1+np.arange(n_segment)*(segment_width+segment_pad)
24 | X1 = X0 + segment_width
25 | return X0, X1
26 |
27 |
28 | # Line style
29 | # ----------------------------------------------------------------------------
30 | X0, X1 = split(5)
31 | styles = "-", ":", "--", "-.", (0, (0.01, 2))
32 |
33 | for x0, x1, style in zip(X0, X1, styles):
34 | ax.plot([x0, x1], [y, y], color="C1", linestyle=style,
35 | solid_capstyle="round", dash_capstyle="round", linewidth=3)
36 | if isinstance(style, str): text = '"%s"' % style
37 | else: text = '%s' % str(style)
38 | text = text.replace(' ', '')
39 | ax.text((x0+x1)/2, y-0.2, text,
40 | size=8, ha="center", va="top", family="Source Code Pro")
41 | ax.text(X0[0]-0.25, y+0.2, "linestyle or ls", family="Source Code Pro",
42 | size=14, ha="left", va="baseline")
43 | y -= 1
44 |
45 | # Dash capstyle
46 | # ----------------------------------------------------------------------------
47 | X0, X1 = split(3)
48 | styles = "butt", "round", "projecting"
49 | for x0, x1, style in zip(X0, X1, styles):
50 | ax.plot([x0, x1], [y, y], color="C1", dash_capstyle="projecting",
51 | linewidth=7, linestyle="--", alpha=.25)
52 | ax.plot([x0, x1], [y, y], color="C1", linewidth=7,
53 | linestyle="--", dash_capstyle=style)
54 | ax.text((x0+x1)/2, y-0.2, '"%s"' % style, family="Source Code Pro",
55 | size=10, ha="center", va="top")
56 | ax.text(X0[0]-0.25, y+0.2, "capstyle or dash_capstyle", family="Source Code Pro",
57 | size=14, ha="left", va="baseline")
58 |
59 |
60 | fig.savefig(ROOT_DIR / "figures/linestyles.pdf", dpi=200)
61 | # plt.show()
62 |
--------------------------------------------------------------------------------
/scripts/markers.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 |
10 |
11 | ROOT_DIR = pathlib.Path(__file__).parent.parent
12 |
13 | # Markers
14 | # -----------------------------------------------------------------------------
15 | fig = plt.figure(figsize=(3.5, 1.5))
16 | ax = fig.add_axes([0, 0, 1, 1], frameon=False,
17 | xlim=[0.5, 10.5], ylim=[0.0, 4.35], xticks=[], yticks=[])
18 | X = np.linspace(1, 10, 12)
19 | Y = np.arange(1, 4)
20 | X, Y = np.meshgrid(X, Y)
21 | X , Y = X.ravel(), Y.ravel()
22 |
23 | plt.scatter(X, 1+Y, s=256, marker="s", fc="C1", ec="none", alpha=.25)
24 | markers = [
25 | "$♠$", "$♣$", "$♥$", "$♦$", "$→$", "$←$", "$↑$", "$↓$", "$◐$", "$◑$", "$◒$", "$◓$",
26 | "1", "2", "3", "4", "+", "x", "|", "_", 4, 5, 6, 7,
27 | ".", "o", "s", "P", "X", "*", "p", "D", "<", ">", "^", "v", ]
28 | for x, y, marker in zip(X, Y, markers):
29 | if y == 3: fc = "white"
30 | else: fc = "C1"
31 | plt.scatter(x, 1+y, s=100, marker=marker, fc=fc, ec="C1", lw=0.5)
32 |
33 | if y == 1: marker = "\$%s\$" % marker
34 | if isinstance(marker, str): text = "'%s'" % marker
35 | else: text = '%s' % marker
36 | plt.text(x, 1+y-0.4, text,
37 | size="x-small", ha="center", va="top", family="Monospace")
38 |
39 |
40 | # Spacing
41 | n_segment = 4
42 | width = 9
43 | segment_width = 0.75*(width/n_segment)
44 | segment_pad = (width - n_segment*segment_width)/(n_segment-1)
45 | X0 = 1+np.arange(n_segment)*(segment_width+segment_pad)
46 | marks = [ 10, [0, -1], (25, 5), [0, 25, -1] ]
47 | y = .6
48 | for x0, mark in zip(X0, marks):
49 | X = np.linspace(x0, x0+segment_width, 50)
50 | Y = y*np.ones(len(X))
51 | ax.plot(X, Y, linewidth=1, color="black",
52 | marker=".", mfc="white", mec="black", mew="1", markevery=mark)
53 | ax.text((X[0]+X[-1])/2, y-0.2, '%s' % str(mark),
54 | size="x-small", ha="center", va="top")
55 |
56 | plt.text(.7, 1, "markevery",
57 | size="medium", ha="left", va="center", family="Source Code Pro")
58 | fig.savefig(ROOT_DIR / "figures/markers.pdf", dpi=600)
59 |
--------------------------------------------------------------------------------
/scripts/performance-tips.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import time
6 | import numpy as np
7 | import matplotlib.pyplot as plt
8 |
9 |
10 | fig, ax = plt.subplots()
11 |
12 | n = 10_000_000
13 | np.random.seed(1)
14 | X = np.random.uniform(0, 1, n)
15 | Y = np.random.uniform(0, 1, n)
16 |
17 | start = time.perf_counter()
18 | ax.plot(X, Y, marker="o", ls="")
19 | end = time.perf_counter()
20 | print(f"Time: {end-start}s")
21 |
22 | ax.clear()
23 |
24 | start = time.perf_counter()
25 | ax.scatter(X, Y)
26 | end = time.perf_counter()
27 | print(f"Time: {end-start}s")
28 |
29 | ax.clear()
30 |
31 | n = 1_000
32 | np.random.seed(1)
33 | X = []
34 | for i in range(n):
35 | X.append(np.random.uniform(0, 1, 10))
36 | # np.random.uniform(0,1,n)
37 | # Y = np.random.uniform(0,1,n)
38 |
39 | start = time.perf_counter()
40 | # for i in range(0,n,2): plt.plot(X[i:i+2], Y[i:i+2])
41 | for i in range(n): plt.plot(X[i])
42 | end = time.perf_counter()
43 | print(f"Time: {end-start}s")
44 |
45 | ax.clear()
46 |
47 | start = time.perf_counter()
48 | ax.plot(sum([list(x)+[None] for x in X], []))
49 | # X0,Y0 = X[0::2], Y[0::2]
50 | # X1,Y1 = X[1::2], Y[1::2]
51 | # S = [None]*len(X)
52 | # X = [v for t in zip(X0,X1,S) for v in t]
53 | # Y = [v for t in zip(Y0,Y1,S) for v in t]
54 | # plt.plot(X,Y)
55 | end = time.perf_counter()
56 | print(f"Time: {end-start}s")
57 |
--------------------------------------------------------------------------------
/scripts/plot-variations.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | # Scripts to generate all the basic plots
8 | import numpy as np
9 | import matplotlib as mpl
10 | import matplotlib.pyplot as plt
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 | mpl.style.use([
16 | ROOT_DIR / 'styles/base.mplstyle',
17 | ROOT_DIR / 'styles/plotlet.mplstyle',
18 | ])
19 | mpl.rc('axes', titlepad=1)
20 |
21 |
22 | subplot_kw = dict(
23 | xlim=(0, 8), xticks=np.arange(1, 8),
24 | ylim=(0, 8), yticks=np.arange(1, 8),
25 | )
26 |
27 | # Basic line plot (color)
28 | # -----------------------------------------------------------------------------
29 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
30 | X = np.linspace(0, 10, 100)
31 | Y = 4+2*np.sin(2*X)
32 | ax.plot(X, Y, color="black", linewidth=0.75)
33 | ax.grid()
34 | fig.savefig(ROOT_DIR / "figures/plot-color.pdf")
35 |
36 | # Basic line plot (linestyle)
37 | # -----------------------------------------------------------------------------
38 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
39 | X = np.linspace(0, 10, 100)
40 | Y = 4+2*np.sin(2*X)
41 | ax.plot(X, Y, color="C1", linewidth=0.75, linestyle="--")
42 | ax.grid()
43 | fig.savefig(ROOT_DIR / "figures/plot-linestyle.pdf")
44 |
45 | # Basic line plot (linewidth)
46 | # -----------------------------------------------------------------------------
47 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
48 | X = np.linspace(0, 10, 100)
49 | Y = 4+2*np.sin(2*X)
50 | ax.plot(X, Y, color="C1", linewidth=1.5)
51 | ax.grid()
52 | fig.savefig("../figures/plot-linewidth.pdf")
53 | fig.savefig(ROOT_DIR / "figures/plot-linewidth.pdf")
54 |
55 | # Basic line plot (marker)
56 | # -----------------------------------------------------------------------------
57 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
58 | X = np.linspace(0, 10, 100)
59 | Y = 4+2*np.sin(2*X)
60 | ax.plot(X, Y, color="C1", linewidth=0.75, marker="o", markevery=5, markersize=2)
61 | ax.grid()
62 | fig.savefig(ROOT_DIR / "figures/plot-marker.pdf")
63 |
64 | # Basic line plot (multi)
65 | # -----------------------------------------------------------------------------
66 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
67 | X = np.linspace(0, 10, 100)
68 | Y1 = 4+2*np.sin(2*X)
69 | Y2 = 4+2*np.cos(2*X)
70 | ax.plot(X, Y1, color="C1", linewidth=0.75)
71 | ax.plot(X, Y2, color="C0", linewidth=0.75)
72 | ax.grid()
73 | fig.savefig(ROOT_DIR / "figures/plot-multi.pdf")
74 |
75 | # Basic line plot (vsplit)
76 | # -----------------------------------------------------------------------------
77 | (fig, [ax2, ax1]) = plt.subplots(nrows=2, gridspec_kw=dict(hspace=0.2), subplot_kw=subplot_kw)
78 |
79 | X = np.linspace(0, 10, 100)
80 | Y1 = 2+1*np.sin(2*X)
81 | ax1.plot(X, Y1, color="C1", linewidth=0.75)
82 | ax1.set_ylim(0, 4), ax1.set_yticks(np.arange(1, 4))
83 | ax1.grid()
84 | ax1.tick_params(axis=u'both', which=u'both', length=0)
85 |
86 | Y2 = 2+1*np.cos(2*X)
87 | ax2.plot(X, Y2, color="C0", linewidth=0.75)
88 | ax2.set_ylim(0, 4), ax2.set_yticks(np.arange(1, 4))
89 | ax2.grid()
90 | ax2.tick_params(axis=u'both', which=u'both', length=0)
91 | fig.savefig(ROOT_DIR / "figures/plot-vsplit.pdf")
92 |
93 | # Basic line plot (hsplit)
94 | # -----------------------------------------------------------------------------
95 | (fig, [ax1, ax2]) = plt.subplots(ncols=2, gridspec_kw=dict(wspace=0.2), subplot_kw=subplot_kw)
96 |
97 | X = np.linspace(0, 10, 100)
98 | Y1 = 2+1*np.sin(2*X)
99 | ax1.plot(Y1, X, color="C1", linewidth=0.75)
100 | ax1.set_xlim(0, 4), ax1.set_xticks(np.arange(1, 4))
101 | ax1.grid()
102 | ax1.tick_params(axis=u'both', which=u'both', length=0)
103 |
104 | Y2 = 2+1*np.cos(2*X)
105 | ax2.plot(Y2, X, color="C0", linewidth=0.75)
106 | ax2.set_xlim(0, 4), ax2.set_xticks(np.arange(1, 4))
107 | ax2.grid()
108 | ax2.tick_params(axis=u'both', which=u'both', length=0)
109 | fig.savefig(ROOT_DIR / "figures/plot-hsplit.pdf")
110 |
111 | # Basic line plot (title)
112 | # -----------------------------------------------------------------------------
113 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
114 | X = np.linspace(0, 10, 100)
115 | Y = 3+2*np.sin(2*X)
116 | ax.plot(X, Y, color="C1", linewidth=0.75)
117 | ax.set_ylim(0, 6), ax.set_yticks(np.arange(1, 6))
118 | ax.grid()
119 | ax.set_title("A Sine wave", size=4, weight="bold")
120 | fig.savefig(ROOT_DIR / "figures/plot-title.pdf")
121 |
122 | # Basic line plot (xlabel)
123 | # -----------------------------------------------------------------------------
124 | (fig, ax) = plt.subplots(subplot_kw=subplot_kw)
125 | X = np.linspace(0, 10, 100)
126 | Y = 3+2*np.sin(2*X)
127 | ax.plot(X, Y, color="C1", linewidth=0.75), ax.set_xticklabels([])
128 | ax.set_ylim(0, 6), ax.set_yticks(np.arange(1, 6)), ax.set_yticklabels([])
129 | ax.grid()
130 | ax.text(4, -1, "Time", transform=ax.transData, clip_on=False,
131 | size=3.5, ha="center", va="center")
132 | fig.savefig(ROOT_DIR / "figures/plot-xlabel.pdf")
133 |
--------------------------------------------------------------------------------
/scripts/projections.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import cartopy
9 | import matplotlib as mpl
10 | import matplotlib.pyplot as plt
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 | mpl.style.use([
16 | ROOT_DIR / 'styles/base.mplstyle',
17 | ROOT_DIR / 'styles/plotlet.mplstyle',
18 | ])
19 |
20 | CARTOPY_SOURCE_TEMPLATE = 'https://naturalearth.s3.amazonaws.com/{resolution}_{category}/ne_{resolution}_{name}.zip'
21 |
22 |
23 | # Configures cartopy to download NaturalEarth shapefiles from S3 instead of naciscdn
24 | # Taken from https://github.com/SciTools/cartopy/issues/1325#issuecomment-904343657
25 | target_path_template = cartopy.io.shapereader.NEShpDownloader.default_downloader().target_path_template
26 | downloader = cartopy.io.shapereader.NEShpDownloader(url_template=CARTOPY_SOURCE_TEMPLATE,
27 | target_path_template=target_path_template)
28 | cartopy.config['downloaders'][('shapefiles', 'natural_earth')] = downloader
29 |
30 |
31 | # Polar plot
32 | # -----------------------------------------------------------------------------
33 | (fig, ax) = plt.subplots(subplot_kw={'projection': 'polar'})
34 | T = np.linspace(0, 3*2*np.pi, 500)
35 | R = np.linspace(0, 2, len(T))
36 | ax.plot(T, R, color="C1")
37 | ax.set_xticks(np.linspace(0, 2*np.pi, 2*8))
38 | ax.set_xticklabels([])
39 | ax.set_yticks(np.linspace(0, 2, 8))
40 | ax.set_yticklabels([])
41 | ax.set_ylim(0, 2)
42 | ax.grid(linewidth=0.2)
43 | fig.savefig(ROOT_DIR / "figures/projection-polar.pdf")
44 | fig.clear()
45 |
46 | # 3D plot
47 | # -----------------------------------------------------------------------------
48 | (fig, ax) = plt.subplots(subplot_kw={'projection': '3d'})
49 | r = np.linspace(0, 1.25, 50)
50 | p = np.linspace(0, 2*np.pi, 50)
51 | R, P = np.meshgrid(r, p)
52 | Z = ((R**2 - 1)**2)
53 | X, Y = R*np.cos(P), R*np.sin(P)
54 |
55 | # Plot the surface.
56 | ax.plot_surface(X, Y, Z, color="C1", antialiased=False)
57 | ax.set_zlim(0, 1)
58 | ax.set_xticks([])
59 | ax.set_yticks([])
60 | ax.set_zticks([])
61 | fig.savefig(ROOT_DIR / "figures/projection-3d.pdf")
62 | fig.clear()
63 |
64 | # Cartopy plot
65 | # -----------------------------------------------------------------------------
66 | fig = plt.figure()
67 | ax = fig.add_subplot(frameon=False,
68 | projection=cartopy.crs.Orthographic())
69 | ax.add_feature(cartopy.feature.LAND, zorder=0,
70 | facecolor="C1", edgecolor="0.0", linewidth=0)
71 | fig.savefig(ROOT_DIR / "figures/projection-cartopy.pdf")
72 |
--------------------------------------------------------------------------------
/scripts/scales.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import numpy as np
4 | import matplotlib.pyplot as plt
5 |
6 |
7 | ROOT_DIR = pathlib.Path(__file__).parent.parent
8 |
9 | fig = plt.figure(figsize=(0.4, 2/3*0.4))
10 | ax = fig.add_axes([0, 0, 1, 1], frameon=False)
11 | ax.tick_params(axis='both', which='both', length=0)
12 | ax.set_xlim(-2, 2)
13 | X = np.linspace(-2, +2, 1001)
14 | Y = np.sin(X*2.5*2*np.pi)
15 |
16 |
17 | # Linear scale
18 | # -----------------------------------------------------------------------------
19 | ax.set_xlim(X.min(), X.max())
20 | ax.set_xscale("linear")
21 | ax.plot(X, Y, color="C1", linewidth=0.75)
22 | ax.set_ylim(-2.5, 1.5)
23 | ax.text(0, 0.12, "-∞", ha="left", va="bottom", size=3, transform=ax.transAxes)
24 | ax.text(0, 0.15, "⇤", ha="left", va="top", size=4, transform=ax.transAxes)
25 | ax.text(1, 0.12, "+∞", ha="right", va="bottom", size=3, transform=ax.transAxes)
26 | ax.text(1, 0.15, "⇥", ha="right", va="top", size=4, transform=ax.transAxes)
27 | fig.savefig(ROOT_DIR / "figures/scale-linear.pdf")
28 | ax.clear()
29 |
30 | # Log scale
31 | # -----------------------------------------------------------------------------
32 | ax.set_xscale("log", base=10)
33 | ax.plot(X, Y, color="C1", linewidth=0.75)
34 | ax.set_ylim(-2.5, 1.5)
35 | ax.text(0, 0.12, "0", ha="left", va="bottom", size=3, transform=ax.transAxes)
36 | ax.text(0, 0.15, "⇤", ha="left", va="top", size=4, transform=ax.transAxes)
37 | ax.text(1, 0.12, "+∞", ha="right", va="bottom", size=3, transform=ax.transAxes)
38 | ax.text(1, 0.15, "⇥", ha="right", va="top", size=4, transform=ax.transAxes)
39 | fig.savefig(ROOT_DIR / "figures/scale-log.pdf")
40 | ax.clear()
41 |
42 | # Symlog scale
43 | # -----------------------------------------------------------------------------
44 | ax.set_xscale("symlog", base=10, linthresh=1)
45 | ax.plot(X, Y, color="C1", linewidth=0.75)
46 | ax.set_ylim(-2.5, 1.5)
47 | ax.text(0, 0.12, "-∞", ha="left", va="bottom", size=3, transform=ax.transAxes)
48 | ax.text(0, 0.15, "⇤", ha="left", va="top", size=4, transform=ax.transAxes)
49 | ax.text(1, 0.12, "+∞", ha="right", va="bottom", size=3, transform=ax.transAxes)
50 | ax.text(1, 0.15, "⇥", ha="right", va="top", size=4, transform=ax.transAxes)
51 | fig.savefig(ROOT_DIR / "figures/scale-symlog.pdf")
52 | ax.clear()
53 |
54 | # Symlog scale
55 | # -----------------------------------------------------------------------------
56 | ax.set_xscale("logit")
57 | ax.plot(X, Y, color="C1", linewidth=0.75)
58 | ax.set_ylim(-2.5, 1.5)
59 | ax.text(0, 0.12, "0", ha="left", va="bottom", size=3, transform=ax.transAxes)
60 | ax.text(0, 0.15, "⇤", ha="left", va="top", size=4, transform=ax.transAxes)
61 | ax.text(1, 0.12, "1", ha="right", va="bottom", size=3, transform=ax.transAxes)
62 | ax.text(1, 0.15, "⇥", ha="right", va="top", size=4, transform=ax.transAxes)
63 | fig.savefig(ROOT_DIR / "figures/scale-logit.pdf")
64 | ax.clear()
65 |
--------------------------------------------------------------------------------
/scripts/sine.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Author: Nicolas P. Rougier
3 | # License: BSD
4 | # ----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 | mpl.style.use([
15 | ROOT_DIR / 'styles/base.mplstyle',
16 | ROOT_DIR / 'styles/sine-plot.mplstyle',
17 | ])
18 |
19 | X = np.linspace(0, 10*np.pi, 1000)
20 | Y = np.sin(X)
21 |
22 |
23 | fig, ax = plt.subplots(figsize=(5.7/2.54, 1.2/2.54))
24 | ax.set_yticks(np.linspace(-1, 1, 5))
25 | ax.plot(X, Y, color="C1")
26 | fig.savefig(ROOT_DIR / "figures/sine.pdf")
27 |
28 |
29 | X = np.linspace(0.1, 10*np.pi, 1000)
30 | Y = np.sin(X)
31 |
32 |
33 | fig, ax = plt.subplots(figsize=(5.7/2.54, 1.0/2.54))
34 | ax.plot(X, Y, "C1o:", markevery=50, mec="1.0")
35 | ax.set_ylim(-1.5, 1.5)
36 | fig.savefig(ROOT_DIR / "figures/sine-marker.pdf")
37 |
38 |
39 | fig, ax = plt.subplots(figsize=(5.7/2.54, 1.0/2.54))
40 | ax.set_xscale("log")
41 | ax.plot(X, Y, "C1o-", markevery=50, mec="1.0")
42 | ax.set_ylim(-1.5, 1.5)
43 | fig.savefig(ROOT_DIR / "figures/sine-logscale.pdf")
44 |
45 |
46 | fig, ax = plt.subplots(figsize=(5.7/2.54, 1.0/2.54))
47 | ax.plot(X, Y, "C1")
48 | ax.fill_betweenx([-1.5, 1.5], [0], [2*np.pi], color=".9")
49 | ax.text(0, -1, r" Period $\Phi$", va="top")
50 | ax.set_ylim(-1.5, 1.5)
51 | fig.savefig(ROOT_DIR / "figures/sine-period.pdf")
52 |
53 |
54 | fig, ax = plt.subplots(figsize=(5.7/2.54, 1.0/2.54))
55 | ax.plot(X, np.sin(X), "C0", label="Sine")
56 | ax.plot(X, np.cos(X), "C1", label="Cosine")
57 | ax.legend(bbox_to_anchor=(0.0, .9, 1.02, 0.1),
58 | frameon=False, mode="expand", ncol=2, loc="lower left")
59 | ax.set_title("Sine and Cosine")
60 | ax.set_xticks([]), ax.set_yticks([])
61 | ax.set_ylim(-1.25, 1.25)
62 | fig.savefig(ROOT_DIR / "figures/sine-legend.pdf")
63 |
64 |
65 | fig, ax = plt.subplots(figsize=(5.7/2.54, 1.0/2.54))
66 | X = np.linspace(0, 10*np.pi, 1000)
67 | Y = np.sin(X)
68 | ax.plot(X, Y, "C1o-", markevery=50, mec="1.0")
69 | ax.set_ylim(-1.5, 1.5)
70 | ax.annotate(" ", (X[200], Y[200]), (X[250], -1), ha="center", va="center",
71 | arrowprops=dict(arrowstyle="->", color="C1", linewidth=0.5, patchA=None, shrinkA=4, shrinkB=0.5))
72 | ax.annotate("A", (X[250], Y[250]), (X[250], -1), ha="center", va="center",
73 | arrowprops=dict(arrowstyle="->", color="C1", linewidth=0.5, patchA=None, shrinkA=4, shrinkB=0.5))
74 | ax.annotate(" ", (X[300], Y[300]), (X[250], -1), ha="center", va="center",
75 | arrowprops=dict(arrowstyle="->", color="C1", linewidth=0.5, patchA=None, shrinkA=4, shrinkB=0.5))
76 | fig.savefig(ROOT_DIR / "figures/sine-annotate.pdf")
77 |
--------------------------------------------------------------------------------
/scripts/styles.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 | for style in ['default'] + plt.style.available:
15 | with plt.style.context(style):
16 | fig = plt.figure(figsize=(5, 3), dpi=100)
17 | ax = plt.subplot(1, 1, 1)
18 | X = np.linspace(0, 2*np.pi, 256)
19 | Y = np.cos(X)
20 | ax.plot(X, Y)
21 | plt.title(style, family="Source Serif Pro", size=32)
22 | plt.tight_layout()
23 | fig.savefig(ROOT_DIR / f"figures/style-{style}.pdf")
24 | plt.close(fig)
25 |
--------------------------------------------------------------------------------
/scripts/text-alignments.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 |
10 |
11 | ROOT_DIR = pathlib.Path(__file__).parent.parent
12 |
13 | dpi = 100
14 | fig = plt.figure(figsize=(4.25, 1.5), dpi=dpi)
15 | ax = fig.add_axes([0, 0, 1, 1], frameon=False,
16 | xlim=(0, 4.25), ylim=(0, 1.5), xticks=[], yticks=[])
17 |
18 | fontsize = 48
19 | renderer = fig.canvas.get_renderer()
20 | horizontalalignment = "left"
21 | verticalalignment = "center"
22 | position = (0.25, 1.5/2)
23 | color = "0.25"
24 |
25 | # Compute vertical and horizontal alignment offsets
26 | text = ax.text(0, 0, "Matplotlib", fontsize=fontsize)
27 | yoffset = {}
28 | for alignment in ["top", "center", "baseline", "bottom"]:
29 | text.set_verticalalignment(alignment)
30 | y = text.get_window_extent(renderer).y0/dpi
31 | yoffset[alignment] = y
32 |
33 | xoffset = {}
34 | for alignment in ["left", "center", "right"]:
35 | text.set_horizontalalignment(alignment)
36 | x = text.get_window_extent(renderer).x0/dpi
37 | xoffset[alignment] = x
38 |
39 | # Actual positioning of the text
40 | text.set_horizontalalignment(horizontalalignment)
41 | text.set_verticalalignment(verticalalignment)
42 | text.set_position(position)
43 |
44 |
45 | for name, y in yoffset.items():
46 | y = position[1] - y + yoffset[verticalalignment]
47 | plt.plot([0.1, 3.75], [y, y], linewidth=0.5, color=color)
48 | plt.text(3.75, y, " "+name, color=color,
49 | ha="left", va="center", size="x-small")
50 |
51 | for name, x in xoffset.items():
52 | x = position[0] - x + xoffset[horizontalalignment]
53 | plt.plot([x, x], [0.25, 1.25], linewidth=0.5, color=color)
54 | plt.text(x, 0.24, name, color=color,
55 | ha="center", va="top", size="x-small")
56 |
57 | P = []
58 | for x in xoffset.values():
59 | x = position[0] - x + xoffset[horizontalalignment]
60 | for y in yoffset.values():
61 | y = position[1] - y + yoffset[verticalalignment]
62 | P.append((x, y))
63 | P = np.array(P)
64 |
65 | ax.scatter(P[:, 0], P[:, 1], s=10, zorder=10,
66 | facecolor="white", edgecolor=color, linewidth=0.75)
67 |
68 | epsilon = 0.05
69 | plt.text(P[3, 0]+epsilon, P[3, 1]-epsilon, "(0,0)",
70 | color=color, ha="left", va="top", size="x-small")
71 | plt.text(P[8, 0]-epsilon, P[8, 1]+epsilon, "(1,1)",
72 | color=color, ha="right", va="bottom", size="x-small")
73 |
74 | fig.savefig(ROOT_DIR / "figures/text-alignments.pdf")
75 | # plt.show()
76 |
--------------------------------------------------------------------------------
/scripts/tick-formatters.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Title: Scientific Visualisation - Python & Matplotlib
3 | # Author: Nicolas P. Rougier
4 | # License: BSD
5 | # ----------------------------------------------------------------------------
6 | import pathlib
7 |
8 | import matplotlib.pyplot as plt
9 | import matplotlib.ticker as ticker
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 |
15 | # Setup a plot such that only the bottom spine is shown
16 | def setup(ax):
17 | """Set up Axes with just an x-Axis."""
18 | ax.spines['right'].set_color('none')
19 | ax.spines['left'].set_color('none')
20 | ax.yaxis.set_major_locator(ticker.NullLocator())
21 | ax.spines['top'].set_color('none')
22 | ax.xaxis.set_ticks_position('bottom')
23 | ax.tick_params(which='major', width=1.00, length=5)
24 | ax.tick_params(which='minor', width=0.75, length=2.5, labelsize=10)
25 | ax.set_xlim(0, 5)
26 | ax.set_ylim(0, 1)
27 | ax.patch.set_alpha(0.0)
28 |
29 |
30 | fig = plt.figure(figsize=(8, 5))
31 | fig.patch.set_alpha(0.0)
32 | n = 7
33 |
34 | fontsize = 18
35 | family = "Source Code Pro"
36 |
37 | # Null formatter
38 | ax = fig.add_subplot(n, 1, 1)
39 | setup(ax)
40 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
41 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
42 | ax.xaxis.set_major_formatter(ticker.NullFormatter())
43 | ax.xaxis.set_minor_formatter(ticker.NullFormatter())
44 | ax.text(0.0, 0.1, "ticker.NullFormatter()", family=family,
45 | fontsize=fontsize, transform=ax.transAxes)
46 |
47 | # Fixed formatter
48 | ax = fig.add_subplot(n, 1, 2)
49 | setup(ax)
50 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
51 | ax.xaxis.set_major_locator(ticker.FixedLocator(range(6)))
52 | majors = ["zero", "one", "two", "three", "four", "five"]
53 | ax.xaxis.set_major_formatter(ticker.FixedFormatter(majors))
54 | ax.text(0.0, 0.1, "ticker.FixedFormatter(['zero', 'one', 'two', …])",
55 | family=family, fontsize=fontsize, transform=ax.transAxes)
56 |
57 |
58 | # FuncFormatter can be used as a decorator
59 | @ticker.FuncFormatter
60 | def major_formatter(x, pos):
61 | """Return formatted value with 2 decimal places."""
62 | return "[%.2f]" % x
63 |
64 |
65 | ax = fig.add_subplot(n, 1, 3)
66 | setup(ax)
67 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
68 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
69 | ax.xaxis.set_major_formatter(major_formatter)
70 | ax.text(0.0, 0.1, 'ticker.FuncFormatter(lambda x, pos: "[%.2f]" % x)',
71 | family=family, fontsize=fontsize, transform=ax.transAxes)
72 |
73 |
74 | # FormatStr formatter
75 | ax = fig.add_subplot(n, 1, 4)
76 | setup(ax)
77 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
78 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
79 | ax.xaxis.set_major_formatter(ticker.FormatStrFormatter(">%d<"))
80 | ax.text(0.0, 0.1, "ticker.FormatStrFormatter('>%d<')",
81 | family=family, fontsize=fontsize, transform=ax.transAxes)
82 |
83 | # Scalar formatter
84 | ax = fig.add_subplot(n, 1, 5)
85 | setup(ax)
86 | ax.xaxis.set_major_locator(ticker.AutoLocator())
87 | ax.xaxis.set_minor_locator(ticker.AutoMinorLocator())
88 | ax.xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
89 | ax.text(0.0, 0.1, "ticker.ScalarFormatter()",
90 | family=family, fontsize=fontsize, transform=ax.transAxes)
91 |
92 | # StrMethod formatter
93 | ax = fig.add_subplot(n, 1, 6)
94 | setup(ax)
95 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
96 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
97 | ax.xaxis.set_major_formatter(ticker.StrMethodFormatter("{x}"))
98 | ax.text(0.0, 0.1, "ticker.StrMethodFormatter('{x}')",
99 | family=family, fontsize=fontsize, transform=ax.transAxes)
100 |
101 | # Percent formatter
102 | ax = fig.add_subplot(n, 1, 7)
103 | setup(ax)
104 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
105 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
106 | ax.xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))
107 | ax.text(0.0, 0.1, "ticker.PercentFormatter(xmax=5)",
108 | family=family, fontsize=fontsize, transform=ax.transAxes)
109 |
110 | # Push the top of the top axes outside the figure because we only show the
111 | # bottom spine.
112 | fig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=1.05)
113 |
114 | fig.savefig(ROOT_DIR / "figures/tick-formatters.pdf", transparent=True)
115 | # plt.show()
116 |
--------------------------------------------------------------------------------
/scripts/tick-locators.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Title: Scientific Visualisation - Python & Matplotlib
3 | # Author: Nicolas P. Rougier
4 | # License: BSD
5 | # ----------------------------------------------------------------------------
6 | import pathlib
7 |
8 | import numpy as np
9 | import matplotlib.pyplot as plt
10 | import matplotlib.ticker as ticker
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 |
16 | # Setup a plot such that only the bottom spine is shown
17 | def setup(ax):
18 | ax.spines['right'].set_color('none')
19 | ax.spines['left'].set_color('none')
20 | ax.yaxis.set_major_locator(ticker.NullLocator())
21 | ax.spines['top'].set_color('none')
22 | ax.xaxis.set_ticks_position('bottom')
23 | ax.tick_params(which='major', width=1.00)
24 | ax.tick_params(which='major', length=5)
25 | ax.tick_params(which='minor', width=0.75)
26 | ax.tick_params(which='minor', length=2.5)
27 | ax.set_xlim(0, 5)
28 | ax.set_ylim(0, 1)
29 | ax.patch.set_alpha(0.0)
30 |
31 |
32 | fig = plt.figure(figsize=(8, 5))
33 | fig.patch.set_alpha(0.0)
34 | n = 8
35 |
36 | fontsize = 18
37 | family = "Source Code Pro"
38 |
39 | # Null Locator
40 | ax = plt.subplot(n, 1, 1)
41 | setup(ax)
42 | ax.xaxis.set_major_locator(ticker.NullLocator())
43 | ax.xaxis.set_minor_locator(ticker.NullLocator())
44 | ax.text(0.0, 0.1, "ticker.NullLocator()",
45 | family=family, fontsize=fontsize, transform=ax.transAxes)
46 |
47 | # Multiple Locator
48 | ax = plt.subplot(n, 1, 2)
49 | setup(ax)
50 | ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5))
51 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.1))
52 | ax.text(0.0, 0.1, "ticker.MultipleLocator(0.5)",
53 | family=family, fontsize=fontsize, transform=ax.transAxes)
54 |
55 | # Fixed Locator
56 | ax = plt.subplot(n, 1, 3)
57 | setup(ax)
58 | majors = [0, 1, 5]
59 | ax.xaxis.set_major_locator(ticker.FixedLocator(majors))
60 | minors = np.linspace(0, 1, 11)[1:-1]
61 | ax.xaxis.set_minor_locator(ticker.FixedLocator(minors))
62 | ax.text(0.0, 0.1, "ticker.FixedLocator([0, 1, 5])",
63 | family=family, fontsize=fontsize, transform=ax.transAxes)
64 |
65 | # Linear Locator
66 | ax = plt.subplot(n, 1, 4)
67 | setup(ax)
68 | ax.xaxis.set_major_locator(ticker.LinearLocator(3))
69 | ax.xaxis.set_minor_locator(ticker.LinearLocator(31))
70 | ax.text(0.0, 0.1, "ticker.LinearLocator(numticks=3)",
71 | family=family, fontsize=fontsize, transform=ax.transAxes)
72 |
73 | # Index Locator
74 | ax = plt.subplot(n, 1, 5)
75 | setup(ax)
76 | ax.plot(range(0, 5), [0]*5, color='white')
77 | ax.xaxis.set_major_locator(ticker.IndexLocator(base=.5, offset=.25))
78 | ax.text(0.0, 0.1, "ticker.IndexLocator(base=0.5, offset=0.25)",
79 | family=family, fontsize=fontsize, transform=ax.transAxes)
80 |
81 | # Auto Locator
82 | ax = plt.subplot(n, 1, 6)
83 | setup(ax)
84 | ax.xaxis.set_major_locator(ticker.AutoLocator())
85 | ax.xaxis.set_minor_locator(ticker.AutoMinorLocator())
86 | ax.text(0.0, 0.1, "ticker.AutoLocator()",
87 | family=family, fontsize=fontsize, transform=ax.transAxes)
88 |
89 | # MaxN Locator
90 | ax = plt.subplot(n, 1, 7)
91 | setup(ax)
92 | ax.xaxis.set_major_locator(ticker.MaxNLocator(4))
93 | ax.xaxis.set_minor_locator(ticker.MaxNLocator(40))
94 | ax.text(0.0, 0.1, "ticker.MaxNLocator(n=4)",
95 | family=family, fontsize=fontsize, transform=ax.transAxes)
96 |
97 | # Log Locator
98 | ax = plt.subplot(n, 1, 8)
99 | setup(ax)
100 | ax.set_xlim(10**3, 10**10)
101 | ax.set_xscale('log')
102 | ax.xaxis.set_major_locator(ticker.LogLocator(base=10.0, numticks=15))
103 | ax.text(0.0, 0.1, "ticker.LogLocator(base=10, numticks=15)",
104 | family=family, fontsize=fontsize, transform=ax.transAxes)
105 |
106 | # Push the top of the top axes outside the figure because we only show the
107 | # bottom spine.
108 | plt.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=1.05)
109 |
110 | fig.savefig(ROOT_DIR / "figures/tick-locators.pdf", transparent=True)
111 | # plt.show()
112 |
--------------------------------------------------------------------------------
/scripts/tick-multiple-locator.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Title: Scientific Visualisation - Python & Matplotlib
3 | # Author: Nicolas P. Rougier
4 | # License: BSD
5 | # ----------------------------------------------------------------------------
6 | import pathlib
7 |
8 | import numpy as np
9 | import matplotlib as mpl
10 | import matplotlib.pyplot as plt
11 | import matplotlib.ticker as ticker
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | mpl.style.use([
17 | ROOT_DIR / 'styles/base.mplstyle',
18 | ROOT_DIR / 'styles/ticks.mplstyle',
19 | ])
20 |
21 |
22 | subplots_kw = dict(
23 | figsize=(5.7/2.54, 0.4/2.54),
24 | subplot_kw=dict(xlim=(0, 5), ylim=(0, 1)),
25 | )
26 |
27 | (fig, ax) = plt.subplots(**subplots_kw)
28 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.0))
29 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.2))
30 | ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
31 | ax.xaxis.set_minor_formatter(ticker.ScalarFormatter())
32 | ax.tick_params(axis='both', which='major', labelsize=5)
33 | ax.tick_params(axis='x', which='minor', rotation=90)
34 |
35 | fig.savefig(ROOT_DIR / "figures/tick-multiple-locator.pdf", transparent=True)
36 |
--------------------------------------------------------------------------------
/scripts/tip-color-range.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | # Scripts to generate all the basic plots
7 | import pathlib
8 |
9 | import numpy as np
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | fig = plt.figure(figsize=(2, 2))
17 | mpl.rcParams['axes.linewidth'] = 1.5
18 | d = 0.01
19 |
20 | ax = fig.add_axes([d, d, 1-2*d, 1-2*d], xticks=[], yticks=[])
21 |
22 | X = np.random.seed(1)
23 | X = np.random.randn(1000, 4)
24 | cmap = plt.get_cmap("Oranges")
25 | colors = [cmap(i) for i in [.1, .3, .5, .7]]
26 | ax.hist(X, 2, density=True, histtype='bar', color=colors)
27 |
28 | fig.savefig(ROOT_DIR / "figures/tip-color-range.pdf")
29 | # plt.show()
30 |
--------------------------------------------------------------------------------
/scripts/tip-colorbar.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | # Scripts to generate all the basic plots
7 | import pathlib
8 |
9 | import numpy as np
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 | import matplotlib.patheffects as path_effects
13 |
14 |
15 | ROOT_DIR = pathlib.Path(__file__).parent.parent
16 |
17 | fig = plt.figure(figsize=(2.15, 2))
18 | mpl.rcParams['axes.linewidth'] = 1.5
19 | d = 0.01
20 | ax = fig.add_axes([d, d, 1-2*d, 1-2*d], xticks=[], yticks=[])
21 |
22 | np.random.seed(1)
23 | Z = np.random.uniform(0, 1, (8, 8))
24 | cmap = plt.get_cmap("Oranges")
25 | im = ax.imshow(Z, interpolation="nearest", cmap=cmap, vmin=0, vmax=2)
26 | cb = fig.colorbar(im, fraction=0.046, pad=0.04)
27 | cb.set_ticks([])
28 |
29 | fig.savefig(ROOT_DIR / "figures/tip-colorbar.pdf")
30 | # plt.show()
31 |
--------------------------------------------------------------------------------
/scripts/tip-dotted.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | # Scripts to generate all the basic plots
7 | import pathlib
8 |
9 | import numpy as np
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 |
13 |
14 | ROOT_DIR = pathlib.Path(__file__).parent.parent
15 |
16 | fig = plt.figure(figsize=(5, .25))
17 |
18 | ax = fig.add_axes([0, 0, 1, 1], frameon=False,
19 | xticks=[], yticks=[], xlim=[0, 1], ylim=[-.5, 1.5])
20 |
21 | epsilon=1e-12
22 | plt.plot([0, 1], [0, 0], "black", clip_on=False, lw=8,
23 | ls=(.5, (epsilon, 1)), dash_capstyle="round")
24 | plt.plot([0, 1], [1, 1], "black", clip_on=False, lw=8,
25 | ls=(-.5, (epsilon, 2)), dash_capstyle="round")
26 | fig.savefig(ROOT_DIR / "figures/tip-dotted.pdf")
27 | # plt.show()
28 |
--------------------------------------------------------------------------------
/scripts/tip-dual-axis.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import numpy as np
4 | import matplotlib as mpl
5 | import matplotlib.pyplot as plt
6 |
7 |
8 | ROOT_DIR = pathlib.Path(__file__).parent.parent
9 |
10 | mpl.rcParams['axes.linewidth'] = 1.5
11 |
12 | fig = plt.figure(figsize=(2, 2))
13 | d = 0.01
14 | ax1 = fig.add_axes([d, d, 1-2*d, 1-2*d], label="cartesian")
15 | ax2 = fig.add_axes([d, d, 1-2*d, 1-2*d], projection="polar", label="polar")
16 |
17 | ax1.set_xticks([]) # np.linspace(0.0, 0.4, 5))
18 | ax1.set_yticks([]) # np.linspace(0.0, 1.0, 11))
19 |
20 | ax2.set_rorigin(0)
21 | ax2.set_thetamax(90)
22 | ax2.set_ylim(0.5, 1.0)
23 | ax2.set_xticks(np.linspace(0, np.pi/2, 10))
24 | ax2.set_yticks(np.linspace(0.5, 1.0, 5))
25 |
26 | ax2.set_xticklabels([])
27 | ax2.set_yticklabels([])
28 |
29 | fig.savefig(ROOT_DIR / "figures/tip-dual-axis.pdf")
30 | # plt.show()
31 |
--------------------------------------------------------------------------------
/scripts/tip-font-family.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Title: Scientific Visualisation - Python & Matplotlib
3 | # Author: Nicolas P. Rougier
4 | # License: BSD
5 | # ----------------------------------------------------------------------------
6 | import pathlib
7 |
8 | import numpy as np
9 | import matplotlib.pyplot as plt
10 | import matplotlib.ticker as ticker
11 |
12 |
13 | ROOT_DIR = pathlib.Path(__file__).parent.parent
14 |
15 |
16 | # Setup a plot such that only the bottom spine is shown
17 | def setup(ax):
18 | ax.spines['right'].set_color('none')
19 | ax.spines['left'].set_color('none')
20 | ax.yaxis.set_major_locator(ticker.NullLocator())
21 | ax.spines['top'].set_color('none')
22 |
23 | ax.spines['bottom'].set_position("center")
24 |
25 | ax.xaxis.set_ticks_position('bottom')
26 | ax.tick_params(which='major', width=1.00)
27 | ax.tick_params(which='major', length=5)
28 | ax.tick_params(which='minor', width=0.75)
29 | ax.tick_params(which='minor', length=2.5)
30 | ax.set_xlim(0, 5)
31 | ax.set_ylim(0, 1)
32 | ax.patch.set_alpha(0.0)
33 |
34 |
35 | fig = plt.figure(figsize=(5, .5))
36 | fig.patch.set_alpha(0.0)
37 | n = 1
38 |
39 | fontsize = 18
40 | ax = plt.subplot(n, 1, 1)
41 | ax.tick_params(axis='both', which='minor', labelsize=6)
42 | setup(ax)
43 | ax.xaxis.set_major_locator(ticker.MultipleLocator(1.0))
44 | ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.2))
45 | ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
46 | ax.xaxis.set_minor_formatter(ticker.ScalarFormatter())
47 | ax.tick_params(axis='x', which='minor', rotation=0)
48 |
49 | for tick in ax.get_xticklabels(which='both'):
50 | tick.set_fontname("Roboto Condensed")
51 |
52 | plt.tight_layout()
53 | fig.savefig(ROOT_DIR / "figures/tip-font-family.pdf", transparent=True)
54 | # plt.show()
55 |
--------------------------------------------------------------------------------
/scripts/tip-hatched.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import numpy as np
4 | import matplotlib.pyplot as plt
5 |
6 |
7 | ROOT_DIR = pathlib.Path(__file__).parent.parent
8 |
9 | cmap = plt.get_cmap("Oranges")
10 | color1, color2 = cmap(0.3), cmap(0.5)
11 |
12 | plt.rcParams['hatch.color'] = color1
13 | plt.rcParams['hatch.linewidth'] = 8
14 |
15 | fig = plt.figure(figsize=(2, 2))
16 | ax = plt.subplot()
17 | np.random.seed(123)
18 |
19 | x1, y1 = 3*np.arange(2), np.random.randint(25, 50, 2)
20 | x2, y2 = x1+1, np.random.randint(25, 75, 2)
21 |
22 | ax.bar(x1, y1, color=color2)
23 | for x, y in zip(x1, y1):
24 | plt.annotate(f"{y:d}%", (x, y), xytext=(0, 1),
25 | fontsize="x-small", color=color2,
26 | textcoords="offset points", va="bottom", ha="center")
27 |
28 | ax.bar(x2, y2, color=color2, hatch="/" )
29 | for x, y in zip(x2, y2):
30 | plt.annotate(f"{y:d}%", (x, y), xytext=(0, 1),
31 | fontsize="x-small", color=color2,
32 | textcoords="offset points", va="bottom", ha="center")
33 |
34 | ax.set_yticks([])
35 | ax.set_xticks(0.5+np.arange(0, 6, 3))
36 | ax.set_xticklabels(["2018", "2019"])
37 | ax.tick_params('x', length=0, labelsize="small", which='major')
38 |
39 | ax.spines['right'].set_visible(False)
40 | ax.spines['left'].set_visible(False)
41 | ax.spines['top'].set_visible(False)
42 |
43 | plt.tight_layout()
44 | fig.savefig(ROOT_DIR / "figures/tip-hatched.pdf")
45 | # plt.show()
46 |
--------------------------------------------------------------------------------
/scripts/tip-multiline.py:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Author: Nicolas P. Rougier
3 | # License: BSD
4 | # ----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 |
12 | ROOT_DIR = pathlib.Path(__file__).parent.parent
13 |
14 | mpl.rcParams['axes.linewidth'] = 1.5
15 |
16 | fig = plt.figure(figsize=(8, 1.5))
17 | dx, dy = 0.0025, 0.01
18 | ax = fig.add_axes([dx, dy, 1-2*dx, 1-2*dy], frameon=False)
19 | X, Y = [], []
20 | for x in np.linspace(0.01, 10*np.pi-0.01, 100):
21 | X.extend([x, x, None])
22 | Y.extend([0, np.sin(x), None])
23 | print(X[:10], Y[:10])
24 | plt.plot(X, Y, "black")
25 | plt.xticks([]), plt.yticks([])
26 | plt.xlim(-0.25, 10*np.pi+.25)
27 | plt.ylim(-1.5, 1.5)
28 | plt.tight_layout()
29 | fig.savefig(ROOT_DIR / "figures/tip-multiline.pdf", dpi=100)
30 | # plt.show()
31 |
--------------------------------------------------------------------------------
/scripts/tip-outline.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 |
6 | # Scripts to generate all the basic plots
7 | import pathlib
8 |
9 | import numpy as np
10 | import matplotlib as mpl
11 | import matplotlib.pyplot as plt
12 | import matplotlib.patheffects as path_effects
13 |
14 |
15 | ROOT_DIR = pathlib.Path(__file__).parent.parent
16 |
17 | fig = plt.figure(figsize=(2, 2))
18 | mpl.rcParams['axes.linewidth'] = 1.5
19 | d = 0.01
20 |
21 | ax = fig.add_axes([d, d, 1-2*d, 1-2*d], xticks=[], yticks=[])
22 |
23 | np.random.seed(1)
24 | Z = np.random.uniform(0, 1, (8, 8))
25 | cmap = plt.get_cmap("Oranges")
26 | ax.imshow(Z, interpolation="nearest", cmap=cmap, vmin=0, vmax=2)
27 |
28 | text = ax.text(0.5, 0.1, "Label", transform=ax.transAxes,
29 | color=cmap(0.9), size=32, weight="bold", ha="center", va="bottom")
30 | text.set_path_effects([path_effects.Stroke(linewidth=5, foreground='white'),
31 | path_effects.Normal()])
32 | fig.savefig(ROOT_DIR / "figures/tip-outline.pdf")
33 |
--------------------------------------------------------------------------------
/scripts/tip-post-processing.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import numpy as np
4 | import matplotlib.pyplot as plt
5 | from matplotlib.figure import Figure
6 | from matplotlib.backends.backend_agg import FigureCanvas
7 | from scipy.ndimage import gaussian_filter
8 |
9 |
10 | ROOT_DIR = pathlib.Path(__file__).parent.parent
11 |
12 | # First pass for drop-shadow
13 | fig = Figure(figsize=(6, 1.5))
14 | canvas = FigureCanvas(fig)
15 | ax = fig.add_axes([0, 0, 1, 1], frameon=False,
16 | xlim=[0, 1], xticks=[], ylim=[0, 1], yticks=[])
17 | ax.text(0.5, 0.5, "Matplotlib", transform=ax.transAxes,
18 | ha="center", va="center", size=64, color="black")
19 | canvas.draw()
20 | Z = np.array(canvas.renderer.buffer_rgba())[:, :, 0]
21 | Z = gaussian_filter(Z, sigma=9)
22 |
23 | # Second pass for text + drop-shadow
24 | fig = plt.figure(figsize=(6, 1.5))
25 | ax = fig.add_axes([0, 0, 1, 1], frameon=False,
26 | xlim=[0, 1], xticks=[], ylim=[0, 1], yticks=[])
27 | ax.imshow(Z, extent=[0, 1, 0, 1], cmap=plt.cm.gray, alpha=0.65, aspect='auto')
28 | ax.text(0.5, 0.5, "Matplotlib", transform=ax.transAxes,
29 | ha="center", va="center", size=64, color="black")
30 |
31 | fig.savefig(ROOT_DIR / "figures/tip-post-processing.pdf", dpi=600)
32 | # plt.show()
33 |
--------------------------------------------------------------------------------
/scripts/tip-transparency.py:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------
2 | # Matplotlib cheat sheet
3 | # Released under the BSD License
4 | # -----------------------------------------------------------------------------
5 | import pathlib
6 |
7 | import numpy as np
8 | import matplotlib as mpl
9 | import matplotlib.pyplot as plt
10 |
11 | ROOT_DIR = pathlib.Path(__file__).parent.parent
12 |
13 | mpl.rc('axes', linewidth=1.5)
14 |
15 | np.random.seed(123)
16 |
17 | fig = plt.figure(figsize=(2, 2), dpi=100)
18 | margin = 0.01
19 | ax = fig.add_axes([margin, margin, 1-2*margin, 1-2*margin])
20 | n = 500
21 | X = np.random.normal(0, 0.25, n)
22 | Y = np.random.normal(0, 0.25, n)
23 | ax.scatter(X, Y, s=50, c="k", lw=2)
24 | ax.scatter(X, Y, s=50, c="w", lw=0)
25 | ax.scatter(X, Y, s=40, c="C1", lw=0, alpha=0.1)
26 |
27 | ax.set_xlim([-1, 1]), ax.set_xticks([]),
28 | ax.set_ylim([-1, 1]), ax.set_yticks([])
29 | fig.savefig(ROOT_DIR / "figures/tip-transparency.pdf")
30 | # plt.show()
31 |
--------------------------------------------------------------------------------
/styles/base.mplstyle:
--------------------------------------------------------------------------------
1 | figure.constrained_layout.use: True
2 | figure.constrained_layout.h_pad: 0.01
3 | figure.constrained_layout.w_pad: 0.01
4 | figure.constrained_layout.hspace: 0.1
5 | figure.constrained_layout.wspace: 0.1
6 |
--------------------------------------------------------------------------------
/styles/plotlet-grid.mplstyle:
--------------------------------------------------------------------------------
1 | font.family: Source Code Pro
2 | font.size: 5
3 |
4 | axes.linewidth: 0.5
5 |
6 | xtick.major.size: 0.0
7 | ytick.major.size: 0.0
8 |
--------------------------------------------------------------------------------
/styles/plotlet.mplstyle:
--------------------------------------------------------------------------------
1 | figure.figsize: 0.4, 0.4
2 |
3 | figure.constrained_layout.h_pad: 0.01
4 | figure.constrained_layout.w_pad: 0.01
5 | figure.constrained_layout.hspace: 0.01
6 | figure.constrained_layout.wspace: 0.01
7 |
8 | axes.linewidth: 0.5
9 |
10 | grid.linewidth: 0.2
11 |
12 | lines.linewidth: 0.75
13 |
14 | xtick.major.size: 0.0
15 | ytick.major.size: 0.0
16 |
17 | xtick.labeltop: False
18 | xtick.labelbottom: False
19 |
20 | ytick.labelleft: False
21 | ytick.labelright: False
22 |
--------------------------------------------------------------------------------
/styles/sine-plot.mplstyle:
--------------------------------------------------------------------------------
1 | font.size: 4
2 |
3 | axes.titlesize: 4
4 | axes.titlepad: 2
5 | axes.linewidth: 0.2
6 |
7 | lines.linewidth: 0.5
8 | lines.markersize: 3
9 |
10 | xtick.labelsize: 3
11 | xtick.major.pad: 1
12 | xtick.major.width: 0.2
13 | xtick.major.size: 1
14 | xtick.minor.width: 0.1
15 | xtick.minor.size: 0.5
16 |
17 | ytick.labelsize: 3
18 | ytick.major.pad: 1
19 | ytick.major.width: 0.2
20 | ytick.major.size: 1
21 | ytick.minor.width: 0.1
22 | ytick.minor.size: 0.5
23 |
24 | legend.fontsize: 3
25 |
--------------------------------------------------------------------------------
/styles/ticks.mplstyle:
--------------------------------------------------------------------------------
1 | savefig.transparent: True
2 |
3 | font.size: 5
4 |
5 | axes.linewidth: 0.5
6 | axes.spines.right: False
7 | axes.spines.top: False
8 | axes.spines.left: False
9 | axes.spines.bottom: True
10 |
11 | xtick.labelsize: 3
12 | xtick.major.size: 2
13 | xtick.major.width: 0.2
14 | xtick.major.pad: 2
15 | xtick.minor.size: 1
16 | xtick.minor.width: 0.2
17 | xtick.minor.pad: 2
18 |
19 | ytick.left: False
20 | ytick.labelleft: False
21 |
--------------------------------------------------------------------------------