一、基础绘图
1、折线图(matplotlib)
具体步骤参考本人之前的文章
from matplotlib import pyplot as plt
x = range(11,31)
y_1 = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]
y_2 = [1,0,3,1,2,2,3,3,2,1,2,1,1,1,1,1,1,1,1,1]
#设置图形大小
plt.figure(figsize=(20,8),dpi=80)
#画两条线,并写明哪条线表示什么,设置线条样式
plt.plot(x,y_1,label="得分1",color="coral",linewidth=5)
plt.plot(x,y_2,label="得分2",color="cyan",linestyle='--')
#设置x轴刻度
_xtick_labels = ["{}岁".format(i) for i in x]
plt.xticks(x,_xtick_labels)
#plt.yticks(range(0,9))
#显示中文字体
plt.rcParams['font.sans-serif'] = ['SimHei',]
#绘制网格,alpha设置网格透明度
plt.grid(alpha=0.5,linestyle=':')
#添加图例(在指定位置显示线条对应的含义)
plt.legend(loc="upper left")
plt.show()
2、条形图
from matplotlib import pyplot as plt
a = []
b = []
plt.figure(figsize=(20,8),dpi=80)
#绘制条形图
plt.bar(range(len(a)),b,width=0.3)
#设置字符串到x轴
plt.xticks(range(len(a)),a,rotation=90)
plt.rcParams['font.sans-serif'] = ['SimHei',]
plt.show()
多条条形图:
from matplotlib import pyplot as plt
a = ["猩球崛起3:终极之战","敦刻尔克","蜘蛛侠:英雄归来","战狼2"]
b_16 = [15746,312,4497,319]
b_15 = [12357,156,2045,168]
b_14 = [2358,399,2358,362]
bar_width = 0.2
x_14 = list(range(len(a)))
x_15 = [i+bar_width for i in x_14]
x_16 = [i+bar_width*2 for i in x_14]
plt.figure(figsize=(8,8),dpi=80)
plt.bar(range(len(a)),b_14,width=bar_width,label="9月14日")
plt.bar(x_15,b_15,width=bar_width,label="9月15日")
plt.bar(x_16,b_16,width=bar_width,label="9月16日")
plt.legend()
plt.xticks(x_15,a)
plt.rcParams['font.sans-serif'] = ['SimHei',]
plt.show()
3、散点图
from matplotlib import pyplot as plt
y_3 = [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]
y_10 = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]
x_3 = range(1,32)
x_10 = range(51,82)
#设置图形大小
plt.figure(figsize=(20,8),dpi=80)
#散点图和折线图的区别
plt.scatter(x_3,y_3,label="3月份",color="red")
plt.scatter(x_10,y_10,label="10月份")
_x = list(x_3)+list(x_10)
_xtick_labels = ["3月{}日".format(i) for i in x_3]
_xtick_labels += ["10月{}日".format(i-50) for i in x_10]
plt.xticks(_x[::3],_xtick_labels[::3],rotation=90)
#添加图例
plt.legend(loc="upper left")
#添加描述信息
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("标题")
plt.rcParams['font.sans-serif'] = ['SimHei',]
plt.show()
4、饼图
平面基础饼图
import numpy as np
import matplotlib.pyplot as plt
# 数据
size = [34,20,20,20,6]
# 设置中文
plt.rcParams['font.sans-serif'] = ['SimHei',]
# 绘图(标明各扇形含义)
plt.pie(size, labels=["Windows", "MAC", "Linux", "Android", "Other"])
#设置标题
plt.title("手机系统占比分析")
plt.show()
立体饼图
import matplotlib.pyplot as plt
data = [2052380, 11315444, 20435242, 7456627, 3014264, 1972395, 185028]
# 数据标签
labels = ['none', 'primary', 'junior', 'senior', 'specialties', 'bachelor', 'master']
# 各区域颜色
colors = ['red', 'orange', 'yellow', 'green', 'purple', 'blue', 'black']
# 数据计算处理
sizes = [data[0] / Num * 100, data[1] / Num * 100, data[2] / Num * 100, data[3] / Num * 100, data[4] / Num * 100,
data[5] / Num * 100, data[6] / Num * 100]
# 设置突出模块偏移值
expodes = (0, 0, 0.1, 0, 0, 0, 0)
# 设置绘图属性并绘图
plt.pie(sizes, explode=expodes, labels=labels, shadow=True, colors=colors)
## 用于显示为一个长宽相等的饼图
plt.axis('equal')
# 保存并显示
# plt.savefig('picture/step3/fig3.png')
plt.show()
5、百分比堆积图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.ticker import PercentFormatter
# 假设 df 已经被正确加载,这里只是一个示例
# df = pd.read_csv('your_data.csv') # 读取数据
# 示例数据(用于演示)
df = pd.DataFrame({
'Category': ['A', 'B', 'C', 'D', 'E'],
'Fair': [10, 20, 30, 40, 50],
'Good': [20, 30, 40, 50, 60],
'Very Good': [30, 40, 50, 60, 70],
'Premium': [40, 50, 60, 70, 80],
'Ideal': [50, 60, 70, 80, 90]
})
# 设置填充的颜色
colors = ['#ADFEDC', '#4EFEB3', '#02F78E', '#02CB74', '#019858']
labels = df.columns[1:].tolist() # 获取列标签
# 获取处理数据
y_values = df.iloc[0:5, 1:].values # 获取所有行的数据(这里只取前四行作为示例)
data = y_values.T # 转置数组,使得每个类别的数据成为一个列
x = range(len(labels)) # x轴标签
bottom_y = np.zeros(len(labels)) # 初始化底部y值为0
# 绘制堆积柱状图
figure, ax = plt.subplots()
for i, color in enumerate(colors):
y = data[i] / data[i].sum() # 计算百分比
ax.bar(x, y, width=0.5, color=color, bottom=bottom_y, edgecolor='gray', label=labels[i])
bottom_y += y # 更新底部y值以进行堆积
# 设置x轴标签
ax.set_xticks(x)
ax.set_xticklabels(labels)
# 设置图例
legend_labels = ['Fair', 'Good', 'Very Good', 'Premium', 'Ideal']
patches = [mpatches.Patch(color=color, label=label) for color, label in zip(colors, legend_labels)]
ax.legend(handles=patches, ncol=1, loc='upper right') # 将图例放在右上角
# 设置y轴为百分比格式
ax.yaxis.set_major_formatter(PercentFormatter(1))
# 绘制平行于x轴的虚线
for i in range(1, 11):
ax.axhline(y=i / 10, linestyle='dashed', color='black', linewidth=0.5)
# 设置标题和轴标签
plt.rcParams['font.sans-serif'] = ['SimHei',]
ax.set_title('百分比堆积柱状图', fontsize=13)
ax.set_ylabel('百分比', fontsize=13) # 修改ylabel为百分比
ax.set_xlabel('类别', fontsize=13) # 修改xlabel为中文
# 显示图形
plt.show()
6、热力图
import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
a=pd.read_csv(r"C:\Users\ASUS\Desktop\ong-customer-train.csv")
a.drop(a[a["Age"].str.contains("-")].index,inplace=True)
a=a.drop(a[a["Age"]=="0"].index)
a["Age"]=a["Age"].str.replace("岁","")
a["Age"]=a["Age"].str.replace(" 岁","")
# y轴含义
new_a=a[["CreditScore","Age","Tenure","Balance","NumOfProducts","EstimatedSalary"]]
# 数据
data=new_a.corr().round(4)
plt.figure(figsize=(8, 6))
sns.heatmap(data,
annot=True, #显示数值
cmap='PuBuGn', #色块颜色
linewidths=1,
linecolor='black',
)
plt.title('Correlation Heatmap') #标题
plt.show()
7、箱型图
sns.boxplot(x=insurance.smoker, y=insurance.charges, order=['no', 'yes'])
plt.show()
二、高级绘图
1、判断相关性
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib as mpl
import warnings
warnings.filterwarnings("ignore")
mpl.rcParams.update(mpl.rcParamsDefault)
sns.set_style("white")
fish = pd.read_csv('Fish.csv')
print(fish.head())
fish1 = fish[fish['Species'].isin(['Bream', 'Perch', 'Pike'])] #选取鱼的种类
# sns.pairplot(fish1, hue='Species')
# plt.show()
#设置主题(palette)
sns.pairplot(fish1, hue='Species', palette='husl', size=2)
plt.show()
若只想选取某一部分的数据:
sns.pairplot(fish1, hue='Species', vars=['Length1', 'Width', 'Height', 'Weight'],
height=3, aspect=1)
plt.show()
由于该图较为抽象,现给出数据集预览:
2、回归拟合图
sns.regplot(x=fish1.Weight, y=fish1.Height, color='#FF6600', marker='>')
plt.show()
若使用log拟合,只需修改默认log参数即可:
sns.regplot(x=fish1.Weight, y=fish1.Height, color='#FF6600', logx=True)
plt.show()
修改图形样式:
sns.regplot(x=fish1.Weight, y=fish1.Height, logx=True, line_kws={'color':'#FF5722', 'alpha':0.8, 'lw':3})
plt.show()
若想拟合多条
sns.lmplot(x='bmi', y='charges', hue='smoker', data=insurance, height=8, aspect=1.2)
plt.show()
(引入了一个insurance 的数据)
3、小提琴图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib as mpl
import warnings
warnings.filterwarnings("ignore")
# Recover default matplotlib settings
mpl.rcParams.update(mpl.rcParamsDefault)
sns.set_style("white")
employment = pd.read_excel("unemployment.xlsx")
sns.violinplot(x=employment.Age, y=employment.Unemployed, hue=employment.Gender, palette='Set2')
plt.show()
若要重叠两图,可以修改dodge参数,使其为False
sns.violinplot(x=employment.Age, y=employment.Unemployed, hue=employment.Gender, palette='Set2', dodge=False)
plt.show()
4、折线图(seaborn)
lineplot参数解释
sns.lineplot(x='Period', y='Unemployed', hue='Gender', style='Gender',data=employment,
dashes=False, palette='CMRmap', markers=['o', '>'])
x='Period':指定 x 轴的数据列为 "Period"。 y='Unemployed':指定 y 轴的数据列为 "Unemployed"。 hue='Gender':根据 "Gender" 列进行分组,并使用不同的颜色来表示不同的分组。 style='Gender':根据 "Gender" 列进行分组,并使用不同的标记样式来表示不同的分组。 markers=True:显示每个数据点的标记。 dashes=False:不使用虚线样式绘制折线。 data=employment:指定要使用的数据集为 employment。 err_style='bars':指定误差线的样式为条形图形式。 ci=70:设置置信区间为 70%,用于计算误差线的范围。 palette 参数指定了使用哪种调色板来着色 markers 参数指定了使用哪些标记
背景设置
plt.style.use('seaborn-darkgrid') #设置背景
"seaborn-whitegrid":与 "seaborn-darkgrid" 类似,但背景为白色。 "ggplot":仿照 R 语言中的 ggplot2 包的风格,带有灰色背景和更突出的轴线。 "fivethirtyeight":模仿知名新闻网站 FiveThirtyEight 的风格,专注于数据可视化。 "bmh":较为简洁的风格,适用于科学绘图。
pattle参数(调色板)类型
'deep':深色调色板 'muted':柔和色调调色板 'bright':鲜亮色调调色板 'pastel':柔和的亮色调色板 'dark':深色调色板 'colorblind':适合色盲人士的调色板
设置标题文字大小,颜色
plt.gcf().text(.2, .84, 'GENDER', fontsize=40, color='Black')
综合效果
plt.figure(figsize=(14, 7))
plt.style.use('ggplot')
plt.gcf().text(.2, .84, 'GENDER', fontsize=40, color='Black')
sns.set(rc={'xtick.labelsize':17,'ytick.labelsize':10,'axes.labelsize':15, 'axes.grid':False})
sns.lineplot(x='Period', y='Unemployed', hue='Gender', style='Gender',data=employment,
dashes=False, palette='CMRmap', err_style='bars', ci=70, markers=['o', '>'])
plt.show()
5、散点&线性分布图
relplot参数解释
sns.relplot(x='Period', y='Unemployed', hue='Gender', col='Age', kind='line',
data=employment, height=6, aspect=1, col_wrap=4, linewidth=2)
hue='smoker':通过颜色来区分不同的类别,这里使用 'smoker' 表示是否吸烟。 data=insurance:指定要使用的数据集,这里使用名为 'insurance' 的数据集。 height=8:设置图形的高度为 8 英寸。 aspect=1:设置图形的纵横比为 1。 col: 使用不同的列值将数据分成多个子图列 kind: 指定要绘制的关系图的类型。line就是线型图 col_wrap: 指定每行的子图数量。在这里,我们设置为 4,表示每行显示 4 个子图。 linewidth: 指定线的宽度
散点
sns.relplot(x='bmi', y='charges', hue='sex', col='sex', row='region',
data=insurance, height=7, aspect=.6)
plt.show()
线性分布
sns.relplot(x='Period', y='Unemployed', hue='Gender', col='Age', kind='line',
data=employment, height=6, aspect=1, col_wrap=4, linewidth=2)
plt.show()
6、核密度分布图
1)二维核密度图
先导入所需的库以及数据
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib as mpl
import warnings
import plotly.graph_objs as go
warnings.filterwarnings("ignore")
insurance = pd.read_csv('insurance.csv')
kdeplot参数解释
sns.kdeplot(x=insurance.bmi, y=insurance.charges, shade=True, cmap='Reds', shade_lowest=False)
cmap='Reds'指定了使用红色系的颜色映射 shade=True表示将估计结果映射为密度颜色 shade_lowest=True 会将密度估计图(Kernel Density Estimation Plot)中最低的区域进行阴影处理
plt.figure(figsize=(6, 8))
sns.kdeplot(x=insurance.bmi, y=insurance.charges, shade=True, cmap='Reds', shade_lowest=True)
plt.show()
swarmplot分布散点图
plt.figure(figsize=(7,7))
sns.swarmplot(x=insurance.smoker, y=insurance.charges)
plt.show()
2)更美观的核密度分布图
【1】
my_dpi = 96
plt.figure(figsize=(480 / my_dpi, 480 / my_dpi), dpi=my_dpi)
sns.jointplot(x=insurance["bmi"], y=insurance["charges"])
plt.show()
【2】
my_dpi=96
plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)
sns.jointplot(x=insurance["bmi"], y=insurance["charges"], kind='hex')
plt.show()
【3】
my_dpi=96
plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)
sns.jointplot(x=insurance["bmi"], y=insurance["charges"], kind='kde')
plt.show()
【4】
my_dpi=96
plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)
plt.hist2d(x=insurance["bmi"], y=insurance["charges"], bins=(300, 300), cmap=plt.cm.jet)
plt.gca()
plt.show()
集中分布时:
【5】
my_dpi=96
plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)
plt.hist2d(x=insurance["bmi"], y=insurance["charges"], bins=(300, 30), cmap=plt.cm.jet)
plt.gca()
plt.show()
3)三维核密度图
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = insurance['age'].values
y = insurance['bmi'].values
z = insurance['charges'].values
# 计算核密度估计
density, x_edges, y_edges = np.histogram2d(x, y, bins=50, density=True)
density /= density.sum()
# 创建网格坐标
x_grid, y_grid = np.meshgrid(x_edges[:-1], y_edges[:-1])
# 绘制三维核密度图
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x_grid, y_grid, density, cmap='viridis')
ax.set_xlabel('age')
ax.set_ylabel('bmi')
ax.set_zlabel('charges')
plt.show()
在此基础上再画一个灰度图:
# 计算灰度值
gray_values = density.sum(axis=1) # 沿y轴方向进行求和,得到灰度值
# 绘制灰度图
fig2 = plt.figure()
ax2 = fig2.add_subplot(111, projection='3d')
X, Y = np.meshgrid(y_edges[:-1], x_edges[:-1])
ax2.plot_surface(X, Y, np.outer(gray_values, np.ones_like(y_edges[:-1])), cmap='gray')
ax2.set_xlabel('bmi')
ax2.set_ylabel('age')
ax2.set_zlabel('gray values')
plt.show()
除此之外,还能加入散点元素,使得数据更为直观地分布在空间中
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = insurance['age'].values
y = insurance['bmi'].values
z = insurance['charges'].values
# 计算核密度估计
density, x_edges, y_edges = np.histogram2d(x, y, bins=50, density=True)
density /= density.sum()
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 绘制三维地形图
X, Y = np.meshgrid(x_edges[:-1], y_edges[:-1])
Z = density.T
ax.plot_surface(X, Y, Z, cmap='terrain', rstride=1, cstride=1)
# 添加散点图
ax.scatter(x, y, z, cmap='viridis', s=5)
ax.set_xlabel('age')
ax.set_ylabel('bmi')
ax.set_zlabel('charges')
ax.set_title('3D Terrain Map')
plt.show()
7、直方分布图
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib as mpl
import warnings
warnings.filterwarnings("ignore")
# Recover default matplotlib settings
mpl.rcParams.update(mpl.rcParamsDefault)
# 参数解释:
# kde:是否显示核密度曲线
fig1 , axes = plt.subplots(nrows=3,ncols=3 , figsize = (20,20))
sns.distplot( housing["longitude"] , ax=axes[0, 0])
sns.distplot( housing["latitude"] , ax=axes[0, 1])
sns.distplot( housing["housing_median_age"] , ax=axes[0, 2])
sns.distplot( housing["total_rooms"], ax=axes[1, 0] )
sns.distplot( housing["population"] , ax=axes[1, 1] )
sns.distplot( housing["households"] , ax=axes[1, 2] )
sns.distplot( housing["median_income"] , ax=axes[2, 0])
sns.distplot( housing["median_house_value"], ax=axes[2, 1])
sns.distplot( housing["median_house_value"], ax=axes[2, 2])
plt.show()
美化,并且删除曲线以后:
fig1 , axes = plt.subplots(nrows=3,ncols=3 , figsize = (20,20))
sns.distplot( housing["longitude"] , color="#00bcd4", ax=axes[0, 0] , kde=False , bins=20)
sns.distplot( housing["latitude"] , color="#937d14", ax=axes[0, 1] , kde=False,bins=20)
sns.distplot( housing["housing_median_age"] , color="#006600", ax=axes[0, 2],kde=False,bins=20)
sns.distplot( housing["total_rooms"] , color="#ff1e56", ax=axes[1, 0] , kde=False,bins=20)
sns.distplot( housing["population"] , color="#216353", ax=axes[1, 1] , kde=False,bins=20)
sns.distplot( housing["households"] , color="#FF8F00", ax=axes[1, 2] , kde=False,bins=20)
sns.distplot( housing["median_income"] , color="#33FF00", ax=axes[2, 0] , kde=False,bins=20)
sns.distplot( housing["median_house_value"] , color="#FF3300", ax=axes[2, 1], kde=False,bins=20)
sns.distplot( housing["median_house_value"] , color="#CCCC00", ax=axes[2, 2] , kde=False,bins=20)
plt.show()
声明:
1、本文数据来源于网络与个人的竞赛经历
2、本文仅限于各种绘图的代码与示例,不涉及每种图的使用场景及其代码写作方法
3、如需使用,可以直接复制代码,修改数据即可