Я хотел бы создать квадратный график, используя несколько осей, используя make_axes_locateable
, как показано в документации matplotlib .Однако, хотя это работает на графиках, где данные x и y имеют одинаковый диапазон, оно не работает, когда диапазоны отличаются на несколько порядков.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
x = np.random.normal(512, 112, 240)
y = np.random.normal(0.5, 0.1, 240)
_, ax = plt.subplots()
divider = make_axes_locatable(ax)
xhax = divider.append_axes("top", size=1, pad=0.1, sharex=ax)
yhax = divider.append_axes("right", size=1, pad=0.1, sharey=ax)
ax.scatter(x, y)
xhax.hist(x)
yhax.hist(y, orientation="horizontal")
x0,x1 = ax.get_xlim()
y0,y1 = ax.get_ylim()
ax.set_aspect(abs(x1-x0)/abs(y1-y0))
plt.show()
Хотя в этом коде используется ответ set_aspect
, как в Как сделать квадрат рассеяния matplotlib? оси не изменены правильно, как показано здесь:

Я попытался исправить это с помощью:
ax.set_aspect(abs(x1-x0)/abs(y1-y0), share=True)
Но это привело к следующему:

Установка аспекта после вызова scatter и перед созданием двух осей гистограммы, казалось, не имела никакого эффекта, даже если кажется, что это было сделано в примере документации.Этот код работает, когда диапазон данных одинаков:

Обновление : одно из ключевых ограничений этого вопросаиспользовать make_axes_locateable
, а не GridSpec
, как описано в комментариях ниже.Проблема, над которой я работаю, заключается в создании функций построения, которые принимают объект Оси для работы и изменяют его, не зная фигуру или любые другие Оси на графике, как в следующем коде:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as grid
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
def joint_plot(x, y, ax=None):
"""
Create a square joint plot of x and y.
"""
if ax is None:
ax = plt.gca()
divider = make_axes_locatable(ax)
xhax = divider.append_axes("top", size=1, pad=0.1, sharex=ax)
yhax = divider.append_axes("right", size=1, pad=0.1, sharey=ax)
ax.scatter(x, y)
xhax.hist(x)
yhax.hist(y, orientation="horizontal")
x0,x1 = ax.get_xlim()
y0,y1 = ax.get_ylim()
ax.set_aspect(abs(x1-x0)/abs(y1-y0))
plt.sca(ax)
return ax, xhax, yhax
def color_plot(x, y, colors, ax=None):
if ax is None:
ax = plt.gca()
divider = make_axes_locatable(ax)
cbax = divider.append_axes("right", size="5%", pad=0.1)
sc = ax.scatter(x, y, marker='o', c=colors, cmap='RdBu')
plt.colorbar(sc, cax=cbax)
ax.set_aspect("equal")
plt.sca(ax)
return ax, cbax
if __name__ == "__main__":
_, axes = plt.subplots(nrows=2, ncols=2, figsize=(9,6))
# Plot 1
x = np.random.normal(100, 17, 120)
y = np.random.normal(0.5, 0.1, 120)
joint_plot(x, y, axes[0,0])
# Plot 2
x = np.random.normal(100, 17, 120)
y = np.random.normal(100, 17, 120)
c = np.random.normal(100, 17, 120)
color_plot(x, y, c, axes[0,1])
# Plot 3
x = np.random.normal(100, 17, 120)
y = np.random.normal(0.5, 0.1, 120)
c = np.random.uniform(0.0, 1.0, 120)
color_plot(x, y, c, axes[1,0])
# Plot 4
x = np.random.normal(0.5, 0.1, 120)
y = np.random.normal(0.5, 0.1, 120)
joint_plot(x, y, axes[1,1])
plt.tight_layout()
plt.show()

Этот вопрос расширяет такие вопросы, как Установить равный аспект на графике с помощью цветовой шкалы и Python, взаимодействие между осью ('квадрат') и set_xlim из-за ограничения только для осей.