具有相同'设置'的matplotlib子图

leo*_*leo 6 python 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^')
Run Code Online (Sandbox Code Playgroud)

plt.subplot之前的所有'设置' 都将被忽略.

我可以按照我想要的方式工作,但是我必须在每个子图声明后复制所有设置.

有没有办法一次配置两个子图?

Han*_*ans 13

这些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^')
Run Code Online (Sandbox Code Playgroud)

在旁注中,您可以通过将绘图命令提取到这样的函数中来根除更多重复:

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()
Run Code Online (Sandbox Code Playgroud)

另一方面,将标题置于图的顶部(而不是在每个图上)可能就足够了,例如,使用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()
Run Code Online (Sandbox Code Playgroud)


Chr*_*Zeh 5

汉斯的回答可能是推荐的方法。但是,如果您仍然想将轴属性复制到另一个轴,这是我发现的一种方法:

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这使您可以为要设置的属性设置白名单,目前我有title,xlabelylabel,但您可以只使用它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
Run Code Online (Sandbox Code Playgroud)

(这except/pass是跳过可获取但不可设置的属性)