Подзаголовки matplotlib с одинаковыми «настройками»

Я рисую одни и те же данные в двух разных форматах: логарифмическом масштабе и линейном масштабе.

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

То, что у меня есть прямо сейчас, это:

import matplotlib.pyplot as plt

# These are the plot 'settings'
plt.xlabel('Size')
plt.ylabel('Time(s)');
plt.title('Matrix multiplication')

plt.xticks(xl, rotation=30, size='small')
plt.grid(True)

# Settings are ignored when using two subplots

plt.subplot(211)
plt.plot(xl, serial_full, 'r--')
plt.plot(xl, acc, 'bs')
plt.plot(xl, cublas, 'g^')

plt.subplot(212)
plt.yscale('log')
plt.plot(xl, serial_full, 'r--')
plt.plot(xl, acc, 'bs')
plt.plot(xl, cublas, 'g^')

Все «настройки» перед plt.subplot игнорируются.

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

Есть ли способ настроить оба подзаговора одновременно?


person leo    schedule 18.10.2012    source источник


Ответы (2)


Настройки plt.* обычно применяются к текущему графику matplotlib; с plt.subplot вы начинаете новый график, поэтому настройки больше не применяются к нему. Вы можете обмениваться метками, отметками и т. д., пройдя через Axes. объекты, связанные с графиками (см. примеры здесь), но ИМХО здесь было бы излишним. Вместо этого я бы предложил поместить общий «стиль» в одну функцию и вызвать ее для каждого сюжета:

def applyPlotStyle():
    plt.xlabel('Size')
    plt.ylabel('Time(s)');
    plt.title('Matrix multiplication')

    plt.xticks(range(100), rotation=30, size='small')
    plt.grid(True)

plt.subplot(211)
applyPlotStyle()
plt.plot(xl, serial_full, 'r--')
plt.plot(xl, acc, 'bs')
plt.plot(xl, cublas, 'g^')

plt.subplot(212)
applyPlotStyle()
plt.yscale('log')
plt.plot(xl, serial_full, 'r--')
plt.plot(xl, acc, 'bs')
plt.plot(xl, cublas, 'g^')

Кстати, вы можете исключить дублирование, извлекая свои сюжетные команды в такую ​​функцию:

def applyPlotStyle():
    plt.xlabel('Size')
    plt.ylabel('Time(s)');
    plt.title('Matrix multiplication')

    plt.xticks(range(100), rotation=30, size='small')
    plt.grid(True)

def plotSeries():
    applyPlotStyle()
    plt.plot(xl, serial_full, 'r--')
    plt.plot(xl, acc, 'bs')
    plt.plot(xl, cublas, 'g^')

plt.subplot(211)
plotSeries()

plt.subplot(212)
plt.yscale('log')
plotSeries()

С другой стороны, может быть достаточно поместить заголовок вверху рисунка (а не над каждым графиком), например, используя suptitle. Точно так же может быть достаточно, чтобы xlabel отображался только под вторым графиком:

def applyPlotStyle():
    plt.ylabel('Time(s)');

    plt.xticks(range(100), rotation=30, size='small')
    plt.grid(True)

def plotSeries():
    applyPlotStyle()
    plt.plot(xl, serial_full, 'r--')
    plt.plot(xl, acc, 'bs')
    plt.plot(xl, cublas, 'g^')

plt.suptitle('Matrix multiplication')
plt.subplot(211)
plotSeries()

plt.subplot(212)
plt.yscale('log')
plt.xlabel('Size')
plotSeries()

plt.show()
person Hans    schedule 18.10.2012

Ответ Ганса, вероятно, является рекомендуемым подходом. Но если вы все еще хотите скопировать свойства оси на другую ось, вот метод, который я нашел:

fig = figure()
ax1 = fig.add_subplot(2,1,1)
ax1.plot([1,2,3],[4,5,6])
title('Test')
xlabel('LabelX')
ylabel('Labely')

ax2 = fig.add_subplot(2,1,2)
ax2.plot([4,5,6],[7,8,9])


for prop in ['title','xlabel','ylabel']:
    setp(ax2,prop,getp(ax1,prop))

show()
fig.show()

введите здесь описание изображения

Это позволяет вам установить белый список, для которого нужно установить свойства, в настоящее время у меня есть title, xlabel и ylabel, но вы можете просто использовать getp(ax1), чтобы распечатать список всех доступных свойств.

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

insp = matplotlib.artist.ArtistInspector(ax1)
props = insp.properties()
for key, value in props.iteritems():
    if key not in ['position','yticklabels','xticklabels','subplotspec']:
        try:
            setp(ax2,key,value)
        except AttributeError:
            pass

(except/pass - пропускать свойства, которые можно получить, но нельзя установить)

person Chris Zeh    schedule 18.10.2012
comment
Я отредактировал ваш блок try, чтобы он не обнаруживал непредвиденных ошибок. (редактирование находится в очереди на проверку.) - person Joooeey; 16.01.2018