Использование twiny () во вставке в Matplotlib - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь добавить вторую ось X к своему врезанному графику, который я создал с помощью InsetPosition из mpl_toolkits.axes_grid1.inset_locator (например, https://scipython.com/blog/inset-plots-in-matplotlib/),, но вторая ось X, кажется, не показываети я не могу понять, почему.

Это код, который я использую:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca()

from mpl_toolkits.axes_grid1.inset_locator import InsetPosition
zoom_ax = fig.add_axes([0,0,1,1])
zoom_ax.set_axes_locator(InsetPosition(ax, [0.6, 0.6, 0.3, 0.3]))

def expansion(z):
    return 1.0 / (1.0 + z)

def redshift(a):
    return 1.0 / a - 1.0

def tick_function(a):
    return ["%.1f" % z for z in redshift(a)]

z_ticks = np.array([0.0, 0.5, 1.0, 2.0, 5.0, 100.0])
a_ticks = expansion(z_ticks)

twin_ax = zoom_ax.twiny()
twin_ax.set_xticks(a_ticks)
twin_ax.set_xticklabels(tick_function(a_ticks))
twin_ax.set_xlim(zoom_ax.get_xlim())

xmin, xmax = 0.0, 1.0
x = np.linspace(xmin, xmax)
zoom_ax.plot(x, np.sin(x))
zoom_ax.set_xlim(xmin, xmax)

plt.show()

Это дает следующий график - без какой-либо оси twiny():

result of the above code

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Может быть, вы захотите использовать обычный mpl_toolkits.axes_grid1.inset_locator.inset_axes, который отлично работает даже с двойникованием.

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca()

from mpl_toolkits.axes_grid1.inset_locator import inset_axes
zoom_ax = inset_axes(ax, "100%", "100%", bbox_to_anchor=[0.6, 0.6, 0.3, 0.3], 
                     bbox_transform=ax.transAxes)

def expansion(z):
    return 1.0 / (1.0 + z)

def redshift(a):
    return 1.0 / a - 1.0

def tick_function(a):
    return ["%.1f" % z for z in redshift(a)]

z_ticks = np.array([0.0, 0.5, 1.0, 2.0, 5.0, 100.0])
a_ticks = expansion(z_ticks)

twin_ax = zoom_ax.twiny()
twin_ax.set_xticks(a_ticks)
twin_ax.set_xticklabels(tick_function(a_ticks))
twin_ax.set_xlim(zoom_ax.get_xlim())

xmin, xmax = 0.0, 1.0
x = np.linspace(xmin, xmax)
zoom_ax.plot(x, np.sin(x))
zoom_ax.set_xlim(xmin, xmax)

plt.show()

С помощью matplotlib 3.0 вы можете упростить это еще больше, используя Axes.inset_axes:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca()

zoom_ax = ax.inset_axes([0.6, 0.6, 0.3, 0.3])

def expansion(z):
    return 1.0 / (1.0 + z)

def redshift(a):
    return 1.0 / a - 1.0

def tick_function(a):
    return ["%.1f" % z for z in redshift(a)]

z_ticks = np.array([0.0, 0.5, 1.0, 2.0, 5.0, 100.0])
a_ticks = expansion(z_ticks)

twin_ax = zoom_ax.twiny()
twin_ax.set_xticks(a_ticks)
twin_ax.set_xticklabels(tick_function(a_ticks))
twin_ax.set_xlim(zoom_ax.get_xlim())

xmin, xmax = 0.0, 1.0
x = np.linspace(xmin, xmax)
zoom_ax.plot(x, np.sin(x))
zoom_ax.set_xlim(xmin, xmax)

plt.show()

Результат визуально одинаков:

enter image description here

0 голосов
/ 07 декабря 2018

Очевидно, twiny() имеет проблемы с axes_locator, используемым zoom_ax (не знаю, является ли это ошибкой или нет).Если вы повторите команду set_axes_locator() для twin_ax, результирующий график будет выглядеть так, как я ожидал (я пропустил команды галочек осей, чтобы сделать мой пример графика более понятным):

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca()

from mpl_toolkits.axes_grid1.inset_locator import InsetPosition
zoom_ax = fig.add_axes([0,0,1,1])
zoom_ax.set_axes_locator(InsetPosition(ax, [0.6, 0.6, 0.3, 0.3]))

def expansion(z):
    return 1.0 / (1.0 + z)

def redshift(a):
    return 1.0 / a - 1.0

def tick_function(a):
    return ["%.1f" % z for z in redshift(a)]

z_ticks = np.array([0.0, 0.5, 1.0, 2.0, 5.0, 100.0])
a_ticks = expansion(z_ticks)

twin_ax = zoom_ax.twiny()
##twin_ax.set_xticks(a_ticks)
##twin_ax.set_xticklabels(tick_function(a_ticks))
twin_ax.set_xlim(zoom_ax.get_xlim())

xmin, xmax = 0.0, 1.0
x = np.linspace(xmin, xmax)
zoom_ax.plot(x, np.sin(x))
zoom_ax.set_xlim(xmin, xmax)

##the extra lines
twin_ax.set_axes_locator(InsetPosition(ax, [0.6, 0.6, 0.3, 0.3]))
x2 = np.linspace(xmin, 2*xmax)
twin_ax.plot(x2,np.cos(x2),'r')
twin_ax.set_xlim(xmin, 2*xmax)

plt.show()

Это приведет кследующий участок:

result of the above code

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...