nodapic
nodapic

Reputation: 325

Underlining Text in Python/Matplotlib

I couldn't find another thread or documentation on this topic - has anyone ever been successful underlining in pythons matplotlib package? The syntax I am using is something like this for all the other attributes:

plt.text(0.05, 0.90, 'Parameters: ', fontsize=12)

However, I can't figure out how to underline this text short of actually coding a line into the file.

Thoughts?

Upvotes: 12

Views: 22667

Answers (2)

Charles Colley
Charles Colley

Reputation: 21

This is an old question, but I actually had a need for underlining text that didn't use LaTeX so I figured I'd follow up with the solution that I came up with, for others who may encounter the same issue.

Ultimately my solution finds a bounding box for the text object in question and then uses the arrowprop arguments in the annotation command in order to draw a straight line underneath the text. There are some caveats with this approach, but overall I find it quite flexible because then you can customize the underline however you'd like.

An example of my solution is as follows:

import matplotlib.pyplot as plt 
import numpy as np 

def test_plot():
    f = plt.figure()
    ax = plt.gca()
    ax.plot(np.sin(np.linspace(0,2*np.pi,100)))

    text1 = ax.annotate("sin(x)", xy=(.7,.7), xycoords="axes fraction")   
    underline_annotation(text1)

    text2 = ax.annotate("sin(x)", xy=(.7,.6), xycoords="axes fraction",
                        fontsize=15, ha="center")
    underline_annotation(text2)

    plt.show()

def underline_annotation(text):
    f, ax = plt.gcf(), plt.gca()

    # text isn't drawn immediately and must be given a renderer if one isn't cached.
    # tightbbox return units are in 'figure pixels', transformed to 'figure fraction'.
    tb = text.get_tightbbox(f.canvas.get_renderer()).transformed(f.transFigure.inverted())

    # Use arrowprops to draw a straight line anywhere on the axis.
    ax.annotate('', xy=(tb.xmin,tb.y0), xytext=(tb.xmax,tb.y0),
                xycoords="figure fraction",
                arrowprops=dict(arrowstyle="-", color='k'))

which produces: underlined annotated sin example

One thing to note is that if you want to pad the underline, or control the line thickness (note that the line thickness is the same for both annotations) you'll have to do it manually within the 'underline_annotation' command, but this is pretty easy to do by passing more arguments through the arrowprops dict, or augmenting the location of where the line is being drawn.

Upvotes: 2

Chris
Chris

Reputation: 46316

Matplotlib can use LaTeX to handle all text, see this page of the documnetation for more information. The command for underlining text in LaTeX is simply \underline. From the docstring of one of the example scripts:

You can use TeX to render all of your matplotlib text if the rc parameter text.usetex is set. This works currently on the agg and ps backends, and requires that you have tex and the other dependencies described at http://matplotlib.sf.net/matplotlib.texmanager.html properly installed on your system. The first time you run a script you will see a lot of output from tex and associated tools. The next time, the run may be silent, as a lot of the information is cached in ~/.tex.cache

So as a simple example we can do

import matplotlib.pyplot as plt
from matplotlib import rc

rc('text', usetex=True)

plt.sunplot(111)

plt.text(0.05, 0.90, r'\underline{Parameters}: ', fontsize=12)

to get underlined text.

Upvotes: 20

Related Questions