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)

NW 2022 Hackathon Project by Angelique Clara Hanzel, Aryan Sonik, Damien Fung, Ramit Brata Biswas

Spiral-Data-Visualizer NW 2022 Hackathon Project by Angelique Clara Hanzell, Aryan Sonik, Damien Fung, Ramit Brata Biswas Description This project vis

Damien Fung 2 Jan 16, 2022
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
A simple python script using Numpy and Matplotlib library to plot a Mohr's Circle when given a two-dimensional state of stress.

Mohr's Circle Calculator This is a really small personal project done for Department of Civil Engineering, Delhi Technological University (formerly, D

Agyeya Mishra 0 Jul 17, 2021
trade bot connected to binance API/ websocket.,, include dashboard in plotly dash to visualize trades and balances

Crypto trade bot 1. What it is Trading bot connected to Binance API. This project made for fun. So ... Do not use to trade live before you have backte

G 3 Oct 07, 2022
🎨 Python Echarts Plotting Library

pyecharts Python ❤️ ECharts = pyecharts English README 📣 简介 Apache ECharts (incubating) 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达

pyecharts 13.1k Jan 03, 2023
A central task in drug discovery is searching, screening, and organizing large chemical databases

A central task in drug discovery is searching, screening, and organizing large chemical databases. Here, we implement clustering on molecular similarity. We support multiple methods to provide a inte

NVIDIA Corporation 124 Jan 07, 2023
CLAHE Contrast Limited Adaptive Histogram Equalization

A simple code to process images using contrast limited adaptive histogram equalization. Image processing is becoming a major part of data processig.

Happy N. Monday 4 May 18, 2022
Data Visualizations for the #30DayChartChallenge

The #30DayChartChallenge This repository contains all the charts made for the #30DayChartChallenge during the month of April. This project aims to exp

Isaac Arroyo 7 Sep 20, 2022
Python library that makes it easy for data scientists to create charts.

Chartify Chartify is a Python library that makes it easy for data scientists to create charts. Why use Chartify? Consistent input data format: Spend l

Spotify 3.2k Jan 04, 2023
Data Analysis: Data Visualization of Airlines

Data Analysis: Data Visualization of Airlines Anderson Cruz | London-UK | Linkedin | Nowa Capital Project: Traffic Airlines Airline Reporting Carrier

Anderson Cruz 1 Feb 10, 2022
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
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
Piglet-shaders - PoC of custom shaders for Piglet

Piglet custom shader PoC This is a PoC for compiling Piglet fragment shaders usi

6 Mar 10, 2022
Python Data. Leaflet.js Maps.

folium Python Data, Leaflet.js Maps folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js

6k Jan 02, 2023
Shaded 😎 quantile plots

shadyquant 😎 This python package allows you to quantile and plot lines where you have multiple samples, typically for visualizing uncertainty. Your d

Mehrad Ansari 13 Sep 29, 2022
A tool for creating Toontown-style nametags in Panda3D

Toontown-Nametag Toontown-Nametag is a tool for creating Toontown Online/Toontown Rewritten-style nametags in Panda3D. It contains a function, createN

BoggoTV 2 Dec 23, 2021
Pyan3 - Offline call graph generator for Python 3

Pyan takes one or more Python source files, performs a (rather superficial) static analysis, and constructs a directed graph of the objects in the combined source, and how they define or use each oth

Juha Jeronen 235 Jan 02, 2023
Mathematical learnings with Lean, for those of us who wish we knew more of both!

Lean for the Inept Mathematician This repository contains source files for a number of articles or posts aimed at explaining bite-sized mathematical c

Julian Berman 8 Feb 14, 2022
Simple addon for snapping active object to mesh ground

Snap to Ground Simple addon for snapping active object to mesh ground How to install: install the Python file as an addon use shortcut "D" in 3D view

Iyad Ahmed 12 Nov 07, 2022
Python toolkit for defining+simulating+visualizing+analyzing attractors, dynamical systems, iterated function systems, roulette curves, and more

Attractors A small module that provides functions and classes for very efficient simulation and rendering of iterated function systems; dynamical syst

1 Aug 04, 2021