matplotlib基础--2

5 图例

 

matplotlib中的图例是帮助观察者理解图像数据的重要工具。图列通常包含在图像中,用于解释不同的颜色、形状、标签和其它元素。

1)主要参数

当不设置图例的参数时,默认的图例是这样的。

x = np.linspace(0,1,50)
y1 = np.sin(x*2*np.pi)
y2 = np.cos(x*2*np.pi)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x,y1,label="sin")
ax.plot(x,y2,label="cos")
ax.legend()

matplotlib基础--2_第1张图片

 图例就是左下角的那部分。图例的主要参数,其实也就是上例ax.lengend()函数的主要参数:

  1. 图例位置相关:loc(位置字符串)
  2. 边框相关:facecolor(背景色),edgecolor(边框颜色),shadow(是否设置阴影),framemon(是否有边框和背景)
  3. 图例的列数:默认是1行多列的格式,ncol(列的个数)。

2)配置示例

通过示例来演示常用设置。

2.1 图例位置
x = np.linspace(0,1,50)
y1 = np.sin(x*2*np.pi)
y2 = np.cos(x*2*np.pi)

fig, ax = plt.subplots(3,3)
fig.set_size_inches(10,10)

locations = [
    ["lower left", "lower center", "lower right"],
    ["center left", "center", "center right"],
    ["upper left", "upper center", "upper right"]
]

for i in range(3):
    for j in range(3):
        ax[i,j].plot(x, y1, label="sin")
        ax[i,j].plot(x, y2, label="cos")
        ax[i][j].legend(loc=locations[i][j])

matplotlib基础--2_第2张图片

 上面的示例显示了不同位置的图列。

2.2 图例边框

边框可以设置边框的背景色,边框颜色和是否有阴影。

x = 2 * np.pi * np.linspace(0,1,50)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x, y1, label="sin",c="red")
ax.plot(x, y2, label="cos",c="black")
ax.legend(facecolor="yellow", edgecolor="green",shadow=True)

matplotlib基础--2_第3张图片

上例中,背景色yellow,边框green,阴影设置为True。

设置无边框比较简单,frameon=False即可。

x = 2 * np.pi * np.linspace(0,1,50)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(frameon=False)

matplotlib基础--2_第4张图片

2.3 图例分列

图例默认是一列多行的格式,比如上面的各个示例,图例都是一次竖着排列下来的。可以通过ncols属性,让图例横着排列。

x = 2 * np.pi * np.linspace(0,1,50)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8, 0.8])
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.legend(frameon=False, loc="upper center", ncol=2)

matplotlib基础--2_第5张图片

上面的示例,图例(legend)设置为两列,位与上方中间位置。

2.4 多个图例

 一般的图形只有一个图例,比如上面的都是这样的,sin和cos都在一个图例中。如果图例太多,或者多个图例之间关系不大,也可以创建多个图列。

from matplotlib.legend import Legend

x = 4 * np.pi * np.linspace(0,1,50)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.sin(x+np.pi/4)
y4 = np.cos(x+np.pi/4)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
legends = []
legends += ax.plot(x, y1, label="sin(x)")
legends += ax.plot(x, y2, label="cos(x)")
legends += ax.plot(x, y3, label="sin(x+$\pi/4)$")
legends += ax.plot(x, y4, label="cos(x+$\pi/4)$")

ax.legend(legends[:2],["sin(x)","cos(x)"], loc="upper right")
leg = Legend(ax, legends[2:], ["sin(x+$\pi/4)$","cos(x+$\pi/4$)"],loc="lower left")
ax.add_artist(leg)

matplotlib基础--2_第6张图片

上面的示例中4条曲线,分成了2个图例来说明。一个图列在右上角,一个图例在左下角。

2.5 图例中不同大小的点

最后,介绍一种更复杂的图例显示方式。首先生成几种主要编程语言的热度,生成图例的时候,给3个主要节点500,5000和10000设置点的大小比例与图中的各个散点数据保持一致。

x=["Python", "C/C++", "Java", "Go", "Shell", "Ruby", "Lua"]
y=np.array([10000, 25000, 20000,1500,3000,4000,1000])

fig = plt.figure(figsize=[8,6])
plt.scatter(x,y,c=np.log10(y), s=y/32)

for hot in [500,5000,10000]:
    plt.scatter([],[], c='b', s=hot/32, alpha=0.3, label=str(hot)+"(hot)")
    
plt.legend(scatterpoints=1, labelspacing=1.5,title="hot legend", frameon=False)

matplotlib基础--2_第7张图片

3) 总结

图例可以设置成各式各样,本篇介绍的图例设置方式并不是仅仅为了美观,更重要的是利用这些设置方式帮助用户能够达到以下目的:

  1. 帮助观察者快速了解图形数据:图例提供了关于图像数据的简洁,易于理解的解释,使得观察者能够快速了解图像的主题和内容。
  2. 帮助观察者更好地理解图像细节:在一些复杂地图像中,观察者可能需要花费很多时间才能理解其中的细节。图例可以提供关于图像细节的额外信息,使得观察者能够更好地理解图像。
  3. 帮助观察者发现图像中地异常或者重要信息:图例可以用于指出图像中地异常或者重要信息,帮助观察者更好的理解和分析图像。

6 文本标注

matplotlib文本和标注可以为数据和图形之间提供额外的信息,帮助观察者更好地理解数据和图形的含义。

文本用于图形中添加注释或者提供更详细的信息,以帮助观察者理解图形的含义。标注则是一种更加细粒度的文本信息,可以被用来为特定的数据点或区域提供更详细的信息。本节通过示例一次介绍文本和标注的常用使用方式。

1 文本

文本在图形中主要用在标题,坐标轴,图形中一些说明的地方。

1.1 颜色和字体
x = np.linspace(0, 10, 50)
y = np.power(x,2)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])

ax.set_title("Caption", fontdict={"fontsize":25, "color":"green"})
ax.set_xlabel("x axis", fontdict={"fontsize":20, "color":"blue"})
ax.set_ylabel("y axis", fontdict={"fontsize":20, "color":"yellow"})
ax.text(2,60,"f(x) = x * x", fontdict={"fontsize":15, "color":"black"})

ax.plot(x,y,label="f(x) = x * x")
ax.legend()

matplotlib基础--2_第8张图片

 需要掌握的部分就是fontdict这个参数,这个字典还有其它参数可以控制字体,这里只演示了两个常用的参数:

  1. fontsize:设置字体大小
  2. color:设置字体颜色

1.2 latex公式

上面的示例中,f(x) = x * x可以latex的方式来显示。

latex让能够显示各种复杂的数学公式,让文本看起来和数学书中一样。

x = np.linspace(0, 10, 50)
y = np.power(x,2)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])

ax.set_title("Caption", fontdict={"fontsize":25, "color":"green"})
ax.set_xlabel("x", fontdict={"fontsize":20, "color":"blue"})
ax.set_ylabel("$x^2$", fontdict={"fontsize":20, "color":"red"})
ax.text(2,60,"$f(x) = x^2$", fontdict={"fontsize":15, "color":"black"})

ax.plot(x,y,label="$f(x) = x^2$")
ax.legend()

matplotlib基础--2_第9张图片

 上面将Y轴的文本和图形中间的数学公式改成了latex格式。

2)标注

图形添加标注时,一般包含2个部分,一个指向数据的箭头,一段说明文字。

设置标志的核心参数是:

  1. xy:这是待标注的数据点的坐标。
  2. xytext:标注文本的坐标,一般是文本的左上角的点。
  3. bbox:文本框的样式字典
  4. arrowprops:箭头的样式字典

下面的示例中,通过设置上面4个参数来演示几种常用的标注:

x = np.linspace(1,10,10)
y = np.array([88,80,25,66,40,70,66,10,90,5])

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x, y)

ax.annotate(
    "the first value",
    xy=(1,88),
    xytext=(0.3,70),
    arrowprops={"arrowstyle": "->", "connectionstyle": "arc3,rad=-0.5"},
)

ax.annotate(
    "point 1",
    xy=(3,25),
    xytext=(1.8,10),
    bbox={"boxstyle":"round","fc":"none","ec":"g"},
    arrowprops={"arrowstyle":"->"}
)

ax.annotate(
    "max",
    xy=(9,90),
    xytext=(6,85),
    bbox={"boxstyle":"round","alpha":0.1},
    arrowprops={"arrowstyle":"wedge,tail_width=0.8","alpha":0.1}
)

ax.annotate(
    "point 2",
    xy=(4,66),
    xytext=(3,85),
    bbox={"boxstyle":"round","fc":"lightblue","ec":"r"},
    arrowprops={"arrowstyle":"fancy"},
)

matplotlib基础--2_第10张图片

  1.  first value:设置箭头的弯曲度
  2. point 1:设置了边框
  3. point 2:设置了边框和背景色,同时设置了另一种箭头样式。
  4. max:设置了边框和另一种箭头的透明度。

3)总结

在使用matplotlib进行数据分析可视化时,合理使用文本和标注可以大大提供图形的可读性和易懂性,帮助观察者更好地理解数据和图形的含义。

7 绘图配置

matplotlib提供了大量配置参数,这些参数可以但不限于让我们从整体上调整通过matplotlib绘制的图形样式,这里的参数还有很多是功能性的,和其它工具结合时需要用的配置。

print(len(plt.rcParams))

结果:305.

本节仅介绍几个常用参数,目的是了解参数的使用方法和产生的效果。

1)坐标轴

首先是坐标轴相关的配置,通过下面的代码可以看看有多个关于坐标轴的配置:

import matplotlib.pyplot as plt

count = 0

for key,val in plt.rcParams.items():
    if key.startswith("axes"):
        print(key, " = ", val)
        count += 1
        
print(f"axes 相关设置有:{count} 个")
axes.autolimit_mode  =  data
axes.axisbelow  =  line
axes.edgecolor  =  black
axes.facecolor  =  white
axes.formatter.limits  =  [-5, 6]
axes.formatter.min_exponent  =  0
axes.formatter.offset_threshold  =  4
axes.formatter.use_locale  =  False
axes.formatter.use_mathtext  =  False
axes.formatter.useoffset  =  True
axes.grid  =  False
axes.grid.axis  =  both
axes.grid.which  =  major
axes.labelcolor  =  black
axes.labelpad  =  4.0
axes.labelsize  =  medium
axes.labelweight  =  normal
axes.linewidth  =  0.8
axes.prop_cycle  =  cycler('color', ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'])
axes.spines.bottom  =  True
axes.spines.left  =  True
axes.spines.right  =  True
axes.spines.top  =  True
axes.titlecolor  =  auto
axes.titlelocation  =  center
axes.titlepad  =  6.0
axes.titlesize  =  large
axes.titleweight  =  normal
axes.titley  =  None
axes.unicode_minus  =  True
axes.xmargin  =  0.05
axes.ymargin  =  0.05
axes3d.grid  =  True
axes 相关设置有:33 个

 一个有33个关于坐标轴的配置。

x = np.linspace(0,1,50) * 4 * np.pi
y1 = np.sin(x)
y2 = np.cos(x)

plt.rcParams.update(plt.rcParamsDefault)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x,y1, label="sin(x)")
ax.plot(x,y2, label="cos(x)")
ax.legend()

 matplotlib基础--2_第11张图片

 修改了背景色,边框和网格:

x = np.linspace(0,1,50) * 4 * np.pi
y1 = np.sin(x)
y2 = np.cos(x)

plt.rcParams.update(plt.rcParamsOrig)
plt.rc("axes",facecolor="yellow",edgecolor="red",grid=True)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x,y1, label="sin(x)")
ax.plot(x,y2, label="cos(x)")
ax.legend()

matplotlib基础--2_第12张图片

 2) 网格

关于网格,除了通过坐标轴来设置,它还有自己的一些专用的设置选项:

count = 0
for key, val in plt.rcParams.items():
    if key.startswith("grid"):
        print(key, " = ", val)
        count += 1
        
print(f"grid 相关设置有:{count}个")

运行结果:

grid.alpha  =  1.0
grid.color  =  #b0b0b0
grid.linestyle  =  -
grid.linewidth  =  0.8
grid 相关设置有:4个

总共有4个相关的设置,设置看看效果。

代码和上面类似,如下:

x = np.linspace(0,1,50) * 4 * np.pi
y1 = np.sin(x)
y2 = np.cos(x)

plt.rcParams.update(plt.rcParamsOrig)
plt.rc("axes",grid=True)
plt.rc("grid", linestyle="-.",linewidth=1.5, color="blue")

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x,y1, label="sin(x)")
ax.plot(x,y2, label="cos(x)")
ax.legend()

运行结果: 

matplotlib基础--2_第13张图片

 3) 刻度的相关参数:

xcount = 0
ycount = 0

for key, val in plt.rcParams.items():
    if key.startswith("xtick"):
        print(key, " = ", val)
        xcount += 1
    if key.startswith("ytick"):
        print(key, " = ", val)
        ycount += 1
        
print(f"xtick 相关设置有:{xcount}个")
print(f"ytick 相关设置有:{ycount}个")

运行结果:

xtick.alignment  =  center
xtick.bottom  =  True
xtick.color  =  black
xtick.direction  =  out
xtick.labelbottom  =  True
xtick.labelsize  =  medium
xtick.labeltop  =  False
xtick.major.bottom  =  True
xtick.major.pad  =  3.5
xtick.major.size  =  3.5
xtick.major.top  =  True
xtick.major.width  =  0.8
xtick.minor.bottom  =  True
xtick.minor.pad  =  3.4
xtick.minor.size  =  2.0
xtick.minor.top  =  True
xtick.minor.visible  =  False
xtick.minor.width  =  0.6
xtick.top  =  False
ytick.alignment  =  center_baseline
ytick.color  =  black
ytick.direction  =  out
ytick.labelleft  =  True
ytick.labelright  =  False
ytick.labelsize  =  medium
ytick.left  =  True
ytick.major.left  =  True
ytick.major.pad  =  3.5
ytick.major.right  =  True
ytick.major.size  =  3.5
ytick.major.width  =  0.8
ytick.minor.left  =  True
ytick.minor.pad  =  3.4
ytick.minor.right  =  True
ytick.minor.size  =  2.0
ytick.minor.visible  =  False
ytick.minor.width  =  0.6
ytick.right  =  False
xtick 相关设置有:19个
ytick 相关设置有:19个

X轴刻度和Y轴刻度的相关设置各有19个。

设置方法和效果如下:

x = np.linspace(0,1,50) * 4 * np.pi
y1 = np.sin(x)
y2 = np.cos(x)

plt.rcParams.update(plt.rcParamsDefault)
plt.rc("xtick", color="red", direction="in")
plt.rc("ytick", color="blue")

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x,y1, label="sin(x)")
ax.plot(x,y2, label="cos(x)")
ax.legend()

运行结果:

matplotlib基础--2_第14张图片上面的示例分布设置X轴和Y轴的眼色,以及X轴的direction, direction="in"表示刻度的小短线在图形的内部。Y轴没有设置这个属性,它的刻度线在图形外的。

4)颜色列表

绘制图形的时候,一个图形中有多条曲线时,每条曲线默认就会使用不同的颜色。这是因为配置有一个默认的颜色列表,绘制多个图形时,会依次使用其中的颜色。

print(plt.rcParams["axes.prop_cycle"])

运行结果:

cycler('color', ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'])

 修改这个默认的颜色列表,看看变化效果:

x = np.linspace(0,1,50) * 4 * np.pi
y1 = np.sin(x)
y2 = np.cos(x)

from matplotlib import cycler

colors= cycler(
    "color", ["#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"]
)

plt.rcParams.update(plt.rcParamsDefault)
plt.rc("axes", prop_cycle=colors)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
ax.plot(x, y1, label="sin(x)")
ax.plot(x, y2, label="cos(x)")

ax.legend()

matplotlib基础--2_第15张图片

 改变颜色列表之后,两条曲线的颜色都变了。

绘制曲线或者其它图形时,其实是有参数可以指定颜色的,为什么还需要这个颜色列表的配置?这是因为,如果我们能够确定报告的风格,那么就可以在一开始就根据报告的风格设置好这个颜色列表。

然后绘制各种图形时就不需要指定颜色,极大简化后续的代码,也提供了代码的可维护性。

5) 总结

在配置rcParams时,可以根据需要修改各种选项,以达到更好的显示效果。

8 样式表

现在matplotlib已经内置了很多样式表,通过使用不同的样式表,可以整体改变绘制图形的风格,不用再调整一个个显示参数。

1)样式表的使用

1.1 所有内置样式表

首先查看内置的样式表:

import matplotlib.pyplot as plt
plt.style.available
['Solarize_Light2',
 '_classic_test_patch',
 'bmh',
 'classic',
 'dark_background',
 'fast',
 'fivethirtyeight',
 'ggplot',
 'grayscale',
 'seaborn',
 'seaborn-bright',
 'seaborn-colorblind',
 'seaborn-dark',
 'seaborn-dark-palette',
 'seaborn-darkgrid',
 'seaborn-deep',
 'seaborn-muted',
 'seaborn-notebook',
 'seaborn-paper',
 'seaborn-pastel',
 'seaborn-poster',
 'seaborn-talk',
 'seaborn-ticks',
 'seaborn-white',
 'seaborn-whitegrid',
 'tableau-colorblind10']
1.2 使用样式表的方式

使用样式表的方式有两种:一个是全局全局样式表设置,比如:

plt.style.use("ggplot")

随后的代码中,所有绘制的图形都是ggplot风格。

另一种局部样式表设置,比如:

with plt.style.context("classic"):
    # draw figure
    pass

这种方式,样式表只在with范围内效率。

2) 不同样式表的效率

下面演示几种风格差异比较大的样式表。首选,装载一个绘制图形的函数。

def draw():
    x = np.linspace(1,10,10)
    y = np.random.randint(10,100,10)
    
    fig = plt.figure(figsize=[6,4])
    fig.add_subplot(211)
    plt.plot(x,y)
    
    fig.add_subplot(212)
    plt.hist(y)
    
draw()

matplotlib基础--2_第16张图片

 2.1 classic风格
with plt.style.context("classic"):
    draw()

matplotlib基础--2_第17张图片

 2.2 solarize_Light2风格
with plt.style.context("Solarize_Light2"):
    draw()

matplotlib基础--2_第18张图片

2.3  bmh风格
with plt.style.context("bmh"):
    draw()

matplotlib基础--2_第19张图片

 2.4 dark_background风格
with plt.style.context("dark_background"):
    draw()

matplotlib基础--2_第20张图片

 2.5 fast风格
with plt.style.context("fast"):
    draw()

matplotlib基础--2_第21张图片

2.6  ggplot风格
with plt.style.context("ggplot"):
    draw()

matplotlib基础--2_第22张图片

2.7 seaborn风格 

matplotlib支持多种seaborn风格。这是使用默认的seaborn风格。

with plt.style.context("seaborn"):
    draw()

matplotlib基础--2_第23张图片

 3) 总结

内置的样式表方便易用,提供了许多预定义的样式,可以快速帮助我们创建美观的图表。使用内置的样式表还有个好处是可以保持图表的统一风格,使得图表具有更高的刻度性和可维护性。matplotlib提供的丰富样式表,可以满足不同类型的绘图需求,并且还可以通过自定义样式表来实现更加个性的绘图效果。

你可能感兴趣的:(python,matplotlib)