Matplotlib绘制饼图时用图例显示数据,防止饼图上数据重叠

文章目录

  • 1. 常规作图
  • 2. 巧设图例
  • 完整代码

对于任意一个字典形式的数据绘制饼图的代码如下:

1. 常规作图

import matplotlib.pyplot as plt

import numpy as np
import pandas as pd
import random


def get_random():
    return "".join(random.sample('zyxwvutsrqponmlkjihgfedcba', np.random.random_integers(3, 10)))


def plot_pie(dict_value: dict):
    keys = list(dict_value.keys())
    values = list(dict_value.values())
    plt.pie(values, labels=keys)
    plt.legend()
    plt.show()


def main():
    series = pd.Series(np.random.randint(1, 10, size=20))
    series.index = [get_random() for _ in range(len(series))]  # 构造数据
    plot_pie(series.to_dict())  # 常规的图


if __name__ == '__main__':
    main()

Matplotlib绘制饼图时用图例显示数据,防止饼图上数据重叠_第1张图片
一言难尽,是吧

2. 巧设图例

如果使用如下的绘图方法:

def plot_pie_optimize(dict_value: dict):
    keys = list(dict_value.keys())
    values = np.array(list(dict_value.values()))
    patches, texts = plt.pie(values)
    labels = ['{} {:1.2f}% ({})'.format(i, j, v) for i, j, v in
              zip(keys, 100. * values / values.sum(), values)]  # 构造图例数据
    patches, labels, dummy = zip(*sorted(
        zip(patches, labels, values), key=lambda x: x[2], reverse=True))
    plt.legend(patches, labels, loc="center", bbox_to_anchor=(-0.1, 0.5), fontsize=8)
    plt.tight_layout()
    plt.show()

就可以得到如下的效果:

Matplotlib绘制饼图时用图例显示数据,防止饼图上数据重叠_第2张图片

它的原理是绘图的时候:

  1. 不要在原有的饼图上添加任何可能会导致重叠的文字,如labels
  2. 自定义legend显示效果,把想要表现的东西都放到legend中,然后展示出来

完整代码

import matplotlib.pyplot as plt

import numpy as np
import pandas as pd
import random


def get_random():
    return "".join(random.sample('zyxwvutsrqponmlkjihgfedcba', np.random.random_integers(3, 10)))


def plot_pie(dict_value: dict):
    keys = list(dict_value.keys())
    values = list(dict_value.values())
    plt.pie(values, labels=keys)
    plt.legend()
    plt.show()


def plot_pie_optimize(dict_value: dict):
    keys = list(dict_value.keys())
    values = np.array(list(dict_value.values()))
    patches, texts = plt.pie(values)
    labels = ['{} {:1.2f}% ({})'.format(i, j, v) for i, j, v in
              zip(keys, 100. * values / values.sum(), values)]  # 构造图例数据
    patches, labels, dummy = zip(*sorted(
        zip(patches, labels, values), key=lambda x: x[2], reverse=True))
    plt.legend(patches, labels, loc="center", bbox_to_anchor=(-0.1, 0.5), fontsize=8)
    plt.tight_layout()
    plt.show()


def main():
    series = pd.Series(np.random.randint(1, 10, size=20))
    series.index = [get_random() for _ in range(len(series))]  # 构造数据
    plot_pie(series.to_dict())  # 常规的图
    plot_pie_optimize(series.to_dict())  # 把legend放外面的图


if __name__ == '__main__':
    main()

你可能感兴趣的:(matplotlib,python,numpy)