数学建模——Python绘图(可视化)

一、基础绘图

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、如需使用,可以直接复制代码,修改数据即可

  • 27
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值