简体   繁体   English

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

[英]matplotlib subplots with same 'settings'

I'm plotting the same data in two different formats: log scale and linear scale. 我正在以两种不同的格式绘制相同的数据:对数比例和线性比例。

Basically I want to have exactly the same plot, but with different scales, one on the top of the other. 基本上我想要完全相同的情节,但有不同的尺度,一个在另一个的顶部。

What I have right now is this: 我现在拥有的是:

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^')

All 'settings' before plt.subplot are ignored. plt.subplot之前的所有'设置'都将被忽略。

I can get this to work the way I want, but I have to duplicate all the settings after each subplot declaration. 我可以按照我想要的方式工作,但是我必须在每个子图声明后复制所有设置。

Is there a way to do configure both subplots at once? 有没有办法一次配置两个子图?

The plt.* settings usually apply to matplotlib's current plot; plt.*设置通常适用于matplotlib的当前情节; with plt.subplot , you're starting a new plot, hence the settings no longer apply to it. 使用plt.subplot ,您将开始一个新的情节,因此设置不再适用于它。 You can share labels, ticks, etc., by going through the Axes objects associated with the plots ( see examples here ), but IMHO this would be overkill here. 您可以通过浏览与绘图关联的Axes对象来共享标签,刻度等等( 请参阅此处的示例 ),但恕我直言,这将是一种过度杀伤。 Instead, I would propose putting the common "styling" into one function and call that per plot: 相反,我建议将常用的“样式”放入一个函数中,并根据情节调用:

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^')

On a side note, you could root out more duplication by extracting your plot commands into such a function: 在旁注中,您可以通过将绘图命令提取到这样的函数中来根除更多重复:

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()

On another side note, it might suffice to put the title at the top of the figure (instead of over each plot), eg, using suptitle . 另一方面,将标题置于图的顶部(而不是在每个图上)可能就足够了,例如,使用suptitle Similary, it might be sufficient for the xlabel to only appear beneath the second plot: 类似地, 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()

Hans' answer is probably the recommended approach. 汉斯的答案可能是推荐的方法。 But in case you still want to go about copying the axis properties to another axis, here is a method I've found: 但是如果您仍想将轴属性复制到另一个轴,这是我发现的方法:

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()

在此输入图像描述

This lets you set a white-list for which properties to set, currently I have the title , xlabel and ylabel , but you can just use getp(ax1) to print out a list of all the available properties. 这允许您设置要设置属性的白名单,目前我有titlexlabelylabel ,但您可以使用getp(ax1)打印出所有可用属性的列表。

You can copy all of the properties using something like the following, but I recommend against it since some of the property settings will mess up the second plot. 您可以使用以下内容复制所有属性,但我建议不要使用它,因为某些属性设置会弄乱第二个图。 I've tried to use a black-list to exclude some, but you'll would need to fiddle with it to get it working: 我试图使用黑名单排除一些,但你需要摆弄它才能让它工作:

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

(The except/pass is to skip properties which are gettable, but not settable) except/pass是跳过可获取但不可设置的属性)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM