Reputation: 1035
I am plotting two time series and computing varies indices for them.
How to write these indices for these plots outside the plot using annotation
or text
in python?
Below is my code
import matplotlib.pyplot as plt
obs_graph=plt.plot(obs_df['cms'], '-r', label='Observed')
plt.legend(loc='best')
plt.hold(True)
sim_graph=plt.plot(sim_df['cms'], '-g', label="Simulated")
plt.legend(loc='best')
plt.ylabel('Daily Discharge (m^3/s)')
plt.xlabel('Year')
plt.title('Observed vs Simulated Daily Discharge')
textstr = 'NSE=%.2f\nRMSE=%.2f\n'%(NSE, RMSE)
# print textstr
plt.text(2000, 2000, textstr, fontsize=14)
plt.grid(True)
plt.show()
I want to print teststr
outside the plots. Here is the current plot:
Upvotes: 52
Views: 134906
Reputation: 639
bbox
If you want the box to be outside the plot, and not to be cropped when saving the figure, you have to use bbox
. Here is a minimal working example:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1, figsize=(8, 4))
x = np.random.normal(loc=15.0, scale=2.0, size=10000)
mu = np.mean(x)
sigma = np.std(x)
my_text = '- Estimated quantities -\n'
my_text += fr'$\mu=${mu:.3f}' + '\n' + fr'$\sigma=${sigma:.3f}'
ax.hist(x, bins=100)
props = dict(boxstyle='round', facecolor='grey', alpha=0.15) # bbox features
ax.text(1.03, 0.98, my_text, transform=ax.transAxes, fontsize=12, verticalalignment='top', bbox=props)
plt.tight_layout()
plt.show()
More details here: https://matplotlib.org/3.3.4/gallery/recipes/placing_text_boxes.html
Upvotes: 4
Reputation: 8297
According to Matplotlib version 3.3.4 documentation, you can use the figtext method:
matplotlib.pyplot.figtext(x, y, s, fontdict=None, **kwargs)
or in your case
plt.figtext(0.02, 0.5, textstr, fontsize=14)
It seems to give the same result as one of the answer by @ImportanceOfBeingErnest, i.e. :
plt.gcf().text(0.02, 0.5, textstr, fontsize=14)
I have used both commands with Matplobib version 3.3.1.
Upvotes: 4
Reputation: 339660
It's probably best to define the position in figure coordinates instead of data coordinates as you'd probably not want the text to change its position when changing the data.
Using figure coordinates can be done either by specifying the figure transform (fig.transFigure
)
plt.text(0.02, 0.5, textstr, fontsize=14, transform=plt.gcf().transFigure)
or by using the text
method of the figure instead of that of the axes.
plt.gcf().text(0.02, 0.5, textstr, fontsize=14)
In both cases the coordinates to place the text are in figure coordinates, where (0,0)
is the bottom left and (1,1)
is the top right of the figure.
At the end you still may want to provide some extra space for the text to fit next to the axes, using plt.subplots_adjust(left=0.3)
or so.
Upvotes: 116
Reputation: 23647
Looks like the text is there but it lies outside of the figure boundary.
Use subplots_adjust()
to make room for the text:
import matplotlib.pyplot as plt
textstr = 'NSE=%.2f\nRMSE=%.2f\n'%(1, 2)
plt.xlim(2002, 2008)
plt.ylim(0, 4500)
# print textstr
plt.text(2000, 2000, textstr, fontsize=14)
plt.grid(True)
plt.subplots_adjust(left=0.25)
plt.show()
Upvotes: 8