Подтвердить что ты не робот

Matplotlib: добавление вторых осей() с прозрачным фоном?

Определить данные

x = np.linspace(0,2*np.pi,100)
y = 2*np.sin(x)

Plot

fig = plt.figure()
ax = plt.axes()
fig.add_subplot(ax)
ax.plot(x,y)

Добавить вторую ось

newax = plt.axes(axisbg='none')

Дает мне ValueError: Unknown element o, хотя он делает то же самое, что и я описываю. Я также вижу, что это работает (без ошибок), чтобы сделать то же самое:

newax = plt.axes()
fig.add_subplot(newax)
newax.set_axis_bgcolor('none')

Тем не менее, он меняет цвет фона исходного рисунка "серый" (или какой-либо фон рисунка)? Я не понимаю, поскольку я думал, что это сделает newax прозрачным, за исключением осей и рамки вокруг фигуры. Даже если я переключу порядок, то же самое:

plt.close('all')
fig = plt.figure()
newax = plt.axes()
fig.add_subplot(newax)
newax.set_axis_bgcolor('none')
ax = plt.axes()
fig.add_subplot(ax)
ax.plot(x,y)

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

Что здесь происходит?

4b9b3361

Ответ 1

На самом деле вы не добавляете новые оси.

Matplotlib обнаруживает, что уже есть сюжет в этой позиции и возвращает его вместо нового объекта осей.

(Проверьте это сами. ax и newax будут тем же самым объектом.)

Вероятно, нет причин, по которым вы захотите, но вот как вы это сделаете.

(Кроме того, не вызывайте newax = plt.axes(), а затем вызывайте fig.add_subplot(newax). Вы делаете то же самое дважды.)

Изменить: с более новыми ( >= 1,2, я думаю?) версиями matplotlib вы можете выполнить то же самое, что и пример ниже, используя label kwarg to fig.add_subplot. Например. newax = fig.add_subplot(111, label='some unique string')

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

# If you just call `plt.axes()` or equivalently `fig.add_subplot()` matplotlib  
# will just return `ax` again. It _won't_ create a new axis unless we
# call fig.add_axes() or reset fig._seen
newax = fig.add_axes(ax.get_position(), frameon=False)

ax.plot(range(10), 'r-')
newax.plot(range(50), 'g-')
newax.axis('equal')

plt.show()

enter image description here

Конечно, это выглядит ужасно, но это то, о чем вы просите...

Я предполагаю из ваших предыдущих вопросов, что вы просто хотите добавить вторую ось x? Если это так, это совсем другое дело.

Если вы хотите связать оси y, тогда сделайте что-то вроде этого (несколько многословное...):

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
newax = ax.twiny()

# Make some room at the bottom
fig.subplots_adjust(bottom=0.20)

# I'm guessing you want them both on the bottom...
newax.set_frame_on(True)
newax.patch.set_visible(False)
newax.xaxis.set_ticks_position('bottom')
newax.xaxis.set_label_position('bottom')
newax.spines['bottom'].set_position(('outward', 40))

ax.plot(range(10), 'r-')
newax.plot(range(21), 'g-')

ax.set_xlabel('Red Thing')
newax.set_xlabel('Green Thing')

plt.show()

enter image description here

Если вы хотите иметь скрытую, несвязанную ось y и совершенно новую ось x, тогда вы сделали бы что-то вроде этого:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)

newax = fig.add_axes(ax.get_position())
newax.patch.set_visible(False)
newax.yaxis.set_visible(False)

for spinename, spine in newax.spines.iteritems():
    if spinename != 'bottom':
        spine.set_visible(False)

newax.spines['bottom'].set_position(('outward', 25))

ax.plot(range(10), 'r-')

x = np.linspace(0, 6*np.pi)
newax.plot(x, 0.001 * np.cos(x), 'g-')

plt.show()

enter image description here

Обратите внимание, что значения оси y для любого объекта, нанесенного на newax, никогда не отображаются.

Если бы вы захотели, вы могли бы сделать еще один шаг вперед и иметь независимые оси x и y (я не совсем уверен, что бы это было, но выглядит аккуратно...):

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2, right=0.85)

newax = fig.add_axes(ax.get_position())
newax.patch.set_visible(False)

newax.yaxis.set_label_position('right')
newax.yaxis.set_ticks_position('right')

newax.spines['bottom'].set_position(('outward', 35))

ax.plot(range(10), 'r-')
ax.set_xlabel('Red X-axis', color='red')
ax.set_ylabel('Red Y-axis', color='red')

x = np.linspace(0, 6*np.pi)
newax.plot(x, 0.001 * np.cos(x), 'g-')

newax.set_xlabel('Green X-axis', color='green')
newax.set_ylabel('Green Y-axis', color='green')


plt.show()

enter image description here

Вы также можете добавить дополнительный позвоночник в нижней части графика. Иногда это проще, особенно если вам не нужны тики или числовые вещи. Не слишком сильно подключить один из моих собственных ответов, но вот пример этого: Как построить несколько осей X или Y в matplotlib?

Как последнее, обязательно посмотрите на примеры паразитных осей, если вы хотите, чтобы разные оси x и y были связаны через конкретное преобразование.