准备工作
使用Python绘图首先需要导入需要的库,并确保中文和负号的正常显示
import os
import xlrd
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.ticker as ticker
plt.rcParams['font.family'] = ['SimHei'] # plt正常显示中文
plt.rcParams['axes.unicode_minus'] = False # plt正常显示负号
sns.set_style({'font.sans-serif':['SimHei']}) # seaborn正常显示中文
如何你是mac系统,设置sns.set_style({'font.sans-serif':['SimHei']})
并不一定能够保证你的中文能正常显示,你可以按照这篇文章的方法让中文正常显示。
准备好你的环境以后,我们开始一些简单常用的绘图示例
堆积条形图
数据准备
data = pd.DataFrame(
data=[
['一年级',4,'male'],
['一年级',5,'female'],
['二年级',12,'male'],
['二年级',24,'female'],
['三年级',13,'male'],
['三年级',25,'female'],
],
columns=list('ABC')
)
绘图代码
fig = plt.figure(figsize=(6,3), dpi=150)
ax1 = fig.add_subplot(1,1,1)
sns.histplot(x='A', weights='B',data=data, hue='C', ax=ax1,
shrink = 0.7, multiple='stack',palette='Blues', )
ax1.set_xlabel('年级')
ax1.set_ylabel('累计人数')
ax1.set_title('不同年级男女比例分布人数分布')
其中x指定的是你图中的横轴,weights是你y轴统计量,hue是分类。
双轴图
数据准备
x = np.linspace(-10,10,100)
y = np.sin(x)
z = x*x
data = pd.DataFrame([x,y,z]).T
data.columns = ['x','y','z']
绘图代码
fig = plt.figure(figsize=(6,3), dpi=150)
ax1 = fig.add_subplot(1,1,1)
ax1_twinx = ax1.twinx()
ax1.plot(data['x'], data['y'], c='r', label='sin(x)')
ax1_twinx.plot(data['x'], data['z'], c='b', label='cos(x)')
# 显示label
ax1.legend(loc='upper left')
ax1_twinx.legend(loc='upper right')
配色的话可以参考slandarer的高质量论文配图配色(附RGB值及16进制码)
我列几个可以取的配色#8ECFC9
、#FFBE7A
、#FA7F6F
、#82B0D2
。
多子图
绘图代码
fig = plt.figure(figsize=(6,4), dpi=200)
# 分配幕布
ax1 = fig.add_subplot(2,1,1)
ax2 = fig.add_subplot(2,1,2)
ax1.plot(data['x'], data['y'], c='#8ECFC9', label='sin(x)')
ax2.plot(data['x'], data['z'], c='#FFBE7A', label='cos(x)')
fig.tight_layout() # 防止重叠
相关系数热力图
最常见的热力图在seaborn的heatmap中有详细的示例,实现也比较简单,大家可以姐直接按照seaborn官方文档中的代码实现
圆圈热力图在python的实现相对要麻烦一点,圆圈热力图在seaborn上有example,链接在这
首先读取数据
import seaborn as sns
sns.set_theme(style="whitegrid")
# Load the brain networks dataset, select subset, and collapse the multi-index
df = sns.load_dataset("brain_networks", header=[0, 1, 2], index_col=0)
如果出现错误一般是网络的原因,可以到mwaskom/seaborn-data
直接下载对应的文件,从本地读取
df = pd.read_csv('brain_networks.csv', header=[0, 1, 2], index_col=0)
计算相关系数矩阵
used_networks = [1, 5, 6, 7, 8, 12, 13, 17]
used_columns = (df.columns
.get_level_values("network")
.astype(int)
.isin(used_networks))
df = df.loc[:, used_columns]
df.columns = df.columns.map("-".join)
# Compute a correlation matrix and convert to long-form
corr_mat = df.corr().stack().reset_index(name="correlation")
corr_mat
计算的结果如图,数据的样式是long-form的,原因是圆圈日历图实际上是通过散点图的形式实现的,所以需要每个点的横纵坐标,而correlation则是圆圈的大小
# Draw each cell as a scatter point with varying size and color
g = sns.relplot(
data=corr_mat,
x="level_0",
y="level_1",
hue="correlation",
size="correlation",
palette="vlag", # 设置调色板
hue_norm=(-1, 1), # 将颜色区间归一化,改变该参数可以调整圆圈的颜色
edgecolor=".7",
height=10,
sizes=(50, 250), # 调整最大和最小的圆圈的大小
size_norm=(-.2, .8), # 将size归一化
)
# Tweak the figure to finalize
g.set(xlabel="", ylabel="", aspect="equal") # 隐藏xlabel和ylabel
g.despine(left=True, bottom=True) # 隐藏刻度
g.ax.margins(.02) # 修改margin
for label in g.ax.get_xticklabels():
label.set_rotation(90) # 旋转坐标
# for artist in g.legend.legendHandles:
# artist.set_edgecolor(".7")