Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove matplotlib text plot border

How to remove matplotlib text border, while making the text be in the first plane, in front of the plotted line?

import matplotlib.pyplot as plt

x = [1, 2, 3]
y = [1, 2, 3]

plt.plot(x, y)
plt.text(2.85, 2.9, 'label', bbox={'facecolor':'white', 'alpha':1, 'pad':10})

plt.show()
like image 707
gcamargo Avatar asked Dec 17 '14 17:12

gcamargo


People also ask

How do I remove the margins in MatPlotLib?

The python plotting library matplotlib will by default add margins to any plot that it generates. They can be reduced to a certain degree through some options of savefig() , namely bbox_inches='tight' and pad_inches=0 .

How do I get rid of Xticks in MatPlotLib?

To remove the ticks on the x-axis, tick_params() method accepts an attribute named bottom, and we can set its value to False and pass it as a parameter inside the tick_params() function. It removes the tick on the x-axis.

How do I get rid of top and right border in MatPlotLib?

To hide the border (aka "spine"): ax. set_frame_on(False) or ax. spines['top']. set_visible(False)


1 Answers

Are you asking how to make the text more visible without adding the box behind it? If so, have a look at the last couple of examples.


Controlling the drawing order

The text is already in front of the line, it's just hard to distinguish the two. However, in general, the order of the elements is controlled by the zorder kwarg.

To demonstrate this, I'll change the colors and size of the font in your example to make things a touch more clear:

import matplotlib.pyplot as plt

x = [1, 2, 3]
y =[1, 2, 3]

fig, ax = plt.subplots()
ax.plot(x, y, linewidth=10, color='yellow')
ax.text(2, 2, 'label', ha='center', size=72)

# For the moment, hide everything else...
ax.axis('off')
fig.tight_layout()

plt.show()

enter image description here

If we decrease the z-order of the text below that of the line or increase the zorder of the line above that of the text, the line will be in front. By default, most plotted data types have a zorder of 1, while annotations such as text have a zorder of 3, if I recall correctly. It's just the relative values of zorder that matter, though. In other words, it doesn't matter whether we do ax.text(..., zorder=0) or ax.plot(..., zorder=4), we'll get the same result.

import matplotlib.pyplot as plt

x = [1, 2, 3]
y =[1, 2, 3]

fig, ax = plt.subplots()
ax.plot(x, y, linewidth=10, color='yellow')
ax.text(2, 2, 'label', ha='center', size=72, zorder=0)

# For the moment, hide everything else...
ax.axis('off')
fig.tight_layout()

plt.show()

enter image description here


A more subtle box for clearer labels

However, what you're probably wanting to accomplish is a cleaner way to display the label and the line together.

In that case, you have several different options.

Let's go back to your original example. You can display the box, behind the text, but remove the edge color on the box. So, if you add 'edgecolor':'none' to the dict in the bbox kwarg, you'll get something similar to this:

import matplotlib.pyplot as plt

x = [1, 2, 3]
y =[1, 2, 3]

plt.plot(x, y)
plt.text(2.85, 2.9, 'label',
         bbox={'facecolor':'white', 'edgecolor':'none', 'pad':10})

plt.show()

enter image description here

Or as an example of what it would look like using the earlier code snippet with a yellow line:

enter image description here

Using a stroke effect for clear labels

However, this doesn't look as nice if we have more than just a simple line. Therefore, you might also want to consider using a stroke path effect:

import matplotlib.pyplot as plt
import matplotlib.patheffects as pe

x = [1, 2, 3]
y =[1, 2, 3]

fig, ax = plt.subplots()
ax.plot(x, y, linewidth=10, color='yellow')
ax.text(2, 2, 'label', ha='center', size=72,
       path_effects=[pe.withStroke(linewidth=10, foreground='w')])

# For the moment, hide everything else...
ax.axis('off')
fig.tight_layout()
fig.set(facecolor='white')

plt.show()

enter image description here

like image 187
Joe Kington Avatar answered Sep 22 '22 21:09

Joe Kington