Поддерживать размер пикселя и соотношение сторон элементов в matplotlib - PullRequest
0 голосов
/ 29 октября 2018

После нескольких лет поиска решений всех моих проблем с кодированием на этом сайте, это мой первый пост с (насколько я могу судить) новым вопросом!

Я хочу создать несколько гистограмм из одного набора данных и сохранить их как отдельные изображения. Я хочу, чтобы размер изображения автоматически масштабировался, чтобы любой заданный объект (например, квадрат 1x1) имел одинаковый размер на каждом изображении.

Следующий код создает два таких изображения, в которых каждый элемент 1x1 имеет размер около 60x60 пикселей, пока все хорошо:

import matplotlib.pyplot as plt

def barchart(bars,size,title):
    hspace,vspace = (max(size)+1,len(size))

    fig = plt.figure(figsize=(hspace,vspace+1))
    fig.add_axes([0.2,0.2,0.6,0.6])
    plt.title(title)
    plt.axis('scaled')

    x_pos = xrange(vspace)
    plt.xlim(0,hspace)
    plt.ylim(-1,vspace)

    plt.barh(x_pos, size, height=1, align='center', alpha=0.5)
    plt.yticks(x_pos, bars)

    plt.savefig(title+'.png',bbox_inches='tight')
    plt.clf()

barchart(["1x1","A","B","C"],[1,3,5,2],"many short bars")

barchart(["1x1","A"],[1,17],"few long bars")

Но я бы хотел сделать это с другим соотношением сторон, например, чтобы каждый элемент 1x1 отображается как 60x30 пикселей на изображении. Есть ли замена для .axis('scaled'), которая это делает? Я попытался масштабировать ширину в figsize, xlim и обоих, а также в .add_axes() и нескольких ключевых словах в .axis(). Похоже, что все они по-разному влияют на окончательный масштаб и пропорции изображений.

Точный размер пикселя не имеет значения, будь то 60x30 или 66x33 или иным образом, если он одинаков для всех изображений.

1 Ответ

0 голосов
/ 30 октября 2018

Наконец-то разобрался с ответом с подсказками в комментарии выше и еще несколькими пробами и ошибками:

import matplotlib.pyplot as plt

def barchart(bars,size,title):
    hspace,vspace = (max(size)+1,len(size))

    AR = 0.5 # x-axis will be scaled to 50%
    fig = plt.figure(figsize=(AR*hspace,vspace+1)) 
    fig.add_axes([0.2,0.2,0.6,0.6])
    plt.xlim(0,hspace)
    plt.ylim(-1,vspace)

    plt.title(title)

    x_pos = xrange(vspace)

    plt.barh(x_pos, size, height=1, align='center', alpha=0.5)
    plt.yticks(x_pos, bars)

    plt.savefig(title+'.png',bbox_inches='tight')
    plt.clf()

barchart(["1x1","A","B","C"],[1,3,5,2],"many short bars")

barchart(["1x1","A"],[1,17],"few long bars")

Решение состояло в том, чтобы зафиксировать размер фигуры и пределы оси в одинаковых пропорциях и просто пропустить .axis('scaled'). Затем масштабируйте только ширину до требуемого коэффициента.

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