如何获得matplotlib中子图的不同长度但相同比例的轴?

时间:2016-08-25 04:39:05

标签: python matplotlib

例如,如果我有这3个数据集来绘制:

a = np.arange(0,10,1)
b = np.arange(2,6,1)
c = np.arange(5,10,1)
显然,我不希望他们共享同一个轴,因为其中一些基本上只有一个大的空图表,在角落的某处有一些数据点。因此,我理想情况下会有不同大小的子图,但都具有相同的比例(即步骤1在所有子图上具有相同的长度)。我知道我可以通过设置图形的大小来手动完成此操作,但是对于更大数量的数据集或不那么好的数字,这将是一个真正的痛苦。但是通过搜索其他问题或文档,我找不到任何可能会在轴上设置固定距离的东西。请注意,我不是在问长宽比。纵横比可以不同,我只需要在轴上使用相同的比例。 (见下图,这有望说明我的问题。注意:不,我不需要在我的实际情节中使用比例尺,这是为了让您了解比例是如何相同的。) 感谢。

updated image

2 个答案:

答案 0 :(得分:1)

经过大量研究后,看起来没有任何简单的命令可以做到这一点。但首先,考虑每个子图的x和y值的范围及其比例和布局,GridSpec将完成这项工作。

因此,对于我们的示例,布局如问题中所示,即顶部的最大图片,下面彼此相邻的两个较小的图片。为了使它更容易,y范围对于所有这些都是相同的(但如果它不是我们将使用与x相同的计算)。现在,了解这种布局,我们可以创建一个网格。垂直跨度是20(因为我们有两行4个图,y范围是10),我们可能需要它们之间的一些空间用于轴标签,图例等,所以我们将添加额外的5.第一个图有x范围为10,但是,第二和第三个数字的范围为4和5,总共为9,我们可能还需要它们之间的一些空间,所以让我们再添加3个。因此,水平网格将跨越12个。因此,我们创建一个25 x 12的网格,并在此网格中拟合我们的图表,如下所示:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec

## GRIDSPEC INTRO - creating a grid to distribute the subplots with same scales and different sizes.
fig = plt.figure()
gs=gridspec.GridSpec(25,12)
## SUBPLOTS of GRIDSPEC
#the first (big) plot
axes1 = plt.subplot(gs[:10,:10])
ax1 = plt.plot(x,y) # plot some data here
ax1 = plt.xlim(1,10)
ax1 = plt.ylim(1,10)
# the second plot below the big one on the left
axes2 = plt.subplot(gs[15:,:4])
ax2 = plt.plot(x,y) # plot some data here
ax2 = plt.xlim(2,6)
ax2 = plt.ylim(1,10)
# the third plot - below the big one on the right
axes3 = plt.subplot(gs[15:,7:])
ax3 = plt.plot(x,y) # plot some data here
ax3 = plt.xlim(5,10)
ax3 = plt.ylim(1,10)
plt.show()

答案 1 :(得分:0)

一小时后好:

__author__ = 'madevelasco'

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd


def group(x, max, min, iters):
    total_range = max - min
    for i in range(0, iters):
        if (x > min + i*total_range/iters and x <= min + (i+1)*total_range/iters):
            return i



def newPlots():
    df = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y'])
    df.plot(x = 'x', y = 'y', kind = 'scatter', alpha=0.5)
    plt.show()

    ##Sort by the column you want
    df.sort_values(['x'], ascending=[False], inplace=True)
    result = df.reset_index(drop=True).copy()

    #Number of groups you want
    iterations = 3
    max_range = df['x'].max()
    min_range = df['x'].min()
    total_range = max_range - min_range

    result['group'] = result.apply(lambda x: group(x['x'], max_range, min_range, iterations ), axis=1)
    print(result)

    for x in range (0, iterations):

        lower = min_range + (x)*total_range/iterations
        upper = min_range + (1+x)*total_range/iterations
        new = result[result['group'] == x]
        new.plot(x = 'x', y = 'y', kind = 'scatter', alpha=0.3)
        axes = plt.gca()
        axes.set_xlim([lower, upper])
        axes.set_ylim([df['y'].min(),df['y'].max()])
        plt.show()

if __name__ == '__main__':
    newPlots()

我用熊猫来做这件事。老实说,可视化的想法是将所有数据放在一个图形中,但不要像这样分开。为了保持您的约会的想法,甚至为了可读性,应该修复其中一个轴。我在编辑之间做了

所有点的图像

General

子图

first subplot

second subplot

third subplot