Skip to main content

A collection of tools for use in the Institute of Chemical Engineering at Ulm University.

Project description

Installation

Install the package by running the following command:

pip install iciw-plots

or

pip install iciw-plots -U
pip install iciw-plots -U
Requirement already satisfied: iciw-plots in c:\programdata\anaconda3\envs\ml3\lib\site-packages (1.0.40)
Collecting iciw-plots
  Downloading ICIW_Plots-1.0.41-py3-none-any.whl.metadata (17 kB)
Requirement already satisfied: numpy in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from iciw-plots) (1.26.4)
Requirement already satisfied: matplotlib in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from iciw-plots) (3.8.4)
Requirement already satisfied: contourpy>=1.0.1 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (1.2.0)
Requirement already satisfied: cycler>=0.10 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (0.11.0)
Requirement already satisfied: fonttools>=4.22.0 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (4.51.0)
Requirement already satisfied: kiwisolver>=1.3.1 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (1.4.4)
Requirement already satisfied: packaging>=20.0 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (24.1)
Requirement already satisfied: pillow>=8 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (10.4.0)
Requirement already satisfied: pyparsing>=2.3.1 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (3.0.9)
Requirement already satisfied: python-dateutil>=2.7 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from matplotlib->iciw-plots) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in c:\programdata\anaconda3\envs\ml3\lib\site-packages (from python-dateutil>=2.7->matplotlib->iciw-plots) (1.16.0)
Downloading ICIW_Plots-1.0.41-py3-none-any.whl (29 kB)
Installing collected packages: iciw-plots
  Attempting uninstall: iciw-plots
    Found existing installation: ICIW_Plots 1.0.40
    Uninstalling ICIW_Plots-1.0.40:
      Successfully uninstalled ICIW_Plots-1.0.40
Successfully installed iciw-plots-1.0.41
Note: you may need to restart the kernel to use updated packages.

Usage

Although I show the usage of the package in the context of a Jupyter notebook, the package can be used in any Python environment. Also, the style has to be used only once, at the beginning of the plotting file or notebook. In this document I write it in nearly every box just to show th use. This is not necessary!

Use of the default style

The default style defines convenient presets for the following settings:

  • Font size
  • Font family
  • Line width
  • Marker size
  • Color palette
  • Grid style
  • Legend style
import matplotlib.pyplot as plt
import numpy as np

plt.style.use("ICIWstyle")

x = np.linspace(0, 2 * np.pi, 100)

for i in range(7):
    plt.plot(x, np.sin(x + (i * (4 * np.pi / 7))), label=f"Line {i}")

plt.legend()
plt.show()

png

In addition to the default style, the package also provides different styles to be loaded additionally. These can be used to

  • enable rendering of texts in LaTeX format by using ICIWlatex
  • disable the background when exporting the plot by using ICIWnobg

The latex style automatically imports the LaTex packages amsmath, amssymb, siunitx and mchem enabling the use of all latex math commands, SI unit rendering and chemical formulas.

Note, How I use the style only temporarily with the contextmanager.

import matplotlib.pyplot as plt

plt.style.use("ICIWstyle")

x = np.linspace(0, 2 * np.pi, 100)

with plt.style.context(
    "ICIWlatex", after_reset=False
):  # use the latex style only for this plot
    for i in range(7):
        plt.plot(x, np.sin(x + (i * (4 * np.pi / 7))))

    plt.xlabel(r"$t$ / \unit{\second}")  # use latex formulae and a unit
    plt.ylabel(r"$c$ / \unit{\mole\per\metre\cubed}")
    plt.legend(
        [
            r"\ce{A}",  # use chemistry symbols
            r"\ce{B}",
            r"\ce{AB}",
            r"\ce{AB2}",
            r"\ce{A2B}",
            r"\ce{C2+}",
        ]
    )

    plt.show()

png

Sizes

The package provides default size options for the following publishers:

  • ACS
  • Elsevier

To make conversion between default matplotlib units (inches) and european units (cm) easier, the package provides the following conversion factors:

  • cm2inch
  • mm2inch
from ICIW_Plots.figures import Elsevier_Sizes, ACS_Sizes
from ICIW_Plots import cm2inch

print(
    f"Width for Elsevier default single column wide plots:\n{Elsevier_Sizes.single_column}"
)
print(
    f"Width for Elsevier default double column wide plots:\n{Elsevier_Sizes.double_column}"
)
print(
    f"width for Elsevier defaultone and a half column wide plots:\n{Elsevier_Sizes.threehalf_column}"
)

print(f"Width for ACS default single column wide plots:\n{ACS_Sizes.single_column}")
print(f"Width for ACS default double column wide plots:\n{ACS_Sizes.double_column}")

fig = plt.figure(figsize=(Elsevier_Sizes.single_column["in"], 5 * cm2inch))
ax = fig.add_axes([0, 0, 1, 1])
plt.show()
Width for Elsevier default single column wide plots:
{'mm': 90, 'in': 3.54, 'cm': 9}
Width for Elsevier default double column wide plots:
{'mm': 190, 'in': 7.48, 'cm': 19}
width for Elsevier defaultone and a half column wide plots:
{'mm': 140, 'in': 5.51, 'cm': 14}
Width for ACS default single column wide plots:
{'mm': 82.55, 'in': 3.25, 'cm': 8.255}
Width for ACS default double column wide plots:
{'mm': 177.8, 'in': 7, 'cm': 17.78}

png

More Sizes and Axes

Oftentimes, I like to create square axis with a fixed width in the middle of a figure with fixed width. matplotlib makes this hard for the user. ICIW-Plots provides functions make_square_ax, make_rect_ax and make_square_subplots that do this for you.

plt.style.use("ICIWstyle")
from ICIW_Plots.figures import Elsevier_Sizes
from ICIW_Plots import make_square_ax

fig = plt.figure(figsize=(Elsevier_Sizes.single_column["in"], 7 * cm2inch))
ax = make_square_ax(
    fig,
    ax_width=5 * cm2inch,
)
ax.plot(x, np.sin(x))
plt.show()
c:\ProgramData\Anaconda3\envs\ML3\Lib\site-packages\ICIW_Plots\layout.py:77: UserWarning: Unscientific behavior. No xlabel provided.
  warnings.warn("Unscientific behavior. No xlabel provided.")
c:\ProgramData\Anaconda3\envs\ML3\Lib\site-packages\ICIW_Plots\layout.py:82: UserWarning: Unscientific behavior. No ylabel provided.
  warnings.warn("Unscientific behavior. No ylabel provided.")

png

As you can see, you even get a warning when you misbehave. Both functions take some arguments you can inspect via the mouseover in your IDE. Note, that the kwargs argument takes any argument, a normal plt.add_axes function would take. Here is just an example of what you can do although it is unreasonable to do so:

from ICIW_Plots.figures import Elsevier_Sizes
from ICIW_Plots import make_square_ax

plt.style.use("ICIWstyle")

fig = plt.figure(figsize=(Elsevier_Sizes.single_column["in"], 7 * cm2inch))
ax = make_square_ax(
    fig,
    ax_width=5 * cm2inch,
    # left_h=0.2,  # These arguments control the spacing of the axis
    # bottom_v=0.2, # not supplying them wil place the axes in the middle of the figure
    xlabel=r"$t$ / s",
    ylabel=r"$U$ / V",
    title="This is a title",
    xscale="log",
)
ax.plot(x, np.sin(x))
plt.show()

png

import matplotlib.pyplot as plt
from ICIW_Plots import make_rect_ax

plt.style.use("ICIWstyle")

fig = plt.figure()

ax = make_rect_ax(
    fig,
    ax_width=7.3 * cm2inch,
    ax_height=5 * cm2inch,
    # left_h=0.2,  # These arguments control the spacing of the axis
    # bottom_v=0.2, # not supplying them wil place the axes in the middle of the figure
    xlabel=r"$t$ / s",
    ylabel=r"$U$ / V",
    title="This is a title",
    xscale="log",
)

ax.plot(x, np.sin(x))

plt.show()

png

The make_square_subplot command behaves slightly different whether you want the x- or y- axes to be shared and which labels you provide. The docstring sys there are the following options:

sharex, sharey : bool, optional

  whether axes on top of or next to eachother share one x or y axes, by default False

sharelabel : bool, optional

 whether to share the labels of the shared axes, by default False

xlabel, ylabel : Optional[str | npt.ArrayLike], optional

 label or labels for the axes. Can be one of the following:

  • None - no label
  • a single str - every subplot will get the same x/y label
  • a 1D npt.ArrayLike - every column/row will get the same x/y label
  • a 2D npt.ArrayLike - every subplot will get its own x/y label

 If sharex or sharey is True, only the last row/column (the shared axis) will get the label. By default None

import matplotlib.pyplot as plt
from ICIW_Plots import make_square_subplots

plt.style.use("ICIWstyle")

fig = plt.figure()
axs = make_square_subplots(
    fig=fig,
    ax_width=3 * cm2inch,
    ax_layout=(2, 3),
    h_sep=1.5 * cm2inch,
    v_sep=1 * cm2inch,
    sharex=True,  # share the axis
    sharey=True,  # share the axis
    sharelabel=False,
    xlabel="$x$",  # every x axis has the same label
    ylabel=["$y_1$", "$y_2$"],  # every y axis along the rows has the same label
)

png

fig = plt.figure()
axs = make_square_subplots(
    fig=fig,
    ax_width=3 * cm2inch,
    ax_layout=(2, 3),
    h_sep=1.5 * cm2inch,
    v_sep=1 * cm2inch,
    sharex=True,  # share the axis
    sharey=True,  # share the axis
    sharelabel=True,  # ticklabels are not repeated for shared axis
    xlabel="$x$",  # every x axis has the same label
    ylabel=["$y_1$", "$y_2$"],  # every y axis along the rows has the same label
)

png

fig = plt.figure()
axs = make_square_subplots(
    fig=fig,
    ax_width=3 * cm2inch,
    ax_layout=(2, 3),
    h_sep=1.5 * cm2inch,
    v_sep=1 * cm2inch,
    sharex=False,  # because we do not share the axis, every axis is labeled
    sharey=False,  # because we do not share the axis, every axis is labeled
    xlabel="x",  # every x axis has the same label
    ylabel=["$y_1$", "$y_2$"],  # every y axis along the rows has the same label
)

png

fig = plt.figure()
axs = make_square_subplots(
    fig=fig,
    ax_width=3 * cm2inch,
    ax_layout=(2, 3),
    h_sep=1.5 * cm2inch,
    v_sep=1 * cm2inch,
    sharex=True,
    sharey=False,
    xlabel=[
        "$x_1$",
        "$x_2$",
        "$x_3$",
    ],  # every x axis along one column has the same label. Because it is shared, they do not repeat.
    ylabel=[
        ["$y_1$", "$y_2$", "$y_3$"],
        ["$y_4$", "$y_5$", "$y_6$"],
    ],  # every y axis was given its own label. Only recommended for non-shared axes
)

png

fig = plt.figure()
axs = make_square_subplots(
    fig=fig,
    ax_width=3 * cm2inch,
    ax_layout=(2, 3),
    h_sep=1.5 * cm2inch,
    v_sep=1 * cm2inch,
    sharex=False,  # because we do not share the axis, every axis is labeled
    sharey=False,  # because we do not share the axis, every axis is labeled
    xlabel="x",  # every x axis has the same label
    ylabel=["$y_1$", "$y_2$"],  # every y axis along the rows has the same label
)

png

There is also a make_rect_subplots command that behaves like make_square_subplots but allows for rectangular subplots.

from ICIW_Plots import make_rect_subplots

fig = plt.figure()
axs = make_rect_subplots(
    fig=fig,
    ax_width=6 * cm2inch,
    ax_height=4 * cm2inch,
    ax_layout=(2, 1),
    h_sep=1.5 * cm2inch,
    v_sep=1 * cm2inch,
    sharex=True,  # share the axis
    sharey=True,  # share the axis
    sharelabel=False,
    xlabel="$x$",  # every x axis has the same label
    ylabel=["$y_1$", "$y_2$"],  # every y axis along the rows has the same label
)

png

In jupyter notebooks the output appears cut to the "appropriate" size. In a python script, you will see the full figure with all the sizes and positions spaced correctly.

Colors

ICIW-Plots defines the university colors.

import matplotlib.pyplot as plt
import ICIW_Plots.colors as ICIWcolors

plt.style.use("ICIWstyle")

fig, ax = plt.subplots()

ax.plot(x, np.sin(x), color=ICIWcolors.CRIMSON)
ax.plot(x, np.cos(x), color=ICIWcolors.CERULEAN)
ax.plot(x, np.log(x + 0.1), color=ICIWcolors.KELLYGREEN)
ax.plot(x, np.tanh(x), color=ICIWcolors.FLAME)
ax.plot(x, np.arcsinh(x), color=ICIWcolors.DRAB)

plt.legend(["crimson", "cerulean", "kellygreen", "flame", "drab"])

plt.show()

png

Colormaps

All university colors are available as colormaps as well. Here is just an example for the cerulean colormap:

import matplotlib.pyplot as plt
import ICIW_Plots.colors as ICIWcolors

plt.style.use("ICIWstyle")

N = 100
x = np.linspace(-3.0, 3.0, N)
y = np.linspace(-2.0, 2.0, N)

X, Y = np.meshgrid(x, y)
Z1 = -(X**2) - Y**2
Z2 = -((X * 10) ** 2) - (Y * 10) ** 2
z = Z1 + 50 * Z2

fig, ax = plt.subplots()

cs = ax.contourf(X, Y, z, cmap=ICIWcolors.cerulean_cm, levels=10)
cbar = fig.colorbar(cs)

plt.show()

png

Additionally, ICIW-Plots provides a way to define "nice looking" colorschemes based on the theory of adjacent or analogous colors. You can use any color as a base and generate an appealing color scheme this way.

This works great for plots where line show an increase in, e.g. temperature.

You can either create a list of these colors or use them as a cycler via the functions adjacent_colors or adjacent_cycler respectively. For cyclers see the later section.

import matplotlib.pyplot as plt
import ICIW_Plots.colors as ICIWcolors

colors = ICIWcolors.adjacent_colors(
    ICIWcolors.FLAME,  # any valid color as an array of three values [R,G,B], here, one of our own university colors
    n=5,  # the number of adjacent colors you want. Must be odd.
    phi=15,  # the "distance" of two adjacent colors. The smaller, the more similar.
)
print(colors)
[(0.91015625, 0.02734375, 0.07031249999999899), (0.91015625, 0.20507812500000003, 0.02734375), (0.91015625, 0.42578125, 0.02734375), (0.91015625, 0.646484375, 0.02734375), (0.91015625, 0.8671875, 0.02734375)]

Cyclers

The package defines some functionality to do your own cyclers. Supported are:

  • color cyclers from colormaps
    • all default matplotlib colormaps by name
    • all custom colormaps from ICIW-Plots by reference
  • line style cyclers
    • all default linestyles by abbreviation (-,--,.-,:)
    • every custom linestyle by a dash tuple (e.g., (0,(3,10,1,15)))
  • marker cyclers
    • all predefined markers by abbreviation (o,s,^,v,and so on)
    • every custom marker by a marker reference

Custom color cyclers take a colormap and sample num_plots points from them equidistantly spaced. start and stop are used to prevent very light or very dark colors from being used. The cycler is then added as the axes prop_cycle.

import matplotlib.pyplot as plt
import ICIW_Plots.cyclers as ICIW_cyclers

fig, ax = plt.subplots()
x = np.linspace(-2 * np.pi, 2 * np.pi)
my_green_cycler = ICIW_cyclers.ICIW_colormap_cycler(
    "Greens",
    7,
    start=0.2,
)
ax.set_prop_cycle(my_green_cycler)
for i in range(7):
    ax.plot(x, np.sin(x + (i * (4 * np.pi / 7))))
plt.show()

png

import matplotlib.pyplot as plt
import ICIW_Plots.cyclers as ICIW_cyclers

fig, ax = plt.subplots()

my_blue_cycler = ICIW_cyclers.ICIW_colormap_cycler(
    ICIWcolors.cerulean_cm,
    7,
    start=0.1,
)
ax.set_prop_cycle(my_blue_cycler)
for i in range(7):
    ax.plot(x, np.sin(x + (i * (4 * np.pi / 7))))
plt.show()

png

import matplotlib.pyplot as plt
import ICIW_Plots.colors as ICIWcolors

adjacent_cyc = ICIWcolors.adjacent_cycler(
    np.array([224, 58, 91])
    / 256,  # any valid color as an array of three values [R,G,B], here, an arbitrary color.
    n=5,
    phi=25,
)

fig, ax = plt.subplots()
ax.set_prop_cycle(adjacent_cyc)

T = np.linspace(400, 500, 100)
E_As = np.linspace(60000, 70000, 5)

for E_A in E_As:
    ax.plot(T, 1e7 * np.exp(-E_A / 8.314 / T), label=f"$E_A$= {E_A}")

ax.set(xlabel="$T$", ylabel="$r$")

plt.legend()
plt.show()

png

Linestyle cyclers

Custom linestyle cyclers take a list of linestyles and a number of plots to cycle through. The cycler is then added as the axes prop_cycle.

my_linestyle_cycler = ICIW_cyclers.ICIW_linestyle_cycler(3)

fig, ax = plt.subplots()

ax.set_prop_cycle(my_linestyle_cycler)
for j in range(3):
    ax.plot(x, x + j * 5)

png

Note, that all lines have the same color, since matplotlib by default cycles through its default cycler containing the colors. By overwriting the default cycler by our linestyle cycler, all lines will have the same color.

We can combine different cyclers together by either

  • inner product (pairwise combinations)
  • outer product (unique combinations)
fig, axs = plt.subplots(1, 2)

custom_c_cycler = ICIW_cyclers.ICIW_colormap_cycler("Greens", 3, start=0.5)
custom_l_cycler = ICIW_cyclers.ICIW_linestyle_cycler(3)

axs[0].set_title("Inner Product")
# this combination gives 3 different combinations of color and line style
# linestyle 1 and color 1, linestyle 2 and color 2, linestyle 3 and color 3
axs[0].set_prop_cycle(custom_c_cycler + custom_l_cycler)
for i in range(3):
    axs[0].plot(x, np.sin(x + (i * (4 * np.pi / 5))))

axs[1].set_title("Outer Product")
# this combination gives 9 different combinations of color and line style
# linestyle 1 and color 1, linestyle 2 and color 1, linestyle 3 and color 1 and so on
axs[1].set_prop_cycle(custom_c_cycler * custom_l_cycler)
for i in range(3):
    for j in range(3):
        axs[1].plot(x, i * x + j * 5)

png

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iciw_plots-1.0.43.tar.gz (33.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

iciw_plots-1.0.43-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file iciw_plots-1.0.43.tar.gz.

File metadata

  • Download URL: iciw_plots-1.0.43.tar.gz
  • Upload date:
  • Size: 33.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.4

File hashes

Hashes for iciw_plots-1.0.43.tar.gz
Algorithm Hash digest
SHA256 7976144465095b30ce5cac7b026a7dc488289f01c5bc9bb1cf0c7170dc830107
MD5 c63a5546b9df009fcccf56ca7e21fe73
BLAKE2b-256 cea10256d4ce73066d94944f0646fa088e651f8cec6cff88df9d0698e505b381

See more details on using hashes here.

File details

Details for the file iciw_plots-1.0.43-py3-none-any.whl.

File metadata

  • Download URL: iciw_plots-1.0.43-py3-none-any.whl
  • Upload date:
  • Size: 31.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.4

File hashes

Hashes for iciw_plots-1.0.43-py3-none-any.whl
Algorithm Hash digest
SHA256 9567f8bfad2b1a55886647bb940064c75308160f1e14b489d7da17900f4cc2bf
MD5 fb432de067fa9b162fb4f62cc9218c02
BLAKE2b-256 c718c43d1f0406f188ed6e30a6ba15953aad9ba221b17f579f23de7b4ef6a8c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page