Matplotlib常用画图总结

发布于:2023-01-19 ⋅ 阅读:(459) ⋅ 点赞:(0)

记录下最近使用过的Matplotlib图形,其实也没有什么总结的,画的时候看一下就好了。
这个里面也画了一些图,到时候可以参考一下。天池:数据分析达人赛1:用户情感可视化分析
可以多看看Seaborn,大部分Seaborn就够了,也比较方便,除非要定制化一些东西可能还是得回归原始的Matplotlib。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.dates as mdate
import seaborn as sns
from itertools import cycle
import warnings
from pylab import *

plt.style.use('fivethirtyeight')
color_cycle = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color'])
warnings.filterwarnings('ignore')
# plt.rcParams['font.sans-serif'] = ['SimHer']   不能用
mpl.rcParams['font.sans-serif'] = u'SimHei'
plt.rcParams['axes.unicode_minus'] = False

一、折线图

data = pd.read_excel('/Users/mato/Desktop/作业05/复仇者联盟上映期间数据.xlsx')

data['票房占比'] = data['票房占比'].map(lambda x: float(x.split('%')[0]) if list(x)[0] != '<' else 0.1)
_, axes=plt.subplots(1, 2, figsize=(15, 8))
sns.lineplot(data=data[data['电影名称'] == '复仇者联盟4:终局之战'], x='时间', y='票房(万)', ax=axes[0])
sns.lineplot(data=data[data['电影名称'] == '复仇者联盟4:终局之战'], x='时间', y='票房占比', ax=axes[1])
# 调整x轴间距
axes[0].xaxis.set_major_locator(ticker.MultipleLocator(base=3))
axes[1].xaxis.set_major_locator(ticker.MultipleLocator(base=3))
# 调整日期表示
axes[0].xaxis.set_major_formatter(mdate.DateFormatter('%m-%d'))  # %Y-%m-%d
axes[1].xaxis.set_major_formatter(mdate.DateFormatter('%m-%d'))
axes[0].set_title("票房折线图")
axes[1].set_title("票房占比折线图")
axes[1].set_ylabel('票房占比(%)')
plt.tight_layout()
plt.show()

在这里插入图片描述

二、频率分布直方图

sns.displot(data=data[data['电影名称'] == '复仇者联盟4:终局之战'], x="票房(万)", kde=True)
plt.show()

在这里插入图片描述

三、饼图

data = pd.read_excel('/Users/mato/Desktop/作业05/复仇者联盟上映期间数据.xlsx')
df = pd.DataFrame(columns=['name','per'])
count = 0
total = 0
# 这个地方如果直接data[data['时间'] == '2019-05-23']这样,你并不会遍历出每一行,
# 而data[data['时间'] == '2019-05-23']['票房占比']这样则可以
for i in data[data['时间'] == '2019-05-23'].iterrows():
    # 注意这里的i是tuple,i[0]是index,i[1]是你要的series
    if list(i[1]['票房占比'])[0] != '<' and float(i[1]['票房占比'].split('%')[0]) > 2:
        df.loc[count]=[i[1]['电影名称'], float(i[1]['票房占比'].split('%')[0])] 
        total += float(i[1]['票房占比'].split('%')[0])
        count += 1
df.loc[count] = ['其他(<1.5%)', 100 - total]
# plt.pie(data[data['时间'] == '2019-05-23']['票房占比'].map(lambda x: float(x.split('%')[0]) if list(x)[0] != '<' else 0.1), labels=data[data['时间'] == '2019-05-23']['电影名称'], autopct='%.1f%%', labeldistance=1.2, shadow=True)
# 得设置颜色,默认的对于这个正好一轮下来初始颜色和最后一个颜色重合;explode必须和pie的数量一样,默认0。
plt.pie(df['per'], labels=df['name'], autopct='%.1f%%', labeldistance=1.1, shadow=True, radius=2, textprops={'fontsize': 15}, colors=['#5d8ca8', '#27ae60', '#f1c40f', '#9b59b6'], explode=(0.2, 0, 0, 0, 0, 0, 0))
plt.show()

在这里插入图片描述

四、折线图

# 如果画出来是直线,一定是你的y轴值为str,记得变为flaot 
import time
data = pd.read_excel('/Users/mato/Desktop/作业05/数据.xlsx')
#将时间戳转为时间格式
data['发布时间']=pd.to_datetime(data['发布时间'], unit='s')
df = data[['发布时间', '播放量','评论数']]
#将时间作为索引
df = df.set_index('发布时间')
# 这里有一个坑,resample年后,他会把2013一整年的归到2014,所以需要loffset来偏移一年
df = df.resample('Y', loffset='-1y').mean()
#保留一位小数
df[['播放量','评论数']] = df[['播放量','评论数']].applymap(lambda x: float("%.1f"%(float(x)/1000)))  # applymap直接替掉原来的data
# 在使用聚合函数resample后,x轴坐标不用你自己变
# df[['发布时间']] = df[['发布时间']].applymap(lambda x: x.split('-')[0])
plt.figure(figsize=(12, 6))  # 要在做图前调整
# 当把‘发布时间’作为索引后,就无法df['发布时间'],得df.index
sns.lineplot(data=df, x=df.index, y='播放量')
plt.ylabel("播放量(万)")
plt.show()

在这里插入图片描述

五、柱状图

"""
这里很奇怪,resample后年份没有前进一年;需要自己改x轴的tick
"""
df1 = data[['发布时间' ,'评论数']]
df1 = df1.set_index('发布时间')
df1 = df1.resample('Y').mean()
# 注意这里要[[]],只有一个的话它是series,两个是dataframe,后者才有applymap
df1[['评论数']] = df1[['评论数']].applymap(lambda x: float("%.1f"%x))
# reset是撤销,set是增加
df1 = df1.reset_index()
df1[['发布时间']] = df1[['发布时间']].applymap(lambda x: str(x).split('-')[0])
sns.barplot(x='发布时间', y='评论数', data=df1, color='salmon')
plt.show()

在这里插入图片描述

六、箱形图

data1 = pd.read_excel('/Users/mato/Desktop/homework06/2019-5-22.xlsx')
# 由于显然票房不可能是负数,但通过四分位计算后,负数是合理的(可能是数据太少的原因),遂将其删除
# data1['票房(万)'] = data1[data1['票房(万)'] >0]  不能这么删Columns must be same length as key
data1 = data1.drop(data1.index[data1[data1['票房(万)'] < 0].index])
# 利用四分位填补异常
box_office_25 = data1['票房(万)'].quantile(0.25)
box_office_75 = data1['票房(万)'].quantile(0.75)
box_office_min = box_office_25 - 1.5 * (box_office_75 - box_office_25)
box_office_max = box_office_75 + 1.5 * (box_office_75 - box_office_25)
new1 =[]
for i in range(len(data1)):
    x = data1['票房(万)'].iloc[i]
    if x < box_office_min:
        new1.append(box_office_min)
    elif x > box_office_max:
        new1.append(box_office_max)
    else:
        new1.append(x)
data1['票房(四分位)'] = new1
# 坑!!!:图画出来后,呢个线其实不是上下限值,而是距离上下限值最近的值
sns.boxplot(x=data1["票房(四分位)"])
plt.show()

在这里插入图片描述

七、散点图

data = pd.read_excel('/Users/mato/Desktop/homework07/iris.xlsx')
_, axes=plt.subplots(1, 2, figsize=(15, 8))
sns.scatterplot(data=data, x="花萼长度", y="花萼宽度", ax=axes[0])
for i in data.columns:
    data[i] = (data[i] - data[i].mean()) / data[i].std()
sns.scatterplot(data=data, x="花萼长度", y="花萼宽度", ax=axes[1])
axes[0].set_title("标准化前")
axes[1].set_title("标准化后")
plt.show()

在这里插入图片描述

八、混淆矩阵、ROC曲线

_, axes=plt.subplots(2, 2, figsize=(15, 8))
# predict返回的是预测的结果,predict_proba返回的是每个结果的概率值
y_predict11 = estimator.predict(x_train)
y_predict12 = estimator.predict(x_test)
# ROC曲线要的是你的分类器输出一个“概率值”(正例1的概率和返例1的概率),会输出俩,所以是[:,1],否则画出来的就是一个点
y_predict21 = estimator.predict_proba(x_train)[:,1]
y_predict22 = estimator.predict_proba(x_test)[:,1]
# 这个ROC曲线每个阀值我先这的理解吧
# 训练出来的模型,通过多个阀值进行测试,AUC达到1就说明,阀值怎么变都能分好,说明模型把他们分类分的非常好了
fpr1, tpr1, _ = roc_curve(y_train, y_predict21)
fpr2, tpr2, _ = roc_curve(y_test, y_predict22)

sns.heatmap(confusion_matrix(y_train, y_predict11), annot=True, ax=axes[0, 0], fmt="d", cmap="YlGnBu", xticklabels=['正例','假例'], yticklabels=['正例','假例'])  # !!注意这种2*2的写法
axes[0, 0].set_ylabel('真实结果')
axes[0, 0].set_xlabel('预测结果')
axes[0, 0].set_title('训练集')
sns.heatmap(confusion_matrix(y_test, y_predict12), annot=True, ax=axes[0, 1], fmt="d", cmap="YlGnBu", xticklabels=['正例','假例'], yticklabels=['正例','假例'])
axes[0, 1].set_ylabel('真实结果')
axes[0, 1].set_xlabeål('预测结果')
axes[0, 1].set_title('测试集')

plt.subplot(2, 2, 3)
plt.plot(fpr1, tpr1, lw=1)
plt.plot([0, 1], [0, 1], linestyle="--", label='ROC curve(area = %0.4f)' %auc(fpr1, tpr1), lw=1)
plt.legend(loc='lower right')  # 各写各的
plt.subploåt(2, 2, 4)
plt.plot(fpr2, tpr2, lw=1)
plt.plot([0, 1], [0, 1], linestyle="--", label='ROC curve(area = %0.4f)' %auc(fpr2, tpr2), lw=1)
plt.legend(loc='lower right')
plt.show()

在这里插入图片描述

九、散点图

transformer = PCA(n_components=2)
transformer.fit(x_train)
test_pca = transformer.transform(x_test)

df = pd.DataFrame(test_pca, index=None, columns = ['a','b'])
# df['c'] = y_test  这样赋值是根据索引的,所以会出现Nan
y_test = y_test.reset_index (drop=True)
df['c'] = y_test
estimator = KMeans(n_clusters=2)
estimator.fit(test_pca)
labels = estimator.labels_
df['d'] = labels

plt.figure(figsize=(15,8))
ax1 = plt.subplot(1, 2, 1)
for i in list(range(0, 2)):
    df1 = df[df['c'] == i]
    plt.plot(df1['a'], df1['b'], 'o', label=i)
ax1.set_title('real') 
ax2 = plt.subplot(1, 2, 2)
for i in list(range(0, 2)):
    df2 = df[df['d'] == i]
    plt.plot(df2['a'], df2['b'], 'o', label=i)
ax2.set_title('cluster') 
plt.show()

在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看