Я пытаюсь разместить два текстовых поля рядом в правом верхнем углу рисунка matplotlib. Я следовал этому руководству по выравниванию текста и могу разместить одно текстовое поле в правом верхнем углу. Но я не знаю, как добавить второе текстовое поле, чтобы правый край верхнего левого поля пересекал левый край верхнего правого поля.
Ниже приведен код для вывода минимального рабочего примера:
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()






Вы хотите выровнять по правому краю левое поле по левому значению x правого поля. Итак, вам нужно нарисовать прямоугольники вокруг текстовых полей. Они дополняются значением pad, масштабируемым с помощью масштабного коэффициента мутации. Чтобы получить эти значения, вам сначала нужно нарисовать фигуру (вы можете сделать это без рендеринга, чтобы немного ускорить).
Вот минимальный пример, предполагающий, что оба текста используют один и тот же (по умолчанию) отступ:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
bbox_kwds = dict(fc = "gainsboro", ec = "black")
text_box1 = ax.text(0.95, 0.95, "RIGHT", ha = "right", va = "top", transform=ax.transAxes, bbox=bbox_kwds)
fig.draw_without_rendering()
pad = text_box1.get_bbox_patch().get_boxstyle().pad * text_box1.get_bbox_patch().get_mutation_scale()
x = ax.transAxes.inverted().transform(text_box1.get_bbox_patch().get_window_extent().p0 - [pad, 0])[0]
text_box2 = ax.text(x, 0.95, "LEFT", ha = "right", va = "top", transform=ax.transAxes, bbox=bbox_kwds)
Я столкнулся с подобной проблемой некоторое время назад. Вот что я сделал... Это основано на некоторой информации, представленной в другом посте здесь. Ниже приведены обновления вашего кода...
0.9, чтобы обе метки находились в пределах графика.transAxes, чтобы у нас везде были одинаковые координаты. Подробнее здесь. Обратите внимание, что bb_datacoords теперь будет иметь координаты x и y первого текстового поля.#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],
Обратите внимание, что, как упоминалось в приведенном выше ответе SO, точное положение неизвестно до тех пор, пока график не будет готов, поэтому есть небольшая дельта 0,01, которую вы можете добавить, чтобы они не перекрывались. Вы можете увеличить его (скажем, 0,02), если хотите увидеть небольшой зазор между двумя прямоугольниками.
Результирующий сюжет выглядит так... Надеюсь, это поможет.