Matplotlib实现单画布绘制多个子图

最近研究Python数据分析,需要利用Matplotlib绘制图表,并将多个图表绘制在一张图中,经过一番折腾,利用matplotlib包下的subplot()函数即可实现此功能。

代码实现:

import matplotlib.pyplot as plt
import numpy as np

class Graph(object):
    def __init__(self):
        self.font = {
            'size': 13
        }

    plt.figure(figsize=(9, 6))
    plt.subplots_adjust(wspace=0.7, hspace=0.5)
    plt.rcParams['font.family'] = 'simhei'
    plt.rcParams['axes.unicode_minus'] = False

    def twinx(self):
        a1 = plt.subplot(231)
        plt.title('双纵轴折线图', fontdict=self.font)
        a1.plot(subjects, v1, label='v1')
        a1.set_ylabel('v1')
        a1.legend(loc='upper right', bbox_to_anchor=[-0.5, 0, 0.5, 1], fontsize=7)
        a2 = a1.twinx()
        a2.plot(subjects, v2, 'r--', label='v2')
        a2.set_ylabel('v2')
        a2.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7)

    def scatter(self):
        plt.subplot(232)
        plt.title('散点图', fontdict=self.font)
        x = range(50)
        y_jiangsu = [np.random.uniform(15, 25) for i in x]
        y_beijing = [np.random.uniform(5, 18) for i in x]
        plt.scatter(x, y_beijing, label='v1')
        plt.scatter(x, y_jiangsu, label='v2')
        plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7)

    def hist(self):
        plt.subplot(233)
        plt.title('直方图', fontdict=self.font)
        x = np.random.normal(size=100)
        plt.hist(x, bins=30)

    def bar_dj(self):
        plt.subplot(234)
        plt.title('堆积柱状图', fontdict=self.font)
        plt.bar(np.arange(len(v1)), v1, width=0.6, label='v1')
        for x, y in enumerate(v1):
            plt.text(x, y, y, va='top', ha='center')
        plt.bar(np.arange(len(v2)), v2, width=0.6, bottom=v1, label='v2')
        for x, y in enumerate(v2):
            plt.text(x, y + 60, y, va='bottom', ha='center')
        plt.ylim(0, 200)
        plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7)
        plt.xticks(np.arange(len(v1)), subjects)

    def bar_bl(self):
        plt.subplot(235)
        plt.title('并列柱状图', fontdict=self.font)
        plt.bar(np.arange(len(v1)), v1, width=0.4, color='tomato', label='v1')
        for x, y in enumerate(v1):
            plt.text(x - 0.2, y, y)
        plt.bar(np.arange(len(v2)) + 0.4, v2, width=0.4, color='steelblue', label='v2')
        for x, y in enumerate(v2):
            plt.text(x + 0.2, y, y)
        plt.ylim(0, 110)
        plt.xticks(np.arange(len(v1)), subjects)
        plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7)

    def barh(self):
        plt.subplot(236)
        plt.title('水平柱状图', fontdict=self.font)
        plt.barh(np.arange(len(v1)), v1, height=0.4, label='v1')
        plt.barh(np.arange(len(v2)) + 0.4, v2, height=0.4, label='v2')
        plt.legend(loc='upper left', bbox_to_anchor=[1, 0, 0.5, 1], fontsize=7)
        plt.yticks(np.arange(len(v1)), subjects)

def main():
    g = Graph()
    g.twinx()
    g.scatter()
    g.hist()
    g.bar_dj()
    g.bar_bl()
    g.barh()
    plt.savefig('坐标轴类.png')
    plt.show()

if __name__ == '__main__':
    subjects = ['语文', '数学', '英语', '物理', '化学']
    v1 = [77, 92, 83, 74, 90]
    v2 = [63, 88, 99, 69, 66]
    main() 

效果如下:
在这里插入图片描述

可以看到,一个画板上放了6个子图。达到了我们想要的效果。现在来解析刚刚的部分代码:

plt.figure(1):表示取第一块画板,一个画板就是一张图,如果你有多个画板,那么最后就会弹出多张图。

plt.subplot(231):221表示将画板划分为2行3列,然后取第1个区域。那么第几个区域是怎么界定的呢?这个规则遵循行优先数数规则.优先从行开始数,从左到右按顺序1234……然后再下一行。

参考资料:
python笔记:matplotlib的简单快速入门之多图合并(2)

Matplotlib的子图subplot的使用

使用matplotlib:subplot绘制多个子图

posted @ 2022-11-16 18:05  杨业壮  阅读(134)  评论(0编辑  收藏  举报