matplotlib: управление положением метки оси Y с несколькими двойными субплотами - PullRequest
0 голосов
/ 15 февраля 2019

Я написал скрипт на Python на основе matplotlib, который генерирует кривые на основе общей временной шкалы.Количество кривых, имеющих одну и ту же ось х на моем графике, может варьироваться от 1 до 6 в зависимости от пользовательских параметров.Для каждого из нанесенных данных используются разные шкалы y и для рисования требуется другая ось.В результате мне может понадобиться нарисовать до 5 разных осей Y справа от моего графика.В другом посте я нашел способ сместить положение осей при добавлении новых, но у меня все еще есть две проблемы:

  1. Как контролировать положение нескольких осей, чтобы галочкаметки не перекрываются?
  2. Как контролировать положение каждой метки оси так, чтобы она располагалась вертикально внизу каждой оси?И как сохранить это выравнивание при изменении размера окна отображения, увеличении и т. Д. Мне, вероятно, нужно написать некоторый код, который сначала запросит положение оси, а затем директиву, которая поместит метку относительно этой позиции, ноЯ действительно понятия не имею, как это сделать.

Я не могу поделиться всем своим кодом, потому что он слишком большой, но я получил его из кода в в этом примере .Я изменил этот пример, добавив один дополнительный график и одну дополнительную ось, чтобы более точно соответствовать тому, что намеревается сделать в моем сценарии.

import matplotlib.pyplot as plt


def make_patch_spines_invisible(ax):
    ax.set_frame_on(True)
    ax.patch.set_visible(False)
    for sp in ax.spines.values():
        sp.set_visible(False)


fig, host = plt.subplots()
fig.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()
par3 = host.twinx()

# Offset the right spine of par2.  The ticks and label have already been
# placed on the right by twinx above.
par2.spines["right"].set_position(("axes", 1.2))
# Having been created by twinx, par2 has its frame off, so the line of its
# detached spine is invisible.  First, activate the frame but make the patch
# and spines invisible.
make_patch_spines_invisible(par2)
# Second, show the right spine.
par2.spines["right"].set_visible(True)

par3.spines["right"].set_position(("axes", 1.4))
make_patch_spines_invisible(par3)
par3.spines["right"].set_visible(True)

p1, = host.plot([0, 1, 2], [0, 1, 2], "b-", label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], "r-", label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], "g-", label="Velocity")
p4, = par3.plot([0,0.5,1,1.44,2],[100, 102, 104, 108, 110], "m-", label="Acceleration")

host.set_xlim(0, 2)
host.set_ylim(0, 2)
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)

host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")
par3.set_ylabel("Acceleration")

host.yaxis.label.set_color(p1.get_color())
par1.yaxis.label.set_color(p2.get_color())
par2.yaxis.label.set_color(p3.get_color())
par3.yaxis.label.set_color(p4.get_color())

tkw = dict(size=4, width=1.5)
host.tick_params(axis='y', colors=p1.get_color(), **tkw)
par1.tick_params(axis='y', colors=p2.get_color(), **tkw)
par2.tick_params(axis='y', colors=p3.get_color(), **tkw)
par3.tick_params(axis='y', colors=p4.get_color(), **tkw)
host.tick_params(axis='x', **tkw)

lines = [p1, p2, p3, p4]

host.legend(lines, [l.get_label() for l in lines])

# fourth y axis is not shown unless I add this line
plt.tight_layout()
plt.show()

При выполнении этого я получаю следующий график: вывод изприведенный выше сценарий

На этом рисунке вопрос 2 выше означает, что я бы хотел, чтобы метки оси Y «Температура», «Скорость», «Ускорение» отображались непосредственно под каждой из соответствующих осей.

Заранее благодарим за любую помощь.

С уважением,

L.

1 Ответ

0 голосов
/ 22 февраля 2019

Для меня сработало предложение ImportanceOfBeingErnest об использовании текста (со строкой вроде

host.text (1.2, 0, «Скорость», ha = «влево», va = «вверх»), вращение = 90, transform = host.transAxes))

вместо того, чтобы пытаться контролировать положение метки.

...