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 is Pygrr PolyArt, a program used for drawing custom Polygon models for your Pygrr project!

This is Pygrr PolyArt, a program used for drawing custom Polygon models for your Pygrr project!

Isaac 4 Dec 14, 2021
A package for plotting maps in R with ggplot2

Attention! Google has recently changed its API requirements, and ggmap users are now required to register with Google. From a user’s perspective, ther

David Kahle 719 Jan 04, 2023
Mattia Ficarelli 2 Mar 29, 2022
Open-questions - Open questions for Bellingcat technical contributors

Open questions for Bellingcat technical contributors These are difficult, long-term projects that would contribute to open source investigations at Be

Bellingcat 234 Dec 31, 2022
Tidy data structures, summaries, and visualisations for missing data

naniar naniar provides principled, tidy ways to summarise, visualise, and manipulate missing data with minimal deviations from the workflows in ggplot

Nicholas Tierney 611 Dec 22, 2022
Plotting library for IPython/Jupyter notebooks

bqplot 2-D plotting library for Project Jupyter Introduction bqplot is a 2-D visualization system for Jupyter, based on the constructs of the Grammar

3.4k Dec 30, 2022
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
Make your BSC transaction simple.

bsc_trade_history Make your BSC transaction simple. 中文ReadMe Background: inspired by debank ,Practice my hands on this small project Blog:Crypto-BscTr

foolisheddy 7 Jul 06, 2022
Automate the case review on legal case documents and find the most critical cases using network analysis

Automation on Legal Court Cases Review This project is to automate the case review on legal case documents and find the most critical cases using netw

Yi Yin 7 Dec 28, 2022
University of Missouri - Kansas City: CS451R: Capstone

CS451RC University of Missouri - Kansas City: CS451R: Capstone Installation cd git clone https://github.com/ala2q6/CS451RC.git cd CS451RC pip3 instal

Alex Arbuckle 1 Nov 17, 2021
Visualize tensors in a plain Python REPL using Sparklines

Visualize tensors in a plain Python REPL using Sparklines

Shawn Presser 43 Sep 03, 2022
Automatically generate GitHub activity!

Commit Bot Automatically generate GitHub activity! We've all wanted to be the developer that commits every day, but that requires a lot of work. Let's

Ricky 4 Jun 07, 2022
YOPO is an interactive dashboard which generates various standard plots.

YOPO is an interactive dashboard which generates various standard plots.you can create various graphs and charts with a click of a button. This tool uses Dash and Flask in backend.

ADARSH C 38 Dec 20, 2022
Python histogram library - histograms as updateable, fully semantic objects with visualization tools. [P]ython [HYST]ograms.

physt P(i/y)thon h(i/y)stograms. Inspired (and based on) numpy.histogram, but designed for humans(TM) on steroids(TM). The goal is to unify different

Jan Pipek 120 Dec 08, 2022
A set of three functions, useful in geographical calculations of different sorts

GreatCircle A set of three functions, useful in geographical calculations of different sorts. Available for PHP, Python, Javascript and Ruby. Live dem

72 Sep 30, 2022
Plotting library for IPython/Jupyter notebooks

bqplot 2-D plotting library for Project Jupyter Introduction bqplot is a 2-D visualization system for Jupyter, based on the constructs of the Grammar

3.4k Dec 29, 2022
An interactive dashboard built with python that enables you to visualise how rent prices differ across Sweden.

sweden-rent-dashboard An interactive dashboard built with python that enables you to visualise how rent prices differ across Sweden. The dashboard/web

Rory Crean 5 Dec 19, 2021
Define fortify and autoplot functions to allow ggplot2 to handle some popular R packages.

ggfortify This package offers fortify and autoplot functions to allow automatic ggplot2 to visualize statistical result of popular R packages. Check o

Sinhrks 504 Dec 23, 2022
Attractors is a package for simulation and visualization of strange attractors.

attractors Attractors is a package for simulation and visualization of strange attractors. Installation The simplest way to install the module is via

Vignesh M 45 Jul 31, 2022
Schema validation just got Pythonic

Schema validation just got Pythonic schema is a library for validating Python data structures, such as those obtained from config-files, forms, extern

Vladimir Keleshev 2.7k Jan 06, 2023