Search code examples
pythonmatplotlibannotationslimitword-wrap

Set the limits for text wrapping


I am trying to generate a plot having four quarters, each having some text saying something about that quarter. However, when I am trying to wrap the text I don't know how to set the limits for text. For example, in the attached figure, I want to limit the text to x=0. However, it is going until the end of x-axis limits. Please find attached the code and corresponding plot the code is generating.

import matplotlib
%matplotlib inline
import matplotlib.pyplot as plt

import numpy as np
from textwrap import wrap

font = {'size': 22}
matplotlib.rc('font', **font)
fig = plt.figure(figsize=(8, 8))
plt.axis([-10, 10, -10, 10])

ax = plt.gca()

ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')

ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

plt.xlabel('Energy ($kWh$)')
ax.xaxis.set_label_coords(0.85, .48)
ax.xaxis.set_ticks_position('bottom')
ax.set_xlim(-10, 10)
ax.xaxis.set_ticks([])

plt.ylabel('Discomfort ($\%$)', rotation=0)
ax.yaxis.set_label_coords(0.7, 0.01)
ax.yaxis.set_ticks_position('left')
ax.set_ylim(-10, 10)
ax.yaxis.set_ticks([])

ax.annotate(
    'Reference Point', xy=(0, 0), xycoords='data',
    xytext=(-10, 2), textcoords='data', wrap=True,
    arrowprops=dict(facecolor='black'))

t = "This is a really long string that I'd rather have wrapped so that 
it doesn't go outside of the figure, but if it's long enough it will go 
off the top or bottom!"

ax.text(-10, 3.5, t, ha='left', wrap=True, fontsize=20)
plt.tight_layout()
plt.savefig('sample.png')

Text should be limited to x=0


Solution

  • As can be seen in the auto wrap demo, wrapping happens at the figure limits. While this is not very comfortable, and I can imagine many cases, where this would not help at all, here, it allows to wrap the text by choosing the correct alignment.

    ax.text(0.49, 0.98, t, ha='right',va="top", wrap=True, 
            fontsize=20, transform=ax.transAxes)
    ax.text(0.51, 0.98, t, ha='left',va="top", wrap=True, 
            fontsize=20, transform=ax.transAxes)
    ax.text(0.49, 0.49, t, ha='right',va="top", wrap=True, 
            fontsize=20, transform=ax.transAxes)
    

    enter image description here