前言

在前文中,我们介绍了使用pyecharts绘制南丁格尔玫瑰图,本章我们再学习一下使用matplotlib绘制南丁格尔玫瑰图,了解在极坐标系中绘制柱状图。并对比一下两种不同的绘制方法,如何实现?

介绍

玫瑰图是弗罗伦斯·南丁格尔所发明的。又名为极坐标面积图,是一种圆形的直方图。 南丁格尔自己常昵称这类图为鸡冠花图(coxcomb),适用于绘制比较、随时间变化的循环现象。和传统的饼图展示形式单一相比,南丁格尔玫瑰图更加绚丽,给人的感觉更直观、深刻,因此,南丁格尔玫瑰图在数据可视化领域的应用十分广泛。
 

Matplotlib

Matplotlib 是 Python 的绘图库,它能让使用者很轻松地将数据图形化,并且提供多样化的输出格式。是一个非常强大的 Python 画图工具,我们可以使用该工具将很多数据通过图表的形式更直观的呈现出来。可以用来绘制各种静态,动态,交互式的图表,线图、散点图、等高线图、条形图、柱状图、3D 图形、甚至是图形动画等等。

安装matplotlib库:

pip install matplotlib

准备数据 

以水果为例,生成一组数据。

# coding=utf-8
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
 
fruits = {'香蕉': 115, '梨': 79, '椰子': 241, '柿子': 74, '鲜枣': 125,
          '榴莲': 147, '石榴': 72, '菠萝蜜': 105, '牛油果': 143, '山楂': 102}
s_fruits = pd.Series(fruits)
print(s_fruits)
香蕉     115
梨       79
椰子     241
柿子      74
鲜枣     125
榴莲     147
石榴      72
菠萝蜜    105
牛油果    143
山楂     102
dtype: int64

源码实现

将上面的数据拆分成为一维数组。

labels = []
nums = []
for x,y in [list(z) for z in zip([fruit for fruit in s_fruits.index], s_fruits)]:
    labels.append(x)
    nums.append(y)
    
labels
['香蕉', '梨', '椰子', '柿子', '鲜枣', '榴莲', '石榴', '菠萝蜜', '牛油果', '山楂']

绘制玫瑰图所需要的参数,柱子数量、每个柱子的宽度和角度。

size= len(nums)  # 柱子的数量
width = 2 * np.pi / size # 每个柱子的宽度
rad = np.cumsum([width] * size)  # 每个柱子的角度

配置每一个柱子的颜色。

# 转化为小数的rgb色列表 
colors = [
     (0.68359375, 0.02734375, 0.3203125),
     (0.78125, 0.05078125, 0.2578125),
     (0.875, 0.0390625, 0.1796875),
     (0.81640625, 0.06640625, 0.0625),
     (0.8515625, 0.1484375, 0.08203125),
     (0.90625, 0.203125, 0.13671875),
     (0.89453125, 0.2890625, 0.0703125),
     (0.84375, 0.2421875, 0.03125),
     (0.9140625, 0.26953125, 0.05078125),
     (0.85546875, 0.31640625, 0.125)
 ]

绘制玫瑰图

text使用参数,请参考:matplotlib.axes.Axes.text()

plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文显示

plt.figure(figsize=(12, 12),dpi=300,)  # 创建画布
ax = plt.subplot(projection='polar')
ax.set_ylim(-8, np.ceil(max(nums) + 1))  # 中间空白,-8为空白半径大小,可自行调整
ax.set_theta_zero_location('N',-5.0)  # 设置极坐标的起点方向 W,N,E,S, -5.0为偏离数值,可自行调整
ax.set_theta_direction(1) # 1为逆时针,-1为顺时针
ax.grid(False)  # 不显示极轴
ax.spines['polar'].set_visible(False)  # 不显示极坐标最外的圆形
ax.set_yticks([])  # 不显示坐标间隔
ax.set_thetagrids([])  # 不显示极轴坐标

ax.bar(rad, nums, width=width, color=colors, alpha=1) # 画图


 # 设置text
for i in np.arange(len(nums)):
    ax.text(rad[i],  # 角度
                    nums[i]-20,  # 长度
                    labels[i]+'\n'+str(nums[i]),  # 文本
                    rotation=rad[i] * 180 / np.pi -5,  # 文字角度
                    rotation_mode='anchor',            # 对齐文本,可选参数['default','anchor']
                    alpha=0.8,#透明度
                    fontstyle='normal',# 设置字体类型,可选参数[ ‘normal’ | ‘italic’ | ‘oblique’ ],italic斜体,oblique倾斜
                    fontweight='medium', # 设置字体粗细,可选参数 [‘light’, ‘normal’, ‘medium’, ‘semibold’, ‘bold’, ‘heavy’, ‘black’]
                    color='white', # 设置字体颜色
                    size=nums[i]/8, # 设置字体大小
                    ha="center", # 'left','right','center'
                    va="top", # 'top', 'bottom', 'center', 'baseline', 'center_baseline'
                    )

plt.show()

效果图

python画单数据南丁格尔玫瑰图 matplotlib南丁格尔图_matplotlib

优化玫瑰图

通过对nums数组进行排序,可美化玫瑰图,如下:

# 对数组进行排序操作
nums.sort()

plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文显示

plt.figure(figsize=(12, 12),dpi=300,)  # 创建画布
ax = plt.subplot(projection='polar')
ax.set_ylim(-2, np.ceil(max(nums) + 1))  # 中间空白,-2为空白半径大小,可自行调整
ax.set_theta_zero_location('N',-5.0)  # 设置极坐标的起点方向 W,N,E,S, -5.0为偏离数值,可自行调整
ax.set_theta_direction(1) # 1为逆时针,-1为顺时针
ax.grid(False)  # 不显示极轴
ax.spines['polar'].set_visible(False)  # 不显示极坐标最外的圆形
ax.set_yticks([])  # 不显示坐标间隔
ax.set_thetagrids([])  # 不显示极轴坐标

ax.bar(rad, nums, width=width, color=colors, alpha=1) # 画图

 # 设置text
for i in np.arange(len(nums)):
    ax.text(rad[i],  # 角度
                    nums[i]-2,  # 长度,-2为文字偏离顶部距离
                    labels[i]+'\n'+str(nums[i]),  # 文本
                    rotation=rad[i] * 180 / np.pi -5,  # 文字角度
                    rotation_mode='anchor',            # 对齐文本,可选参数['default','anchor']
                    alpha=0.8,#透明度
                    fontstyle='normal',# 设置字体类型,可选参数[ ‘normal’ | ‘italic’ | ‘oblique’ ],italic斜体,oblique倾斜
                    fontweight='medium', # 设置字体粗细,可选参数 [‘light’, ‘normal’, ‘medium’, ‘semibold’, ‘bold’, ‘heavy’, ‘black’]
                    color='white', # 设置字体颜色
                    size=nums[i]/0.8, # 设置字体大小
                    ha="center", # 'left','right','center'
                    va="top", # 'top', 'bottom', 'center', 'baseline', 'center_baseline'
                    )

plt.show()

效果图

python画单数据南丁格尔玫瑰图 matplotlib南丁格尔图_信息可视化_02