I am trying to put two text-boxes side-by-side in the top-right corner of a matplotlib figure. I followed this tutorial on text-alignment and can place one text-box in the top-right corner. But I do not know how to add a second text-box such that the right-edge of the top-left box intersects the left-edge of the top-right box.
The code to output run the minimal working example is below:
import numpy as np
import matplotlib.pyplot as plt
# data
x = np.linspace(-10, 10, 51)
shrink_factors = np.linspace(1, 0, x.size)
y1 = shrink_factors*np.sin(np.exp(-x))
y2 = shrink_factors*np.cos(np.exp(-x))
# get plot parameters
xlim = [np.min(x), np.max(x)]
ylim = [0, 1.125*np.max([np.max(y1), np.max(y2)])]
facecolors = ("red", "blue")
(color1, color2) = facecolors
label1 = "Label 1"
label2 = "Label 2"
text1 = "RED 1"
text2 = "BLUE 2"
text_background_color = "gainsboro"
text_size = 12
figsize = (12, 7)
# figsize = (7, 12)
# initialize plot
fig, ax = plt.subplots(
figsize=figsize)
# plot data
ax.plot(x, y1, color=color1, label=label1)
ax.plot(x, y2, color=color2, label=label2)
ax.grid(color="black", linestyle=":", alpha=0.3)
ax.set_xlim(xlim)
ax.set_ylim(ylim)
fig.legend(mode="expand", loc="lower center", ncol=2)
# add text-boxes side-by-side
text_box1 = ax.text(0.95, 0.95, text1,
color=color1,
fontsize=text_size,
horizontalalignment="right",
verticalalignment="top",
transform=ax.transAxes)
text_box1.set_bbox({"facecolor": text_background_color, "edgecolor": "black"})
text_box1_pos = text_box1.get_position()
text_box2 = ax.text(text_box1_pos[0], 0.95, text2,
color=color2,
fontsize=text_size,
horizontalalignment="left",
verticalalignment="top",
transform=ax.transAxes)
text_box2.set_bbox({"facecolor": text_background_color, "edgecolor": "black"})
# finish plot
plt.show()
plt.close()
I had encountered a similar issue some time back. Here is what I did... This is based on some of the info provide in another post here. Given below are the updates to your code...
0.9
, so that both the labels are within the plottransAxes
so that we have same coordinates everywhere. More info here. Note the bb_datacoords
will now have the x and y coordinates of the first textbox#text_box1_pos = text_box1.get_position() --> You code, not required anymore
r = fig.canvas.get_renderer()
transf = ax.transAxes.inverted()
bb = text_box1.get_window_extent(renderer = r)
bb_datacoords = bb.transformed(transf)
bb_datacoords.x1+0.01, #text_box1_pos[0],
Note that, as mentioned in the above SO answer, the exact position is not known till the plot is done, so there is a small delta of 0.01 that you can add to make them non-overlapping. You can increase it (to say 0.02) if you want to see a small gap in between the two boxes.
The resulting plot looks like this... Hope this helps.