📊 Extensions for Matplotlib

Overview

matplotx

Some useful extensions for Matplotlib.

PyPi Version PyPI pyversions GitHub stars Downloads

gh-actions codecov LGTM Code style: black

Install with

pip install matplotx

and use in Python with

import matplotx

See below for what matplotx can do.

Clean line plots (dufte)

matplotlib matplotx.styles.dufte, matplotx.ylabel_top, matplotx.line_labels matplotx.styles.dracula | matplotx.styles.dufte

The middle plot is created with

import matplotlib.pyplot as plt
import matplotx
import numpy as np

# create data
rng = np.random.default_rng(0)
offsets = [1.0, 1.50, 1.60]
labels = ["no balancing", "CRV-27", "CRV-27*"]
x0 = np.linspace(0.0, 3.0, 100)
y = [offset * x0 / (x0 + 1) + 0.1 * rng.random(len(x0)) for offset in offsets]

# plot
with plt.style.context(matplotx.styles.dufte):
    for yy, label in zip(y, labels):
        plt.plot(x0, yy, label=label)
    plt.xlabel("distance [m]")
    matplotx.ylabel_top("voltage [V]")  # move ylabel to the top, rotate
    matplotx.line_labels()  # line labels to the right
    plt.show()

The three matplotx ingredients are:

  • matplotx.styles.dufte: A minimalistic style
  • matplotx.ylabel_top: Rotate and move the the y-label
  • matplotx.line_labels: Show line labels to the right, with the line color

You can also combine dufte with any other style (see below) with

plt.style.use(matplotx.styles.dracula | matplotx.styles.dufte)

(This uses the Python 3.10 dict merge operator |. If you're using an older Python version, you have to use, e.g., {**x, **y}.)

Further reading and other styles:

Clean bar plots

matplotlib dufte dufte with matplotx.show_bar_values()

The right plot is created with

import matplotlib.pyplot as plt
import matplotx

labels = ["Australia", "Brazil", "China", "Germany", "Mexico", "United\nStates"]
vals = [21.65, 24.5, 6.95, 8.40, 21.00, 8.55]
xpos = range(len(vals))

with plt.style.context(matplotx.styles.dufte_bar):
    plt.bar(xpos, vals)
    plt.xticks(xpos, labels)
    matplotx.show_bar_values("{:.2f}")
    plt.title("average temperature [°C]")
    plt.show()

The two matplotx ingredients are:

  • matplotx.styles.dufte_bar: A minimalistic style for bar plots
  • matplotx.show_bar_values: Show bar values directly at the bars

Extra styles

matplotx contains numerous extra color schemes, e.g., Dracula, Nord, gruvbox, and Solarized, the revised Tableau colors.

import matplotlib.pyplot as plt
import matplotx

# use everywhere:
plt.style.use(matplotx.styles.dracula)

# use with context:
with plt.style.context(matplotx.styles.dracula):
    pass

Other styles:

Contour plots for functions with discontinuities

plt.contour matplotx.contour(max_jump=1.0)

Matplotlib has problems with contour plots of functions that have discontinuities. The software has no way to tell discontinuities and very sharp, but continuous cliffs apart, and contour lines will be drawn along the discontinuity.

matplotx improves upon this by adding the parameter max_jump. If the difference between two function values in the grid is larger than max_jump, a discontinuity is assumed and no line is drawn. Similarly, min_jump can be used to highlight the discontinuity.

As an example, take the function imag(log(Z)) for complex values Z. Matplotlib's contour lines along the negative real axis are wrong.

import matplotlib.pyplot as plt
import numpy as np

import matplotx

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

X, Y = np.meshgrid(x, y)
Z = X + 1j * Y

vals = np.imag(np.log(Z))

# plt.contour(X, Y, vals, levels=[-2.0, -1.0, 0.0, 1.0, 2.0])  # draws wrong lines

matplotx.contour(X, Y, vals, levels=[-2.0, -1.0, 0.0, 1.0, 2.0], max_jump=1.0)
matplotx.discontour(X, Y, vals, min_jump=1.0, linestyle=":", color="r")

plt.gca().set_aspect("equal")
plt.show()

Relevant discussions:

License

This software is published under the MIT license.

Comments
  • Remove some typing hint to support older numpy ?

    Remove some typing hint to support older numpy ?

    Hello, I got an error ModuleNotFoundError: No module named 'numpy.typing' due to the typing hint from numpy.typing import ArrayLike.

    Would you mind remove this hint to support older numpy version like 1.19.* ? It seems no performance issue after remove it.

    opened by ProV1denCEX 5
  • Support for horizontal barchart

    Support for horizontal barchart

    This PR solves #30 by adding an alignment argument to show_bar_values defaulting to "vertical".

    I couldn't think of a robust way of determining the alignment automatically. Checking if the width of the bar is greater or lower than its height seemed a bit dodgy in some cases... I don't know. What do you think @nschloe ?

    Usage (adapted from README demo):

    import matplotlib.pyplot as plt
    import matplotx
    
    labels = ["Australia", "Brazil", "China", "Germany", "Mexico", "United\nStates"]
    vals = [21.65, 24.5, 6.95, 8.40, 21.00, 8.55]
    ypos = range(len(vals))
    
    
    with plt.style.context(matplotx.styles.dufte_bar):
        plt.barh(ypos, vals)
        plt.yticks(ypos, labels)
        matplotx.show_bar_values("{:.2f}", alignment="horizontal")
        plt.title("average temperature [°C]")
        plt.tight_layout()
        plt.show()
    

    Produces: Figure_1

    opened by RemDelaporteMathurin 3
  • Support for horizontal barchart

    Support for horizontal barchart

    matplotx.show_bar_values works perfectly with vertical bar charts but not with horizontal bar charts.

    These are often used with long text labels.

    import matplotlib.pyplot as plt
    import matplotx
    
    labels = ["Australia", "Brazil", "China", "Germany", "Mexico", "United\nStates"]
    vals = [21.65, 24.5, 6.95, 8.40, 21.00, 8.55]
    ypos = range(len(vals))
    
    with plt.style.context(matplotx.styles.dufte_bar):
        plt.barh(ypos, vals)
        plt.yticks(ypos, labels)
        matplotx.show_bar_values("{:.2f}")
        plt.title("average temperature [°C]")
        plt.tight_layout()
        plt.show()
    
    

    Produces: image

    I can write a PR and add a show_hbar_values() function that works with horizontal bar charts and produces: image

    Or it can also be an argument of matplotx.show_bar_value defaulting to "vertical" like show_bar_value(alignement="horizontal")

    What do you think @nschloe ?

    opened by RemDelaporteMathurin 2
  • Citation

    Citation

    Great package! Thank you so much it really helps!

    I will surely use this in my next paper/talk. How can I cite this package?

    Do you plan on adding a Zenodo DOI?

    Cheers Remi

    opened by RemDelaporteMathurin 2
  • Some styles are broken

    Some styles are broken

    Using the code example in the readme:

    import matplotlib.pyplot as plt
    import matplotx
    plt.style.use(matplotx.styles.ayu)
    

    I get this error:

    File ~/.conda/envs/.../lib/python3.10/site-packages/matplotlib/style/core.py:117, in use(style)
        115 for style in styles:
        116     if not isinstance(style, (str, Path)):
    --> 117         _apply_style(style)
        118     elif style == 'default':
        119         # Deprecation warnings were already handled when creating
        120         # rcParamsDefault, no need to reemit them here.
        121         with _api.suppress_matplotlib_deprecation_warning():
    
    File ~/.conda/envs/.../lib/python3.10/site-packages/matplotlib/style/core.py:62, in _apply_style(d, warn)
         61 def _apply_style(d, warn=True):
    ---> 62     mpl.rcParams.update(_remove_blacklisted_style_params(d, warn=warn))
    
    File ~/.conda/envs/.../lib/python3.10/_collections_abc.py:994, in MutableMapping.update(self, other, **kwds)
        992 if isinstance(other, Mapping):
        993     for key in other:
    --> 994         self[key] = other[key]
        995 elif hasattr(other, "keys"):
        996     for key in other.keys():
    
    File ~/.conda/envs/.../lib/python3.10/site-packages/matplotlib/__init__.py:649, in RcParams.__setitem__(self, key, val)
        647     dict.__setitem__(self, key, cval)
        648 except KeyError as err:
    --> 649     raise KeyError(
        650         f"{key} is not a valid rc parameter (see rcParams.keys() for "
        651         f"a list of valid parameters)") from err
    
    KeyError: 'dark is not a valid rc parameter (see rcParams.keys() for a list of valid parameters)'
    

    Lib versions:

    matplotlib-base           3.5.2           py310h5701ce4_1    conda-forge
    matplotx                  0.3.7                    pypi_0    pypi
    

    This happens with aura, ayu, github, gruvbox and others.

    Some of the themes working are: challenger_deep, dracula, dufte, nord, tab10

    opened by floringogianu 1
  • Support for subplots

    Support for subplots

    Related to the issue I opened. It seems that small changes already go quite a long way towards support for subplots. This does not yet work for the style.

    For the original code, everything was correctly calculated with the axes in mind, but then it was applied to plt instead of ax, even if an ax parameter was supplied for line_labels, it was still applied to plt.

    The code changes should have no effect when there are no subplots. When there are subplots, the code now offers better support.

    import matplotlib.pyplot as plt
    import matplotx
    import numpy as np
    
    # create data
    rng = np.random.default_rng(0)
    offsets = [1.0, 1.50, 1.60]
    labels = ["no balancing", "CRV-27", "CRV-27*"]
    names = ["Plot left", "Plot right"]
    x0 = np.linspace(0.0, 3.0, 100)
    y = [offset * x0 / (x0 + 1) + 0.1 * rng.random(len(x0)) for offset in offsets]
    
    fig, axes = plt.subplots(2,1)                                           
    
    for ax, name in zip(axes, names):                                                         
        with plt.style.context(matplotx.styles.dufte):
            for yy, label in zip(y, labels):
                ax.plot(x0, yy, label=label)                                
            ax.set_xlabel("distance [m]")                                   
        matplotx.ylabel_top(name)    
        matplotx.line_labels(ax=ax)
    

    Original code

    image

    New code

    image

    opened by mitchellvanzuijlen 1
  • dufte.legend allow plt.text kwargs

    dufte.legend allow plt.text kwargs

    To draw the legend dufte uses plt.text() https://github.com/nschloe/dufte/blob/main/src/dufte/main.py#L196

    plt.text() allows for additional kwargs to customize the text https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html

    If possible, could you loop through the additional text kwargs to allow for a higher customizable legend?

    opened by exc4l 0
  • Improper ylabel_top placement

    Improper ylabel_top placement

    I've been using matplotx.ylabel_top and just noticed an issue with the label placement after setting the y tick labels explicitly. A working example is below.

    import numpy as np
    from seaborn import scatterplot
    import matplotx
    
    rng = np.random.default_rng(42)
    x = rng.random(100)
    y = -2*x + rng.normal(0, 0.5, 100)
    ax = scatterplot(
        x=x,
        y=y
    )
    ax.set_yticks([0, -1, -2])
    matplotx.ylabel_top('Example\nLabel')
    

    example

    i'm using

    numpy==1.23.4
    seaborn==0.12.1
    matplotx==0.3.10
    
    opened by markmbaum 0
  • First example images not properly clickable in readme

    First example images not properly clickable in readme

    I just came across this project, looks really neat. Especially the smooth contourf got me curious.

    I've noticed in the readme that (at least on firefox) if I click any of the three images, the link that opens (even with the "open image in new tab" context menu option) is https://github.com/nschloe/matplotx/blob/main/tests/dufte_comparison.py. In contrast, the contourf images open just fine, for instance.

    I assume the reason for this is the enclosing a tag for the first example: https://github.com/nschloe/matplotx/blob/c767b08ea91492b1db9626b8b2c8786b4bc99458/README.md?plain=1#L39

    In case this is not just a firefox thing, I would recommend trying to make the first three images clickable on their own right.

    opened by adeak 0
  • Adapt `line_labels` for `PolyCollections`

    Adapt `line_labels` for `PolyCollections`

    I'm keen on making a PR to adapt line_labels to make it work with fill_between objects (PolyCollection)

    This would be the usage and output:

    import matplotlib.pyplot as plt
    import matplotx
    import numpy as np
    
    x = np.linspace(0, 1)
    y1 = np.linspace(1, 2)
    y2 = np.linspace(2, 4)
    
    plt.fill_between(x, y1, label="label1")
    plt.fill_between(x, y1, y2, label="label1")
    
    matplotx.label_fillbetween()
    plt.show()
    

    image

    @nschloe would you be interested in this feature?

    opened by RemDelaporteMathurin 0
  • Support for subplots

    Support for subplots

    Perhaps this is already implemented and I'm just unable to find it. I think this package in general is great; very easy to use and very beautiful. Thank you for your time making it.

    I'm unable to get matplotx working properly when using subplots. Adapting the Clean line plots (dufte) example to include two subplots (side-by-side, or one-below-the-other) appears not to work.

    import matplotlib.pyplot as plt
    import matplotx
    import numpy as np
    
    # create data
    rng = np.random.default_rng(0)
    offsets = [1.0, 1.50, 1.60]
    labels = ["no balancing", "CRV-27", "CRV-27*"]
    x0 = np.linspace(0.0, 3.0, 100)
    y = [offset * x0 / (x0 + 1) + 0.1 * rng.random(len(x0)) for offset in offsets]
    
    fig, axes = plt.subplots(2,1)                                           # add subplots
    
    for ax in axes:                                                         # Let's make two identical subplots
        with plt.style.context(matplotx.styles.dufte):
            for yy, label in zip(y, labels):
                ax.plot(x0, yy, label=label)                                # changed plt. to ax.
            ax.set_xlabel("distance [m]")                                   # changed plt. to ax.
            matplotx.ylabel_top("voltage [V]")                              # move ylabel to the top, rotate
            matplotx.line_labels()                                          # line labels to the right
            #plt.show()                                                     # Including this adds the 'pretty axis' below the subplots.                             
    

    image

    opened by mitchellvanzuijlen 2
Releases(v0.3.10)
Owner
Nico Schlömer
Mathematics, numerical analysis, scientific computing, Python. Always interested in new problems.
Nico Schlömer
Custom Plotly Dash components based on Mantine React Components library

Dash Mantine Components Dash Mantine Components is a Dash component library based on Mantine React Components Library. It makes it easier to create go

Snehil Vijay 239 Jan 08, 2023
Simple Python interface for Graphviz

Simple Python interface for Graphviz

Sebastian Bank 1.3k Dec 26, 2022
An open-source plotting library for statistical data.

Lets-Plot Lets-Plot is an open-source plotting library for statistical data. It is implemented using the Kotlin programming language. The design of Le

JetBrains 820 Jan 06, 2023
With Holoviews, your data visualizes itself.

HoloViews Stop plotting your data - annotate your data and let it visualize itself. HoloViews is an open-source Python library designed to make data a

HoloViz 2.3k Jan 04, 2023
Learn Data Science with focus on adding value with the most efficient tech stack.

DataScienceWithPython Get started with Data Science with Python An engaging journey to become a Data Scientist with Python TL;DR Download all Jupyter

Learn Python with Rune 110 Dec 22, 2022
CPG represent!

CoolPandasGroup CPG represent! Arianna Brandon Enne Luan Tracie Project requirements: use Pandas to clean and format datasets use Jupyter Notebook to

Enne 3 Feb 07, 2022
Render Jupyter notebook in the terminal

jut - JUpyter notebook Terminal viewer. The command line tool view the IPython/Jupyter notebook in the terminal. Install pip install jut Usage $jut --

Kracekumar 169 Dec 27, 2022
Flame Graphs visualize profiled code

Flame Graphs visualize profiled code

Brendan Gregg 14.1k Jan 03, 2023
Function Plotter: a simple application with GUI to plot mathematical functions

Function-Plotter Function Plotter is a simple application with GUI to plot mathe

Mohamed Nabawe 4 Jan 03, 2022
A Jupyter - Three.js bridge

pythreejs A Python / ThreeJS bridge utilizing the Jupyter widget infrastructure. Getting Started Installation Using pip: pip install pythreejs And the

Jupyter Widgets 844 Dec 27, 2022
A tool for automatically generating 3D printable STLs from freely available lidar scan data.

mini-map-maker A tool for automatically generating 3D printable STLs from freely available lidar scan data. Screenshots Tutorial To use this script, g

Mike Abbott 51 Nov 06, 2022
HiPlot makes understanding high dimensional data easy

HiPlot - High dimensional Interactive Plotting HiPlot is a lightweight interactive visualization tool to help AI researchers discover correlations and

Facebook Research 2.4k Jan 04, 2023
Draw datasets from within Jupyter.

drawdata This small python app allows you to draw a dataset in a jupyter notebook. This should be very useful when teaching machine learning algorithm

vincent d warmerdam 505 Nov 27, 2022
📊 Extensions for Matplotlib

📊 Extensions for Matplotlib

Nico Schlömer 519 Dec 30, 2022
A simple script that displays pixel-based animation on GitHub Activity

GitHub Activity Animator This project contains a simple Javascript snippet that produces an animation on your GitHub activity tracker. The project als

16 Nov 15, 2021
The open-source tool for building high-quality datasets and computer vision models

The open-source tool for building high-quality datasets and computer vision models. Website • Docs • Try it Now • Tutorials • Examples • Blog • Commun

Voxel51 2.4k Jan 07, 2023
Visualize the bitcoin blockchain from your local node

Project Overview A new feature in Bitcoin Core 0.20 allows users to dump the state of the blockchain (the UTXO set) using the command dumptxoutset. I'

18 Sep 11, 2022
Python package to Create, Read, Write, Edit, and Visualize GSFLOW models

pygsflow pyGSFLOW is a python package to Create, Read, Write, Edit, and Visualize GSFLOW models API Documentation pyGSFLOW API documentation can be fo

pyGSFLOW 21 Dec 14, 2022
A python script editor for napari based on PyQode.

napari-script-editor A python script editor for napari based on PyQode. This napari plugin was generated with Cookiecutter using with @napari's cookie

Robert Haase 9 Sep 20, 2022
Drug design and development team HackBio internship is a virtual bioinformatics program that introduces students and professional to advanced practical bioinformatics and its applications globally.

-Nyokong. Drug design and development team HackBio internship is a virtual bioinformatics program that introduces students and professional to advance

4 Aug 04, 2022