Как установить одинаковое соотношение сторон для сюжетов в matplotlib - PullRequest
0 голосов
/ 22 октября 2019

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

Похоже, что есть много вопросов по этому поводу, но в примерах, похоже, удобно иметь одинаковые оси для всех вспомогательных участков. В любом случае ни один из найденных мной вариантов не помог мне.

Я пробовал следующее

import numpy as np
import matplotlib.pyplot as plt

xdata = np.arange(0,2,.01)
ydata1 = xdata
ydata2 = xdata ** 2

fig, ax = plt.subplots(1,2)

ax[0].plot(xdata,ydata1)
ax[1].plot(xdata,ydata2)

ax[0].set_aspect(.5)
ax[1].set_aspect(.5)
plt.show(fig)

plots

Однако,Похоже, что matplotlib использует данные осей x и y для определения соотношения сторон, а поскольку оси y имеют разную протяженность, субплоты получаются разными. Это супер странно для меня. Как сделать так, чтобы у них было одинаковое физическое соотношение сторон?

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

РЕДАКТИРОВАТЬ Итак, я хочу, чтобы оба вспомогательных сюжета имели одинаковое соотношение сторон в человеческом смысле, то есть отношение шириныпоказатель высоты одинаков для обоих. Например, в Mathematica я бы достиг этого, просто установив атрибут AspectRatio:

xdata = Range[0, 2, .01];
ydata1 = {#, #} & /@ xdata;
ydata2 = {#, #^2} & /@ xdata;
fig = GraphicsRow[
   ListLinePlot[#, AspectRatio -> 1/GoldenRatio, Frame -> True, 
      ImageSize -> 300] & /@ {ydata1, ydata2}];
Export["fig.png", fig]

Made by Mathematica

Ответы [ 2 ]

2 голосов
/ 22 октября 2019

Краткий ответ: используйте аргумент ключевого слова figsize при создании подзаговоров:

import numpy as np
import matplotlib.pyplot as plt

xdata = np.arange(0,2,.01)
ydata1 = xdata
ydata2 = xdata ** 2

fig = plt.figure(figsize=(10,6))
ax = fig.subplots(1,2)

ax[0].plot(xdata,ydata1)
ax[1].plot(xdata,ydata2)

# Squares
ax[0].plot([0,1,1,0],[0,0,1,1])
ax[1].plot([0,1,1,0],[0,0,1,1])

plt.show(fig)

figsize - это кортеж в дюймах с первым элементом в качестве ширины в x-направление, второй элемент, как ширина в направлении у.

Это относится ко всей фигуре;вам нужно настроить его, чтобы получить подходящую форму для ваших участков.

enter image description here

Более длинный ответ: .set_aspect(num) устанавливаетОтношение оси Y к оси X для каждого графика.

Итак, когда вы использовали .set_aspect(.5) на каждой оси, вы сказали matplotlib перенастроить каждую ось так, чтобы ось Y была в 0,5 раза больше. как ось х. Это означает, что квадрат 1x1 на самом деле выглядит как прямоугольник на каждом графике:

import numpy as np
import matplotlib.pyplot as plt

xdata = np.arange(0,2,.01)
ydata1 = xdata
ydata2 = xdata ** 2

fig, ax = plt.subplots(1,2)

ax[0].plot(xdata,ydata1)
ax[1].plot(xdata,ydata2)

# Squares
ax[0].plot([0,1,1,0],[0,0,1,1])
ax[1].plot([0,1,1,0],[0,0,1,1])

ax[0].set_aspect(.5)
ax[1].set_aspect(.5)
plt.show(fig)

Вот почему ваши графики имеют разные формы;пределы оси отличаются , но вы установили размер фигур на обоих графиках равным одинаковых .

enter image description here

1 голос
/ 22 октября 2019

Вопрос не совсем ясен относительно желаемого результата. Возможно, вы хотите иметь фиксированный аспект данных без изменения осей?

import numpy as np
import matplotlib.pyplot as plt

xdata = np.arange(0,2,.01)
ydata1 = xdata
ydata2 = xdata ** 2

fig, ax = plt.subplots(1,2)

ax[0].plot(xdata,ydata1)
ax[1].plot(xdata,ydata2)

ax[0].set_aspect(.5, adjustable="datalim")
ax[1].set_aspect(.5, adjustable="datalim")
plt.show()

enter image description here

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