开启辅助访问
 找回密码
 立即注册

python绘图总结

lcd7171 回答数5 浏览数9876
本文主要包括python绘图中的matplotlib, pandas, seaborn三个部分。matplotlib分为如下几个主题

  • 中文支持
  • plt示例代码
  • 面向对象
  • 创建子图
  • 全局设置
  • 颜色系统
  • backend设置
  • 循环作图
  • plt不输出对象
首先导入基本模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline本文代码在jupyter notebook中运行,最后一行魔法命令,可以在画图时结尾不需要plt.show()
中文支持

plt.rcParams['font.sans-serif'] = ['FangSong']
plt.rcParams['axes.unicode_minus'] = Falseplt示例代码

用pyplot模块作图非常简单,这里用一台例子展示各个位置的设置方式
bar1 = [4, 5, 6, 8, 7]
bar2 = [7, 6, 2, 5, 4]
labels = ['小明', '小张', '小洪', '小红', '小铭']
bar_width = 0.35

plt.bar(np.arange(5)-0.5*bar_width, bar1, label='第一次',
        width=bar_width, color='#58C9B9')
plt.bar(np.arange(5)+0.5*bar_width, bar2, label='第二次',
        width=bar_width, color='#519D9E')
plt.xlabel('人名', fontsize=15)
plt.ylabel('数量', fontsize=15)
plt.title('数量统计', fontsize=18)
plt.ylim([0, 10])
plt.legend()
plt.xticks(np.arange(5), labels, fontsize=13)
plt.box(False)
plt.grid(color='0.4', axis='y', linestyle='solid', alpha=0.1)

for i, j in enumerate(bar1):
    plt.text(i-0.5*bar_width-0.05, j+0.1, str(j))

for i, j in enumerate(bar2):
    plt.text(i+0.5*bar_width-0.05, j+0.1, str(j))

plt.savefig('fig.pdf', bbox_inches='tight')

其中plt.bar第一台参数是横轴坐标;plt.xticks第一台参数也是横坐标列表,指定在哪些横坐标上标刻度。
绘制各种图形的代码示例可以参考官网
面向对象

Matplotlib中常⽤对象的包含关系为Figure > Axes > (Line2D, Text,etc.)。Figure对象表示一整张图表;其中可包含多个绘图区域,可以理解为多个坐标轴,用Axes表示,也可以称之为子图;在每一台子图中绘制具体的图形对象,如点、线、文本等。
很多情况下直接使用pyplot模块就够用了,但是当有多个图和坐标系时,使用面向对象的创建方式可以更加自由地在子图之间进行切换。
关于对象更加详细深刻的阐述可参考绘图: matplotlib核心剖析
对象的创建
fig = plt.figure()
axes = fig.add_subplot(1, 1, 1)
axes.plot([1, 2, 3])axes创建后使用方法与plt没有很大的区别,但是或是会有一些差别,比如标题坐标轴的设置
面向对象与plt的差异
axes.set_title('title')
axes.set_xlabel('x')
axes.set_ylabel('y')

plt.title('title')
plt.xlabel('x')
plt.ylabel('y')有的函数只能由axes调用而不可以用plt,比如画多边形时的add_patch
fig = plt.figure()
axes = fig.add_subplot(1, 1, 1)
axes.plot([1, 2, 3])

poly = plt.Polygon([[0.5, 1], [1, 1.5], [1, 1]],
                   facecolor='0.9', edgecolor='0.5')
axes.add_patch(poly)面向对象与plt的相互转化
但是有时本来只是在用plt作图,为了用add_patch而特意创建一台axes就比较麻烦,此时可以用plt.gca()获取当前的Axes对象
plt.plot([1, 2, 3])
poly = plt.Polygon([[0.5, 1], [1, 1.5], [1, 1]],
                   facecolor='0.9', edgecolor='0.5')
plt.gca().add_patch(poly)下面一台例子很好地展现了图表之间的切换
plt.figure(1)
plt.figure(2)
ax1 = plt.subplot(211)
ax2 = plt.subplot(212)
x = np.linspace(0, 3, 100)
for i in range(1, 4):
    plt.figure(1)
    plt.plot(x, np.exp(i*x/3))
    plt.sca(ax1)
    plt.plot(x, np.sin(i*x))
    plt.sca(ax2)
    plt.plot(x, np.cos(i*x))

说明

  • plt.figure(1)其中的数字用于图之间的区分,这个函数调用第一次表示创建id为1的图(Figure对象),调用第二次表示切换到这个图上,这样之后调用plt就会自动在这个图中绘制
  • plt.sca表示切换到该Axes对象,这样之后调用plt就会自动在这个子图中绘制
上述方法完全使用plt来完成,虽然可以做,但可读性较差,下面使用对象来完成会更加清晰。
fig1, ax0 = plt.subplots(1, 1)
fig2, (ax1, ax2) = plt.subplots(2, 1)
x = np.linspace(0, 3, 100)
for i in range(1, 4):
    ax0.plot(x, np.exp(i*x/3))
    ax1.plot(x, np.sin(i*x))
    ax2.plot(x, np.cos(i*x))Axes设置
Axes对象设置坐标轴、标题的相关方法一般分为以set为前缀与get前缀两种,但不是一一对应的,有的方法只有get而没有set,展示一部分方法如下
Axes.set_xlim
Axes.get_xlim

Axes.set_xlabel
Axes.set_xticks
Axes.set_xticklabels
Axes.get_xticklines从get的结果可以看出,一张图是由很多基础对象构成的。比如一台折线图,不仅折线是Line2D对象,而且Axes.get_xticklines的结果也是Line2D,而get_xticklabels是Text对象,一整张图就是由这些基础对象拼凑而成的。
常见的设置方式有如下几种
fig, ax = plt.subplots()
ax.plot([1, 2, 3])
ax.set_title('title')
ax.set_xlabel('x')
ax.set_ylabel('y')

labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

# ax.set(title='title', xlabel='x', ylabel='y')更多设置内容参考官网Axes API和博客(setp和getp的用法)。
关于setp和getp多说一句,下面展示几组等价做法
ax.get_xaxis()
plt.getp(ax, 'xaxis')

ax.set_xlabel('x')
plt.setp(ax, 'xlabel', 'x')

plt.setp(ax.lines[0],'color','g')
ax.get_lines()[0].set_color('g')只要Axes类中定义了get_xxx方法,就可以用getp;定义了set_xxx方法,就可以用setp。line2D等其他类也是一样。这些类都可以在官网API中找到。所以任何对象都可以去找API看有哪些属性可以设置。此外,get既可以查找参数值也查找对象,比如lines隶属于axes,就可以由后者调用出前者,matplotlib中各种类的隶属关系可以参考之前提到的那篇绘图: matplotlib核心剖析。
创建子图

matplotlib中规则排版的子图有多种设置方式
# 第一种
plt.subplot(211)
plt.plot([1, 2, 3, 4])
plt.subplot(212)
plt.scatter([1,2,3,4], [3,4,2,1])

# 第二种(可以配合循环使用)
plt.subplot(1, 2, 1)
plt.plot([1, 2, 3, 4])
plt.subplot(1, 2, 2)
plt.scatter([1,2,3,4], [3,4,2,1])

# 第三种
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)
ax2 = fig.add_subplot(2,1,2)

# 第四种
ax1 = plt.subplot(211)
ax2 = plt.subplot(212)

# 第五种
fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True)

# 第六种
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
for ax in axes.flatten():
    pass更复杂的排版可以参考官网
全局设置

套用主题
plt.style.use('ggplot')
plt.style.use('default')
print(plt.style.avAIlable)

with plt.style.context(('dark_background')):
    plt.plot(np.sin(np.linspace(0, 2 * np.pi)), 'r-o')主题效果展示,自定义主题可以在stylelib文件夹中创建.mplstyle文件,有哪些参数可以参考下一节,参考官网。
全局修改
import matplotlib as mpl
mpl.rcParams['lines.linewidth'] = 2
mpl.rcParams['lines.color'] = 'r'

mpl.rcdefaults()mpl.rcParams类似字典,里面存有所有当前参数设置,可以直接修改。用plt.rcParams也可。
其他修改方法
# 第一种
mpl.rc('lines', linewidth=2, color='r')

# 第二种
with mpl.rc_context(rc={'lines.linewidth': 1}):
    plt.plot(np.sin(np.linspace(0, 2 * np.pi)), 'r-o')坐标轴全局设置
类似这样设置
Axes.tick_params(direction='out', length=6, width=2, colors='r',
               grid_color='r', grid_alpha=0.5)颜色系统

调用颜色有以下几种方法

  • 使用颜色名称
  • RGB/RGBA或hex
  • 0-1数字字符串
  • CN主题颜色板
  • 色板
  • 多种颜色
使用颜色名称
颜色名称有4种使用方式
1.常规颜色
plt.plot([1, 2, 3], color='red')所有名称共148种,常用的颜色名称都可以直接使用。可以用下面的命令查看
import matplotlib._color_data as mcd
mcd.CSS4_COLORS2.xkcd颜色
在正常颜色名称前面加上xkcd:,一共949种,用下面命令查看
import matplotlib._color_data as mcd
mcd.XKCD_COLORS上面两类的同名颜色展示可以参考官网。
3.简写
常用颜色名称还有简写,可以选择这些中的一台
{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}4.Tableau
Tableau颜色可以从下面字符串中选择
{'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'}RGB/RGBA或hex
一台三元或四元的列表(元组、np.array等都可以),三元表示RGB: red green blue,四元表示RGBA: red green blue alpha,其中alpha表示透明度。数值都要在0-1之间,如果是0-255的整数要先除以255.
plt.plot([1, 2, 3], color=[0.3, 0.5, 0.6])
plt.plot([1, 2, 3], color=[0.3, 0.5, 0.6, 0.2])
plt.plot([1, 2, 3], color='#0F0F0F')
plt.plot([1, 2, 3], color='#0F0F0F40')0-1数字字符串
plt.plot([1, 2, 3], color='0.7')黑色半透明,值越大越透明。
CN主题颜色板
这是主题内置的颜色集,同样指定C1,使用ggplot主题和seaborn主题得到的颜色就是不一样。这也是使用该主题时默认使用的颜色。由主题配置文件中的axes.prop_cycle参数控制的,可以用mpl.rcParams调用显示,也可以修改。
import matplotlib as mpl
with plt.style.context(('ggplot')):
    plt.plot([1, 2, 3], color='C0')
    plt.plot([6, 2, 3], color='C1')
    print(mpl.rcParams['axes.prop_cycle'])上述内容参考官网
色板
1.色板的使用
n = 5
cmap = plt.cm.get_cmap('Set1', n)
for i in range(n):
    print(cmap(i))结果为
(0.8941176470588236, 0.10196078431372549, 0.10980392156862745, 1.0)
(0.30196078431372547, 0.6862745098039216, 0.2901960784313726, 1.0)
(1.0, 0.4980392156862745, 0.0, 1.0)
(0.6509803921568628, 0.33725490196078434, 0.1568627450980392, 1.0)
(0.6, 0.6, 0.6, 1.0)其中cmap包含5种颜色,通过cmap(i)调用得到RGBA格式的颜色,这5种颜色来源于色板Set1。cmap也可以接小数。
2.所有内置色板
要查看所有色板可以用下面这条命令
import matplotlib.cm
print(matplotlib.cm.cmap_d.keys())所有色板的颜色展示参考官网
3.其他调用方式
# 连续型色板
cmap = plt.cm.get_cmap('BrBG')
for i in range(10):
    print(cmap(i))

import matplotlib as mpl
cmap = mpl.cm.BrBG
for i in range(10):
    print(cmap(i))

# 离散型色板
import matplotlib as mpl
cmap = mpl.cm.Set1
cmap.colors4.cmap对象设置
cmap对象可以进一步设置,比如颜色上下限等,方法参考官网
5.自定义cmap对象
import matplotlib as mpl
cmap = mpl.colors.ListedColormap(['red', 'green', 'blue', 'cyan'])
for i in range(4):
    print(cmap(i))可以用这个思路对原色板进行修改,详情可以参考官网,渐变色的创建可以参考stackoverflow
多种颜色
以画点图为例,要作一台点图,所有点的颜色不同,有三种方法

  • c参数接一台和点数量等长的可迭代对象
  • 一台点一台点来画
  • 数字配合色板
1.可迭代对象
# 使用颜色简称
data = np.random.rand(5,2)
plt.scatter(data[:, 0], data[:, 1], c='rrbyb')

# 使用rgb三值向量,所以c参数就要接一台5*3的矩阵
data = np.random.rand(5,2)
plt.scatter(data[:, 0], data[:, 1], c=np.random.rand(5,3))2.一台一台点来画
# rgb三值向量表示颜色
for x, y in np.random.rand(10,2):
    plt.scatter(x, y, c=np.random.rand(3, ))3.整数配合色板
指定色板则c参数可以接一台数字
data = np.random.rand(5,2)
cmap = plt.cm.get_cmap('hsv', 5)
plt.scatter(data[:, 0], data[:, 1],
            c=list('12345'), cmap=cmap)backend设置

有的服务器没有图形显示界面,画图代码如果不加设置,会请求显示图片而报错,此时可以用下面两种方式设置
# 这两行需要在导入plt之前
import matplotlib as mpl
mpl.use('agg')

import matplotlib.pyplot as plt或者这样
import matplotlib.pyplot as plt
plt.switch_backend('agg')本节参考这篇博客和stackoverflow。
循环作图

1、 jupyter中循环画线图,默认会全画在一张图里,如果想每张图都堆到下面,只要加个plt.show()
for i in range(3):
    plt.plot([1,2,i])
    plt.show()2、 动态图。在同一台位置,循环展示一些图片,像播放幻灯片一样
import time
from IPython import display
for i in range(3):
    plt.plot([1,2,i])
    plt.show()
    display.clear_output(wait=True)
    time.sleep(0.5)3、 循环大量作图不需要展示但要保存时,有时会出现这种情况:
RuntimeWarning: More than 20 figures have been opened.并不是所有循环作图都会出现这个问题,因此在这里记录一下什么时候会出现,出现了该如何解决。比如下面这种情况就不会出现
for i in range(30):
    plt.plot([1, 2, 3])
    plt.savefig('{}.png'.format(i))只有当你创建了图时才会出现,比如作图时想用axes,然后就创建了图,如下所示
for i in range(30):
    fig, ax = plt.subplots(1, 1, figsize=(10, 10))
    ax.imshow(data)
    ax.add_artist(plt.Rectangle((2, 3), 20, 20, fill=False, color='g'))
    plt.savefig('images/{}.png'.format(i), bbox_inches='tight')这时就会报那个warning;即使在无图形界面的服务器上,backend设置成了agg,也会报这个warning。这个warning是说我们打开了太多figure没有关闭,所以处理办法就是加一台plt.close()来解决,如下所示
for i in range(30):
    fig, ax = plt.subplots(1, 1, figsize=(10, 10))
    ax.imshow(data)
    ax.add_artist(plt.Rectangle((2, 3), 20, 20, fill=False, color='g'))
    plt.savefig('images/{}.png'.format(i), bbox_inches='tight')
    plt.close()当然,如果axes的位置都换成plt.gca(),不需要第一步创建图,则也不需要close。
plt不输出对象

在 jupyter notebook 交互模式下,plt作图前会输出对象,例如下面代码
plt.hist([1,2,3,4,5]) 会在作图之前产生下面这些输出
(array([1., 0., 1., 0., 0., 1., 0., 1., 0., 1.]),
array([1. , 1.4, 1.8, 2.2, 2.6, 3. , 3.4, 3.8, 4.2, 4.6, 5. ]),
<a list of 10 Patch objects>)如果不想出现这些,有如下几种方法
# 1. 加分号
plt.hist([1,2,3,4,5])

# 2. 赋值
_ = plt.hist([1,2,3,4,5])

# 3. 调用 plt.show()
plt.hist([1,2,3,4,5])
plt.show()pandas绘图

特点总结

  • Series和DataFrame对象都可以调用plot方法进行作图,默认是折线图,可以通过kind参数改为其他类型,也可以调用类似df.plot.bar这样的方法
  • 多列数据框会用不同颜色将每一列画进同一张图片中,实现类似分组作图的效果,但这不算是自动分组作图。其他方式比如配合groupby或set_index的方式,都相当于弄出多列再画上去,无法做到直接这样设置参数color=x实现分组。
  • matplotlib中的全局参数、主题、颜色在这里都适用。也可以结合plt与面向对象一起使用。
具体代码可以参考官网
seaborn绘图

seaborn最大的优势是可以将变量传给color等参数实现分组作图。举一台最简单的例子
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid")
sns.relplot(x="total_bill", y="tip", hue="smoker", data=tips);面向对象
这是一种操作办法
f, (ax1, ax2) = plt.subplots(2)
sns.regplot(x, y, ax=ax1)
sns.kdeplot(x, ax=ax2)另一种是利用返回的对象
data = np.random.normal(size=(20, 6)) + np.arange(6) / 2
ax = sns.boxplot(data=data)
ax.set_title('abc')

tips = sns.load_dataset("tips")
grid = sns.relplot(x="total_bill", y="tip", hue="smoker", data=tips)
grid.axes[0,0].set_title('abc')色板的使用
使用色板
# 展示颜色
sns.palplot(sns.light_palette("green"))

# 调用颜色1
set1 = sns.color_palette("Set1", 2)
sns.relplot(x="total_bill", y="tip", hue="smoker",
            palette=set1, data=tips)

# 调用颜色2
with sns.color_palette("Set1"):
    sns.relplot(x="total_bill", y="tip", hue="smoker", data=tips)

# 全局设置
sns.set_palette("husl")主题设置
主题全局设置
sns.set(style="darkgrid")
sns.set_style("darkgrid", {"axes.facecolor": ".9"})

# 恢复默认
sns.set()局部设置
with sns.axes_style("white"):
    sns.relplot(x="total_bill", y="tip", hue="smoker", data=tips)共有5种主题
darkgrid(默认)
whitegrid
dark
white
ticks一些细节参数可以用下面命令查到
sns.axes_style()参数主题有四种
notebook(默认)
paper
talk
poster用下面方式设置
sns.set_context("paper")资料推荐


  • matplotlib官网教程
  • 50种常见可视化
  • Program Creek
  • seaborn官方教程
  • matplotlib官网API
  • 绘图: matplotlib核心剖析
专栏信息

专栏主页:Data Analysis
专栏目录:目录
版本说明:软件及包版本说明
使用道具 举报
| 来自北京 用Deepseek满血版问问看
DAIWEISI3 | 未知
对于matplotlib的绘图内容基本都覆盖到了,应付日常使用已经足够了,[赞]
用Deepseek满血版问问看
回复
使用道具 举报
topone8877 | 来自北京
比较systemic
回复
使用道具 举报
叮叮当 | 来自北京
非常棒,收藏了!
回复
使用道具 举报
丁侦球 | 来自广东
收藏吃灰
回复
使用道具 举报
qhy3719 | 来自北京
为什么我觉得还不如excel呢
回复
使用道具 举报
快速回复
您需要登录后才可以回帖 登录 | 立即注册

当贝投影