Matplotlib中图层叠加问题

参考链接:https://blog.csdn.net/sunsoda/article/details/82431770

matplotlib中的多图层叠加的问题

问题的引出

老板提出希望在之前绘制的降水分布图基础上,叠加上一下线路、变电站的分布。简单一想这个任务很简单,只需要知道线路,变电站经纬度,再叠加到图层即可。但是在实际操作却遇到一个小问题,即如何保证叠加的顺序,通过查阅matplotlib手册了解到一个set_zorder这个属性,可以完美解决图层叠加问题,因此在这里记录以下。

我们先从下面这个例子讲起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 28 08:28:12 2020

@author: 23820
"""

import numpy as np
import pandas as pd

import matplotlib.lines as mlines
import matplotlib.patches as mpatches
import matplotlib as mpl
import matplotlib.pyplot as plt
##################################################
# 解决中文字体显示问题
font = {
'family' : 'SimHei'
};
mpl.rc('font', **font);
##################################################
# 随机设置坐标值
# %matplotlib inline
N = 3
x = np.random.rand(N)
y = np.random.rand(N)
##################################################
fig = plt.figure(figsize=[8,4])
ax = fig.add_subplot(121)
# 绘制circle
for xi,yi in zip(x,y):
circle = mpatches.Circle((xi,yi), 0.05, ec="blue",fc='blue')
ax.add_patch(circle)
# 绘制Line
line = mlines.Line2D(x,y,lw=3.,ls='-',alpha=1,color='red')
ax.add_line(line)
ax.set_title('先圆后线')

############################################
ax = fig.add_subplot(122)
# 绘制Line
line = mlines.Line2D(x,y,lw=3.,ls='-',alpha=1,color='red')
ax.add_line(line)

# 绘制circle
for xi,yi in zip(x,y):
circle = mpatches.Circle((xi,yi), 0.05, ec="blue",fc='blue')
ax.add_patch(circle)
ax.set_title('先线后圆')

1

这个例子,正是我在作图时遇到的问题,无论我是先画圆,还是先画线条,圆圈总是在线条之下,如何才能把圆圈调换到线条上来呢?这里我就联想到PS处理图片时最终的概念图层,调换不同的图层的叠加顺序,即会呈现出不一样的图片,那么在matplotlib中,是否也存在这样的接口,可以让我来设置图层的叠加顺序呢?通过查阅matplolib的官网终于找到这个大杀器set_zorder

set_zorder

set_zorder顾名思义,set:设置,z:对象,order:顺序,set_zorder即设置对象的顺序。matplotlib为多个对象都提供了这个函数。在官网搜索set_zorder即可看到

  • matplotlib.artist.Artist.set_zorder (Python method, in matplotlib.artist.Artist.set_zorder)
  • matplotlib.axes.Axes.set_zorder (Python method, in matplotlib.axes.Axes.set_zorder)
  • matplotlib.axis.Axis.set_zorder (Python method, in matplotlib.axis.Axis.set_zorder)
  • matplotlib.axis.Tick.set_zorder (Python method, in matplotlib.axis.Tick.set_zorder)
  • matplotlib.axis.XAxis.set_zorder (Python method, in matplotlib.axis.XAxis.set_zorder)
  • matplotlib.axis.XTick.set_zorder (Python method, in matplotlib.axis.XTick.set_zorder)
  • matplotlib.axis.YAxis.set_zorder (Python method, in matplotlib.axis.YAxis.set_zorder)-
  • matplotlib.axis.YTick.set_zorder (Python method, in matplotlib.axis.YTick.set_zorder)

可以看出,针对matplotlib中不同对象,都提供了set_zorder这个method,其规则如下:

Set the zorder for the artist. Artists with lower zorder values are drawn first. order值越小,越先画

因此,在我们上面那个case,就可以完美破解,希望圆圈画在线上,我们只需要把圆圈设个较大的zorder值,线条设个较小的zorder值即可

主要添加了circle.set_zorder(1)line.set_zorder(0)这两行代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fig = plt.figure(figsize=[8,4])
ax = fig.add_subplot(121)
# 绘制circle
for xi,yi in zip(x,y):
circle = mpatches.Circle((xi,yi), 0.05, ec="blue",fc='blue')
circle.set_zorder(0)
ax.add_patch(circle)
# 绘制Line
line = mlines.Line2D(x,y,lw=3.,ls='-',alpha=1,color='red')

line.set_zorder(1)#设置后面显示

ax.add_line(line)
ax.set_title('先圆后线')

ax = fig.add_subplot(122)
# 绘制circle
for xi,yi in zip(x,y):
circle = mpatches.Circle((xi,yi), 0.05, ec="blue",fc='blue')
circle.set_zorder(1)
ax.add_patch(circle)
# 绘制Line
line = mlines.Line2D(x,y,lw=3.,ls='-',alpha=1,color='red')

line.set_zorder(0)#设置优先显示

ax.add_line(line)
ax.set_title('先线后圆')
t=ax.get_xaxis()

2

try

最后现学现卖,送朵花花给大家,虽然这个代码不用zorder似乎也可以~~哈哈哈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
fig = plt.figure(figsize=[8,4])
ax = fig.add_subplot(121)
# 绘制circle
x=np.array([0.4,0.5,0.6,0.55,0.45])*2
y=np.array([0.4,0.5,0.4,0.3,0.3])*2

colors=['red','orange','yellow','green','blue']
for i,xi,yi in zip(np.arange(len(x)),x,y):
circle = mpatches.Circle((xi,yi), 0.2, ec='pink',fc='pink')
circle.set_zorder(i)
ax.add_patch(circle)

circle = mpatches.Circle((1,0.8), 0.1, ec="white",fc="white")
ax.add_patch(circle)
circle.set_zorder(10)

x=np.array([0.4,0.5,0.6,0.55,0.45])*2+1
y=np.array([0.4,0.5,0.4,0.3,0.3])*2

xl=[1,1]
yl=[0,0.55]
line = mlines.Line2D(xl,yl,lw=3.,ls='-',alpha=1,color='green')
line.set_zorder(0)
ax.add_line(line)
colors=['red','orange','yellow','green','blue']
for i,xi,yi in zip(np.arange(len(x)),x,y):
circle = mpatches.Circle((xi,yi), 0.2, ec=colors[i],fc=colors[i])
circle.set_zorder(i)
ax.add_patch(circle)

circle = mpatches.Circle((2,0.8), 0.1, ec="white",fc="white")
ax.add_patch(circle)
circle.set_zorder(10)

xl=[2,2]
yl=[0,0.55]
line = mlines.Line2D(xl,yl,lw=3.,ls='-',alpha=1,c='green')
line.set_zorder(0)
ax.add_line(line)
ax.set_xlim([0,2.5])
ax.set_ylim([0,2.5])

3


Matplotlib中图层叠加问题
https://fulequn.github.io/2020/09/Article202009281/
作者
Fulequn
发布于
2020年9月28日
许可协议