Flexitext is a Python library that makes it easier to draw text with multiple styles in Matplotlib

Overview

PyPI - Version Build Status Code style: black codecov

Introduction

Flexitext is a Python library that makes it easier to draw text with multiple styles in Matplotlib. This library is inspired and influenced by the R package ggtext.

Installation

Flexitext requires a working Python interpreter (3.7+). This library can be installed using pip:

pip install flexitext

Alternatively, you can install the development version from GitHub:

pip install git+https://github.com/tomicapretto/flexitext.git

Flexitext only requires Matplotlib version 3.4 or higher.

Overview

Albeit being inspired on ggtext, Flexitext does not use HTML, CSS, or Markdown to specify text styles. On the contrary, it implements a tag-based styling that looks similar to HTML tags, but is not exactly like HTML. These formatted strings consist of three components:

  • An opening tag that defines the styles to apply.
  • The text to be styled.
  • A closing tag, indicating the extent to which the styles in the opening tag apply.

Let's see an example:

This is blue text and this is regular text" ">
"
    
     This is blue text and this is regular text"
    
  • is the opening tag. Styles are key-value pairs separated by :. Multiple styles are separated by commas.
  • This is blue text is the text block. This text is going to be drawn using a font size of 16 and blue color.
  • is the closing tag. Only the text within the opening and the closing tags is formatted.

And finally we have and this is regular text. This is going to be drawn using the default style because it is not contained within any formatting tags.

Examples

The easiest way to use flexitext is through the flexitext function.

import matplotlib as mpl
import matplotlib.pyplot as plt

from flexitext import flexitext

mpl.rcParams['figure.facecolor'] = 'w'
fig, ax = plt.subplots(figsize=(9, 6))

text = "Normal text"
ax.text(0.5, 0.7, text, size=24, ha="center")

text = "
   
    Bold text"
   
flexitext(0.5, 0.6, text, ha="center")

text = "
   
    Italic text"
   
flexitext(0.5, 0.5, text, ha="center")

text = "
   
    Bold and 
    
     italic too!"
    
   
flexitext(0.5, 0.4, text, ha="center");

png

Styles can be nested

It is much easier now" flexitext(0.5, 0.6, text, ha="center"); ">
fig, ax = plt.subplots(figsize=(9, 6))

text = "
      
       It is much 
       
        easier 
        
         now"
        
       
      
flexitext(0.5, 0.6, text, ha="center");

png

A more convoluted example:

You can write using\n" " multiple formats,\nand linebreaks\n\n" " also bold text\n\n" " and why not italics too" ) fig, ax = plt.subplots(figsize=(9, 6)) flexitext(0.5, 0.5, text, ha="center", ma="center"); ">
text = (
    "
         
          You can write using
          \n"
         
    "
         
          multiple formats,
          \nand linebreaks
          \n
          \n"
         
    "
         
          also 
          
           bold text
           \n
           \n"
          
         
    "
         
          and why not 
          
           italics too"
          
         
)

fig, ax = plt.subplots(figsize=(9, 6))
flexitext(0.5, 0.5, text, ha="center", ma="center");

png

Use the figure fraction coordinates to write a formatted title.

A great chart showing\n" " the values for the " " blues and the reds" ) flexitext(0.025, 0.8, text, va="bottom", xycoords="figure fraction"); ">
fig, ax = plt.subplots(figsize=(9, 6))
fig.subplots_adjust(top=0.8, left=0.025)

x = [1, 2, 3]
y_blue = [2, 2.7, 4.5]
y_red = [1, 3, 2.5]


ax.scatter(x, y_blue, color="royalblue", s=120)
ax.scatter(x, y_red, color="crimson", s=120)

# Add flexitext
text = (
    "
        
         
          A 
          
           great chart showing
           \n"
          
         
        
    "
        
         the values for the "
        
    "
        
         blues and the 
         
          reds"
         
        
)
flexitext(0.025, 0.8, text, va="bottom", xycoords="figure fraction");

png

Notes

Flexitext only supports the following styles

  • alpha
  • backgroundcolor
  • color
  • family
  • name
  • size
  • style
  • weight

See Matplotlib's documentation for more information about their meaning and available values.

Flexitext logo is created with Flexitext and Matplotlib (see here).

Related work

  • highlight_text: Flexitext and highlight_text have similar goals. This library, highlight_text, allows you to customize more aspects of the highlighted text, such as the bounding box of the text or the border of the text with path effects. On the other hand, it requires you to pass a styles as a separated list of dictionaries instead of within the text.
Comments
  • Added Framework::Matplotlib to setup.cfg

    Added Framework::Matplotlib to setup.cfg

    Was having trouble finding this package, couldn't remember the name. Figure this would have helped me and make it slightly more discoverable. Also, please consider adding this package to https://matplotlib.org/mpl-third-party/

    opened by story645 6
  • About flexitext parameter

    About flexitext parameter "ha" and "va"

    Hello author, the ha and va parameters in the flexitext library do not seem to be consistent with those in ax.text. Set ha='center' in ax.text, the text of different lines will be aligned in the center, but this parameter seems to be invalid in flexitext (The alignment result is not quite consistent with the text). Setting ha='center' in flexitext is still left-aligned? The following is my code:

    `

    fig.subplots_adjust(top=0.8, left=0.025)
    x = [1, 2, 3]
    y_blue = [2, 2.7, 4.5]
    y_red = [1, 3, 2.5]
    ax.scatter(x, y_blue, color="royalblue", s=120)
    ax.scatter(x, y_red, color="crimson", s=120)
    # Add flexitext
    text = (
        "<name:Montserrat><size:24>A <weight:bold>great chart</> showing</>\n"
        "<size:18>the values for the "
        "<color:royalblue, weight:bold>blues</> and the <color:crimson, weight:bold>reds</></></>"
    )
    flexitext(0.5, 0.5, text, va="center", ha='center', ax=ax); #xycoords="figure fraction"
    ax.text(0.5, 0.2, text, va="center", ha='center',transform=ax.transAxes)
    plt.show()
    

    `

    image Is there a parameter in flexitext that can horizontally align the text of different lines in the center (even if the text size is inconsistent)?

    Thank you.

    opened by JiWenzheng 4
  • plt.subplots?

    plt.subplots?

    Hi, I want to use Flexitext to draw the text of subplots, but I find that parameter transform = axes. TransAxes is not supported. Is it possible to specify coordinate system in the future?

    opened by JiWenzheng 2
  • Several improvements and fixes

    Several improvements and fixes

    • Modify dev requirements and sort them alphabetically.
    • Add pyproject.toml where we set the length of the black formatter.
    • Flexitext now parses floats like 2. as 2.0. Previously it tried to parse two different numbers, resulting in an error.
    • Increase coverage to 100%.
    • Added changelog.
    opened by tomicapretto 1
  • Incompatibility with `constrained` layout?

    Incompatibility with `constrained` layout?

    I think I found a bug when using Matplotlib's constrained layout and flexitext. In this case, flexitext makes the layout very inconsistent if the window is resized, and different from what is expected. Here's some example code:

    import matplotlib.pyplot as plt
    from flexitext import flexitext
    
    fig, ax = plt.subplots(1, 2, figsize=(12, 6), layout="constrained")
    
    text1 = "<size:42, name:Carlito>Some<color:#11557c, weight:bold> text</></>"
    text2 = "<size:36, name:Lato, color:royalblue><weight:bold>Here</> too</>"
    
    flexitext(0.5, 0.5, text1, ha="center", ax=ax[0])
    flexitext(0.5, 0.5, text2, ha="center", ax=ax[1])
    
    fig.set_facecolor("w")
    # fig.savefig("example.png", dpi=300)
    plt.show()
    

    Here is a screenshot of the result: Screenshot from 2022-11-08 14-34-27

    After maximizing the window, and going back to its original size, the layout has changed: Screenshot from 2022-11-08 14-34-36

    Maximizing again, and going back to the original size: Screenshot from 2022-11-08 14-34-40

    Note that uncommenting fig.savefig("example.png", dpi=300) triggers a canvas draw and improves the layout for the given window size, but it doesn't seem to be what the layout would be without the flexitext.

    Expected layout: Screenshot from 2022-11-08 14-39-11

    Layout after a canvas draw: Screenshot from 2022-11-08 14-39-23

    What do you think?

    opened by guillaumedavidphd 7
Releases(v0.2.0)
  • v0.2.0(Mar 6, 2022)

    This release includes two relevant fixes/improvements:

    • Add mva argument to flexitext() which controls the vertical alignment of individual texts within the outer text box.
    • Improve backgroundcolor behavior. The backgroundcolor of one piece of text does not overlap other pieces of text by default now.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Sep 21, 2021)

This repository contains a streaming Dataflow pipeline written in Python with Apache Beam, reading data from PubSub.

Sample streaming Dataflow pipeline written in Python This repository contains a streaming Dataflow pipeline written in Python with Apache Beam, readin

Israel Herraiz 9 Mar 18, 2022
A minimalistic wrapper around PyOpenGL to save development time

glpy glpy is pyOpenGl wrapper which lets you work with pyOpenGl easily.It is not meant to be a replacement for pyOpenGl but runs on top of pyOpenGl to

Abhinav 9 Apr 02, 2022
Keir&'s Visualizing Data on Life Expectancy

Keir's Visualizing Data on Life Expectancy Below is information on life expectancy in the United States from 1900-2017. You will also find information

9 Jun 06, 2022
It's an application to calculate I from v and r. It can also plot a graph between V vs I.

Ohm-s-Law-Visualizer It's an application to calculate I from v and r using Ohm's Law. It can also plot a graph between V vs I. Story I'm doing my Unde

Sihab Sahariar 1 Nov 20, 2021
PanGraphViewer -- show panenome graph in an easy way

PanGraphViewer -- show panenome graph in an easy way Table of Contents Versions and dependences Desktop-based panGraphViewer Library installation for

16 Dec 17, 2022
Extensible, parallel implementations of t-SNE

openTSNE openTSNE is a modular Python implementation of t-Distributed Stochasitc Neighbor Embedding (t-SNE) [1], a popular dimensionality-reduction al

Pavlin Poličar 1.1k Jan 03, 2023
Profile and test to gain insights into the performance of your beautiful Python code

Profile and test to gain insights into the performance of your beautiful Python code View Demo - Report Bug - Request Feature QuickPotato in a nutshel

Joey Hendricks 138 Dec 06, 2022
An interactive dashboard for visualisation, integration and classification of data using Active Learning.

AstronomicAL An interactive dashboard for visualisation, integration and classification of data using Active Learning. AstronomicAL is a human-in-the-

45 Nov 28, 2022
DrawBot lets you draw images taken from the internet on Skribbl.io, Gartic Phone and Paint

DrawBot You don't speak french? No worries, english translation is over here. C'est quoi ? DrawBot est un logiciel codé par V2F qui va prendre possess

V2F 205 Jan 01, 2023
Plot, scatter plots and histograms in the terminal using braille dots

Plot, scatter plots and histograms in the terminal using braille dots, with (almost) no dependancies. Plot with color or make complex figures - similar to a very small sibling to matplotlib. Or use t

Tammo Ippen 207 Dec 30, 2022
Farhad Davaripour, Ph.D. 1 Jan 05, 2022
100 Days of Code The Complete Python Pro Bootcamp for 2022

100-Day-With-Python 100 Days of Code - The Complete Python Pro Bootcamp for 2022. In this course, I spend with python language over 100 days, and I up

Rajdip Das 8 Jun 22, 2022
Lightweight, extensible data validation library for Python

Cerberus Cerberus is a lightweight and extensible data validation library for Python. v = Validator({'name': {'type': 'string'}}) v.validate({

eve 2.9k Dec 27, 2022
Application for viewing pokemon regional variants.

Pokemon Regional Variants Application Application for viewing pokemon regional variants. Run The Source Code Download Python https://www.python.org/do

Michael J Bailey 4 Oct 08, 2021
In-memory Graph Database and Knowledge Graph with Natural Language Interface, compatible with Pandas

CogniPy for Pandas - In-memory Graph Database and Knowledge Graph with Natural Language Interface Whats in the box Reasoning, exploration of RDF/OWL,

Cognitum Octopus 34 Dec 13, 2022
Scientific measurement library for instruments, experiments, and live-plotting

PyMeasure scientific package PyMeasure makes scientific measurements easy to set up and run. The package contains a repository of instrument classes a

PyMeasure 445 Jan 04, 2023
Project coded in Python using Pandas to look at changes in chase% for batters facing a pitcher first time through the order vs. thrid time

Project coded in Python using Pandas to look at changes in chase% for batters facing a pitcher first time through the order vs. thrid time

Jason Kraynak 1 Jan 07, 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
Package managers visualization

Software Galaxies This repository combines visualizations of major software package managers. All visualizations are available here: http://anvaka.git

Andrei Kashcha 1.4k Dec 22, 2022
A Python Library for Self Organizing Map (SOM)

SOMPY A Python Library for Self Organizing Map (SOM) As much as possible, the structure of SOM is similar to somtoolbox in Matlab. It has the followin

Vahid Moosavi 497 Dec 29, 2022