Python--Matplotlib(操作示例)

官方文档:https://matplotlib.org/Matplotlib.pdf
官方代码: Python source code , Jupyter notebooks

文章目录

该库包含可以使用Matplotlib进行的许多操作的示例。

线,条和标记(Lines, bars and markers)

简单绘图(Simple Plot)

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# 绘图数据
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)

fig, ax = plt.subplots()
ax.plot(t, s)

ax.set(xlabel='time (s)', ylabel='voltage (mV)',
       title='About as simple as it gets, folks')
ax.grid()

fig.savefig("test.png")
plt.show()

在这里插入图片描述

堆积条形图(Stacked bar chart)

这是使用创建带有误差线的堆积条形图的示例bar。注意用于误差线的参数yerr,并在bottom将女性条堆叠在男性条的顶部。

import matplotlib.pyplot as plt

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 35, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]
men_std = [2, 3, 4, 1, 2]
women_std = [3, 5, 2, 3, 3]
width = 0.35       #条形的宽度:也可以是len(x)序列

fig, ax = plt.subplots()

ax.bar(labels, men_means, width, yerr=men_std, label='Men')
ax.bar(labels, women_means, width, yerr=women_std, bottom=men_means,
       label='Women')

ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.legend()

plt.show()

在这里插入图片描述
Axes.bar(self, x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs):
绘制条形图。这些条以给定的对齐方式位于x处。它们的尺寸由高度和宽度给定。垂直基线为底部(默认为0)。许多参数可以采用应用于所有条形的单个值或一系列值,每个条形一个。

  1. label: object – 设置将在图例中显示的标签。
  2. xerr, yerr: float or array-like of shape(N,) or shape(2, N), optional --如果不是“None”,则在条提示中添加水平/垂直错误栏。值是相对于数据的+/-大小:
  3. x: float或类似数组 – 条形的x坐标
  4. height, width: float或类似数组 – 条形的高(宽)度。
  5. bottom:float或类似数组,默认值:0 – 条形起始的y坐标。
  6. align:{‘center’,‘edge’},默认值:‘center’ – 条形与x坐标的对齐方式。

带标签的分组条形图(Grouped bar chart with labels)

本示例说明如何创建分组的条形图以及如何使用标签注释条形图。

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

x = np.arange(len(labels))  # 标签位置
width = 0.35  # 条的宽度

fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')

# 为标签,标题和自定义x轴刻度标签等添加一些文本
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 垂直方向偏移3个点
                    textcoords="offset points",
                    ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

fig.tight_layout()

plt.show()

在这里插入图片描述
Axes.annotate(self, text, xy, *args, **kwargs):

  1. text: str – 注释文字。
  2. xy: (float,float) – 要注释的点(x,y)。坐标系由xycoords确定。
  3. xytext: (float,float),默认值:xy – 放置文本的位置(x,y)。坐标系由textcoords确定。
  4. textcoords: str或Artist或Transform或Callable或 (float,float),默认值:xycoords的值。
  5. xycoords: str或Artist或Transform或Callable或 (float,float),默认值:“ data” – 使用要注释的对象的坐标系。
  6. ha: ‘center’, ‘right’, ‘left’。
  7. va: ‘top’, ‘bottom’, ‘center’, ‘baseline’, ‘center_baseline’。

水平条形图(Horizontal bar chart)

此示例展示了一个简单的水平条形图。

import matplotlib.pyplot as plt
import numpy as np

# 修复随机状态以提高可重复性
np.random.seed(19680801)


plt.rcdefaults()
fig, ax = plt.subplots()

# Example data
people = ('Tom', 'Dick', 'Harry', 'Slim', 'Jim')
y_pos = np.arange(len(people))
performance = 3 + 10 * np.random.rand(len(people))
error = np.random.rand(len(people))

ax.barh(y_pos, performance, xerr=error, align='center')
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.invert_yaxis()  # 标签从上到下阅读
ax.set_xlabel('Performance')
ax.set_title('How fast do you want to go today?')

plt.show()

在这里插入图片描述

间隙的条形图(Broken Barh)

制作一个“折断”的水平条形图,即有间隙的条形图。

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.broken_barh([(110, 30), (150, 10)], (10, 9), facecolors='tab:blue')
ax.broken_barh([(10, 50), (100, 20), (130, 10)], (20, 9),
               facecolors=('tab:orange', 'tab:green', 'tab:red'))
ax.set_ylim(5, 35)
ax.set_xlim(0, 200)
ax.set_xlabel('seconds since start')
ax.set_yticks([15, 25])
ax.set_yticklabels(['Bill', 'Jim'])
ax.grid(True)
ax.annotate('race interrupted', (61, 25),
            xytext=(0.8, 0.9), textcoords='axes fraction',
            arrowprops=dict(facecolor='black', shrink=0.05),
            fontsize=16,
            horizontalalignment='right', verticalalignment='top')

plt.show()

在这里插入图片描述

绘制分类变量(Plotting categorical variables)

如何在Matplotlib中使用分类变量。 Matplotlib允许您将类别变量直接传递给许多绘图函数,即

import matplotlib.pyplot as plt

data = {'apple': 10, 'orange': 15, 'lemon': 5, 'lime': 20}
names = list(data.keys())
values = list(data.values())

fig, axs = plt.subplots(1, 3, figsize=(9, 3), sharey=True)
axs[0].bar(names, values)
axs[1].scatter(names, values)
axs[2].plot(names, values)
fig.suptitle('Categorical Plotting')

在这里插入图片描述
matplotlib.pyplot.subplots(nrows=1, ncols=1, *, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw):
创建一个图和一组子图。该实用程序包装器使您可以在一次调用中方便地创建子图的通用布局,包括封闭的图形对象。

  1. nrows, ncols: int, default: 1 – 子图网格的行数/列数。
  2. sharex, sharey: bool or {‘none’, ‘all’, ‘row’, ‘col’}, default: False – 控制x (sharex) 或 y (sharey) 之间的属性共享。
  3. squeeze:bool,默认值:True
  4. subplot_kw: dict, optional – 带有传递给用于创建每个子图的add_subplot调用的关键字的字典。
  5. gridspec_kw: dict, optional – 使用传递给用于创建子图放置的网格的GridSpec构造函数的关键字的字典。
  6. fig_kw:所有其他关键字参数都传递给pyplot.figure调用。
cat = ["bored", "happy", "bored", "bored", "happy", "bored"]
dog = ["happy", "happy", "happy", "happy", "bored", "bored"]
activity = ["combing", "drinking", "feeding", "napping", "playing", "washing"]

fig, ax = plt.subplots()
ax.plot(activity, dog, label="dog")
ax.plot(activity, cat, label="cat")
ax.legend()

plt.show()

在这里插入图片描述

绘制两个信号的相干(Plotting the coherence of two signals)

一个示例,显示了如何绘制两个信号的相干性。

import numpy as np
import matplotlib.pyplot as plt

# 修复随机状态以提高可重复性
np.random.seed(19680801)

dt = 0.01
t = np.arange(0, 30, dt)
nse1 = np.random.randn(len(t))                 # 白噪声1
nse2 = np.random.randn(len(t))                 # 白噪声2

# 两个信号的相干部分为10Hz加上随机部分
s1 = np.sin(2 * np.pi * 10 * t) + nse1
s2 = np.sin(2 * np.pi * 10 * t) + nse2

fig, axs = plt.subplots(2, 1)
axs[0].plot(t, s1, t, s2)
axs[0].set_xlim(0, 2)
axs[0].set_xlabel('time')
axs[0].set_ylabel('s1 and s2')
axs[0].grid(True)

cxy, f = axs[1].cohere(s1, s2, 256, 1. / dt)
axs[1].set_ylabel('coherence')

fig.tight_layout()
plt.show()

在这里插入图片描述

CSD示例(CSD Demo)

计算两个信号的互谱密度(cross spectral density)。

import numpy as np
import matplotlib.pyplot as plt


fig, (ax1, ax2) = plt.subplots(2, 1)
# 在子图之间留出一些额外的空间
fig.subplots_adjust(hspace=0.5)

dt = 0.01
t = np.arange(0, 30, dt)

# 修复随机状态以提高可重复性
np.random.seed(19680801)


nse1 = np.random.randn(len(t))                 # white noise 1
nse2 = np.random.randn(len(t))                 # white noise 2
r = np.exp(-t / 0.05)

cnse1 = np.convolve(nse1, r, mode='same') * dt   # 有色噪声1
cnse2 = np.convolve(nse2, r, mode='same') * dt   # 有色噪声2

# 具有相干部分和随机部分的两个信号
s1 = 0.01 * np.sin(2 * np.pi * 10 * t) + cnse1
s2 = 0.01 * np.sin(2 * np.pi * 10 * t) + cnse2

ax1.plot(t, s1, t, s2)
ax1.set_xlim(0, 5)
ax1.set_xlabel('time')
ax1.set_ylabel('s1 and s2')
ax1.grid(True)

cxy, f = ax2.csd(s1, s2, 256, 1. / dt)
ax2.set_ylabel('CSD (db)')
plt.show()

在这里插入图片描述

带误差带的曲线(Curve with error band)

此示例演示如何围绕参数化曲线绘制误差带。
参数化曲线 x(t), y(t) 可以直接用plot绘制。

import numpy as np
from scipy.interpolate import splprep, splev

import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch

N = 400
t = np.linspace(0, 2 * np.pi, N)
r = 0.5 + np.cos(t)
x, y = r * np.cos(t), r * np.sin(t)

fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()

在这里插入图片描述
误差带可以用来表示曲线的不确定性。在这个例子中,我们假设误差可以表示为标量误差,它描述了垂直于曲线的每个点的不确定性。

我们使用PathPatch将此错误可视化为路径周围的彩色条带。面片由两个路径段(xp, yp)和(xn,yn)创建,这两个路径段垂直于曲线(x, y)移动+/-err。

注:这种使用PathPatch的方法适用于2D中的任意曲线。如果只有标准的y-vs.-x绘图,则可以使用更简单的填充线间距方法(另请参见填充线间距区域)。

# 误差幅度取决于曲线参数* t *
# (实际值是任意的,仅用于说明目的):
err = 0.05 * np.sin(2 * t) ** 2 + 0.04 + 0.02 * np.cos(9 * t + 2)

# 通过样条导数计算法线
tck, u = splprep([x, y], s=0)
dx, dy = splev(u, tck, der=1)
l = np.hypot(dx, dy)
nx = dy / l
ny = -dx / l

# 错误的结束点
xp = x + nx * err
yp = y + ny * err
xn = x - nx * err
yn = y - ny * err

vertices = np.block([[xp, xn[::-1]],
                     [yp, yn[::-1]]]).T
codes = Path.LINETO * np.ones(len(vertices), dtype=Path.code_type)
codes[0] = codes[len(xp)] = Path.MOVETO
path = Path(vertices, codes)

patch = PathPatch(path, facecolor='C0', edgecolor='none', alpha=0.3)

fig, ax = plt.subplots()
ax.plot(x, y)
ax.add_patch(patch)
plt.show()

在这里插入图片描述
matplotlib.patches.PathPatch
一般的多曲线路径片。路径是路径对象。有效的关键字参数包括:

  1. facecolor or fc: color or None – 设置面片颜色。
  2. edgecolor or ec: color or None or ‘auto’ – 设置色块边缘颜色。
  3. alpha: float or None – 设置用于混合的alpha值(并非所有后端都支持)。

误差线限制选择(Errorbar limit selection)

使用参数uplims,lolimbar的lolim在参数栏上选择性地绘制下限和/或上限符号的图示。
或者,您可以使用2xN值在一个方向上绘制误差线。

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
x = np.arange(10)
y = 2.5 * np.sin(x / 20 * np.pi)
yerr = np.linspace(0.05, 0.2, 10)

plt.errorbar(x, y + 3, yerr=yerr, label='both limits (default)')

plt.errorbar(x, y + 2, yerr=yerr, uplims=True, label='uplims=True')

plt.errorbar(x, y + 1, yerr=yerr, uplims=True, lolims=True,
             label='uplims=True, lolims=True')

upperlimits = [True, False] * 5
lowerlimits = [False, True] * 5
plt.errorbar(x, y, yerr=yerr, uplims=upperlimits, lolims=lowerlimits,
             label='subsets of uplims and lolims')

plt.legend(loc='lower right')

在这里插入图片描述

fig = plt.figure()
x = np.arange(10) / 10
y = (x + 0.1)**2

plt.errorbar(x, y, xerr=0.1, xlolims=True, label='xlolims=True')
y = (x + 0.1)**3

plt.errorbar(x + 0.6, y, xerr=0.1, xuplims=upperlimits, xlolims=lowerlimits,
             label='subsets of xuplims and xlolims')

y = (x + 0.1)**4
plt.errorbar(x + 1.2, y, xerr=0.1, xuplims=True, label='xuplims=True')

plt.legend()
plt.show()

在这里插入图片描述
matplotlib.pyplot.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, errorevery=1, capthick=None, *, data=None, **kwargs)
将y与x绘制为线条 和/或 带有误差线的标记。x, y定义数据位置,xerr, yerr定义误差线大小。默认情况下,这将绘制数据标记/线以及错误栏。使用fmt ='none’绘制没有任何数据标记的错误栏。

  1. x, y: float或类似数组 – 数据位置。
  2. xerr, yerr: float或类似数组的shape(N, ) 或shape(2, N),可选。 scalar:所有数据点的对称+/-值。shape(N, ):每个数据点的对称+/-值。shape(2, N):每个条形的-和+值分开。第一行包含较低的错误,第二行包含较高的错误。None:无误差栏。
  3. lolims, uplims, xlolims, xuplims: bool, default: False – 这些参数可用于指示值仅给出上限/下限。在这种情况下,将使用尖号符号进行指示。 lims参数可以是标量,也可以是长度与xerr和yerr相同的数组状。要使用反转轴的限制,必须在errorbar() 之前调用set_xlim或set_ylim。注意棘手的参数名称:设置例如将lolims设置为True意味着y值是True值的下限,因此,只会绘制向上的箭头!

误差线子采样(Errorbar subsampling)

Axes.errorbar的参数errorevery只能用于在数据点的子集上绘制误差线。如果存在许多具有相似错误的数据点,这将特别有用。

import numpy as np
import matplotlib.pyplot as plt

# example data
x = np.arange(0.1, 4, 0.1)
y1 = np.exp(-1.0 * x)
y2 = np.exp(-0.5 * x)

# 可变误差条值示例
y1err = 0.1 + 0.1 * np.sqrt(x)
y2err = 0.1 + 0.1 * np.sqrt(x/2)


fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, sharex=True,
                                    figsize=(12, 6))

ax0.set_title('all errorbars')
ax0.errorbar(x, y1, yerr=y1err)
ax0.errorbar(x, y2, yerr=y2err)

ax1.set_title('only every 6th errorbar')
ax1.errorbar(x, y1, yerr=y1err, errorevery=6)
ax1.errorbar(x, y2, yerr=y2err, errorevery=6)

ax2.set_title('second series shifted by 3')
ax2.errorbar(x, y1, yerr=y1err, errorevery=(0, 6))
ax2.errorbar(x, y2, yerr=y2err, errorevery=(3, 6))

fig.suptitle('Errorbar subsampling')
plt.show()

在这里插入图片描述

事件收集模型(EventCollection Demo)

import matplotlib.pyplot as plt
from matplotlib.collections import EventCollection
import numpy as np

# 修复随机状态以提高可重复性
np.random.seed(19680801)

# 创建随机数据
xdata = np.random.random([2, 10])

# 将数据分为两部分
xdata1 = xdata[0, :]
xdata2 = xdata[1, :]

# 对数据进行排序,以使曲线清晰
xdata1.sort()
xdata2.sort()

# 创建一些y数据点
ydata1 = xdata1 ** 2
ydata2 = 1 - xdata2 ** 3

# 绘制数据
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(xdata1, ydata1, color='tab:blue')
ax.plot(xdata2, ydata2, color='tab:orange')

# 创建标记x个数据点的事件
xevents1 = EventCollection(xdata1, color='tab:blue', linelength=0.05)
xevents2 = EventCollection(xdata2, color='tab:orange', linelength=0.05)

# 创建标记y个数据点的事件
yevents1 = EventCollection(ydata1, color='tab:blue', linelength=0.05,
                           orientation='vertical')
yevents2 = EventCollection(ydata2, color='tab:orange', linelength=0.05,
                           orientation='vertical')

# 将事件添加到轴
ax.add_collection(xevents1)
ax.add_collection(xevents2)
ax.add_collection(yevents1)
ax.add_collection(yevents2)

# 设定极限
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])

ax.set_title('line plot with data points')

# 显示绘图
plt.show()

在这里插入图片描述

事件图模型(Eventplot Demo)

一个事件图,显示具有各种线属性的事件序列。该图以水平和垂直方向显示。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib
matplotlib.rcParams['font.size'] = 8.0

# 修复随机状态以提高可重复性
np.random.seed(19680801)


# 创建随机数据
data1 = np.random.random([6, 50])

# 为每个位置设置不同的颜色
colors1 = ['C{}'.format(i) for i in range(6)]

# 为每组位置设置不同的线属性
# 注意一些重叠
lineoffsets1 = [-15, -3, 1, 1.5, 6, 10]
linelengths1 = [5, 2, 1, 1, 3, 1.5]

fig, axs = plt.subplots(2, 2)

# 创建一个水平图
axs[0, 0].eventplot(data1, colors=colors1, lineoffsets=lineoffsets1,
                    linelengths=linelengths1)

# 创建一个垂直图
axs[1, 0].eventplot(data1, colors=colors1, lineoffsets=lineoffsets1,
                    linelengths=linelengths1, orientation='vertical')

# 创建另一组随机数据。
# 伽玛分布仅用于美学目的
data2 = np.random.gamma(4, size=[60, 50])

# 这次使用单个值作为参数
# 这些值将用于所有数据集(lineoffsets2除外,
# 设置此用法中每个数据集之间的增量)
colors2 = 'black'
lineoffsets2 = 1
linelengths2 = 1

# 创建一个水平图
axs[0, 1].eventplot(data2, colors=colors2, lineoffsets=lineoffsets2,
                    linelengths=linelengths2)


# 创建一个垂直图
axs[1, 1].eventplot(data2, colors=colors2, lineoffsets=lineoffsets2,
                    linelengths=linelengths2, orientation='vertical')

plt.show()

在这里插入图片描述

填充多边形(Filled polygon)

fill() 基于点坐标x,y的列表绘制填充的多边形。本示例使用科赫雪花作为示例多边形。

import numpy as np
import matplotlib.pyplot as plt


def koch_snowflake(order, scale=10):
    """
    返回Koch雪花的点坐标的两个列表x,y。

    Arguments
    ---------
    order : int
        递归深度。
    scale : float
        雪花的范围(底边的边长)。
    """
    def _koch_snowflake_complex(order):
        if order == 0:
            # initial triangle
            angles = np.array([0, 120, 240]) + 90
            return scale / np.sqrt(3) * np.exp(np.deg2rad(angles) * 1j)
        else:
            ZR = 0.5 - 0.5j * np.sqrt(3) / 3

            p1 = _koch_snowflake_complex(order - 1)  # start points
            p2 = np.roll(p1, shift=-1)  # 终点
            dp = p2 - p1  # 连接向量

            new_points = np.empty(len(p1) * 4, dtype=np.complex128)
            new_points[::4] = p1
            new_points[1::4] = p1 + dp / 3
            new_points[2::4] = p1 + dp * ZR
            new_points[3::4] = p1 + dp / 3 * 2
            return new_points

    points = _koch_snowflake_complex(order)
    x, y = points.real, points.imag
    return x, y

基础用法

x, y = koch_snowflake(order=5)

plt.figure(figsize=(8, 8))
plt.axis('equal')
plt.fill(x, y)
plt.show()

在这里插入图片描述

使用关键字参数facecolor和edgecolor修改多边形的颜色。由于在默认的Matplotlib样式中,边缘的线宽为0,因此我们也必须对其进行设置,以使边缘变得可见。

x, y = koch_snowflake(order=2)

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(9, 3),
                                    subplot_kw={'aspect': 'equal'})
ax1.fill(x, y)
ax2.fill(x, y, facecolor='lightsalmon', edgecolor='orangered', linewidth=3)
ax3.fill(x, y, facecolor='none', edgecolor='purple', linewidth=3)

plt.show()

在这里插入图片描述
matplotlib.pyplot.fill(*args, data=None, **kwargs):绘制填充的多边形。

  1. args: sequence of x, y, [color] – 每个多边形由其节点的x和y位置列表定义,并可以选择后面跟一个颜色说明符。有关受支持的颜色说明符,请参见matplotlib.colors。标准颜色循环用于没有颜色说明符的多边形。有: ax.fill(x, y) – 具有默认颜色的多边形;ax.fill(x, y, "b") – 一个蓝色的多边形;ax.fill(x, y, x2, y2) – 两个多边形;ax.fill(x, y, "b", x2, y2, "r") – 蓝色和红色的多边形
  2. data: indexable object, optional – 具有标签数据的对象。

填充线之间的区域(Filling the area between lines)

本示例说明如何使用fill_between为两条线之间的区域着色。

import matplotlib.pyplot as plt
import numpy as np

基本用法(Basic usage)

参数y1和y2可以是标量,表示给定y值处的水平边界。如果仅给出y1,则y2默认为0。

x = np.arange(0.0, 2, 0.01)
y1 = np.sin(2 * np.pi * x)
y2 = 0.8 * np.sin(4 * np.pi * x)

fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=(6, 6))

ax1.fill_between(x, y1)
ax1.set_title('fill between y1 and 0')

ax2.fill_between(x, y1, 1)
ax2.set_title('fill between y1 and 1')

ax3.fill_between(x, y1, y2)
ax3.set_title('fill between y1 and y2')
ax3.set_xlabel('x')
fig.tight_layout()

在这里插入图片描述
Axes.fill_between(self, x, y1, y2=0, where=None, interpolate=False, step=None, *, data=None, **kwargs):填充两条水平曲线之间的区域。曲线由点(x, y1)和(x, y2)定义。这将创建一个或多个描述填充区域的多边形。可以使用where来排除某些水平截面。默认情况下,边直接连接给定点。如果填充应为阶跃函数(即x之间的常数), 请使用阶跃。

  1. x: array (length N) – 定义曲线的节点的x坐标。
  2. y1: array (length N) or scalar – 定义第一条曲线的节点的y坐标。
  3. y2: array (length N) or scalar, default: 0 – 定义第二条曲线的节点的y坐标。
  4. where: array of bool (length N), optional – 定义在何处排除某些水平区域。填充的区域由坐标x [where]定义。更准确地说,如果where [i]和where [i + 1],则在x [i]和x [i + 1]之间填充。请注意,此定义意味着在其中的两个False值之间隔离的True值不会导致填充。由于相邻的False值,True位置的两侧均未填充。
  5. interpolate: bool, default: False – 仅当在何处使用且两条曲线相互交叉时,此选项才相关。
  6. step: {‘pre’, ‘post’, ‘mid’}, optional – 如果填充应该是阶跃函数,即x之间的常数,则定义阶跃。该值确定执行步骤的位置:‘pre’: y值从每个x位置开始持续不断地向左连续,即间隔(x [i-1], x [i]]的值为y [i]; ‘post’: y值从每个x位置开始连续不断地向右连续,即间隔[x [i], x[i + 1]] 的值为y[i]; ‘mid’:步进发生在x位置之间的一半。

示例:置信带(Confidence bands)

fill_between的常见应用是置信带的指示。fill_between使用颜色循环的颜色作为填充颜色。当应用于填充区域时,这些可能会有点强。因此,通常最好的做法是通过使用alpha使区域半透明来淡化颜色。

N = 21
x = np.linspace(0, 10, 11)
y = [3.9, 4.4, 10.8, 10.3, 11.2, 13.1, 14.1,  9.9, 13.9, 15.1, 12.5]

# 拟合线性曲线以估计其y值及其误差。
a, b = np.polyfit(x, y, deg=1)
y_est = a * x + b
y_err = x.std() * np.sqrt(1/len(x) +
                          (x - x.mean())**2 / np.sum((x - x.mean())**2))

fig, ax = plt.subplots()
ax.plot(x, y_est, '-')
ax.fill_between(x, y_est - y_err, y_est + y_err, alpha=0.2)
ax.plot(x, y, 'o', color='tab:brown')

在这里插入图片描述

选择性填充水平区域(Selectively filling horizontal regions)

参数where允许指定要填充的x范围。这是一个与x大小相同的布尔数组。仅填充连续True序列的x范围。结果,永远不会填充相邻的True和False值之间的范围。当数据点应表示连续数量时,这通常是不希望的。因此,建议除非数据点的x距离足够精细,否则建议设置interpolate = True,以使上述效果不明显。插值近似条件条件将改变的实际x位置,并将填充扩展到该位置。

x = np.array([0, 1, 2, 3])
y1 = np.array([0.8, 0.8, 0.2, 0.2])
y2 = np.array([0, 0, 1, 1])

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)

ax1.set_title('interpolation=False')
ax1.plot(x, y1, 'o--')
ax1.plot(x, y2, 'o--')
ax1.fill_between(x, y1, y2, where=(y1 > y2), color='C0', alpha=0.3)
ax1.fill_between(x, y1, y2, where=(y1 < y2), color='C1', alpha=0.3)

ax2.set_title('interpolation=True')
ax2.plot(x, y1, 'o--')
ax2.plot(x, y2, 'o--')
ax2.fill_between(x, y1, y2, where=(y1 > y2), color='C0', alpha=0.3,
                 interpolate=True)
ax2.fill_between(x, y1, y2, where=(y1 <= y2), color='C1', alpha=0.3,
                 interpolate=True)
fig.tight_layout()

在这里插入图片描述

注:如果y1或y2是掩码数组,也会发生类似的间隙。由于无法估计缺失值,因此插值在这种情况下不起作用。只能通过添加更多靠近屏蔽值的数据点来减少屏蔽值周围的间隙。

在整个轴上选择性标记水平区域(Selectively marking horizontal regions across the whole Axes)

可以应用相同的选择机制来填充轴的整个垂直高度。为了独立于y限制,我们添加了一个转换,该转换解释数据协坐标中的x值和轴坐标中的y值。以下示例标记了y数据高于给定阈值的区域。

fig, ax = plt.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)
ax.plot(x, y, color='black')

threshold = 0.75
ax.axhline(threshold, color='green', lw=2, alpha=0.7)
ax.fill_between(x, 0, 1, where=y > threshold,
                color='green', alpha=0.5, transform=ax.get_xaxis_transform())

在这里插入图片描述

Fill Betweenx示例(Fill Betweenx Demo)

使用fill_betweenx沿两条曲线之间的水平方向进行着色。

import matplotlib.pyplot as plt
import numpy as np

y = np.arange(0.0, 2, 0.01)
x1 = np.sin(2 * np.pi * y)
x2 = 1.2 * np.sin(4 * np.pi * y)

fig, [ax1, ax2, ax3] = plt.subplots(1, 3, sharey=True, figsize=(6, 6))

ax1.fill_betweenx(y, 0, x1)
ax1.set_title('between (x1, 0)')

ax2.fill_betweenx(y, x1, 1)
ax2.set_title('between (x1, 1)')
ax2.set_xlabel('x')

ax3.fill_betweenx(y, x1, x2)
ax3.set_title('between (x1, x2)')

# 现在在满足逻辑条件的x1和x2之间填充。注意这与调用不同
# fill_between(y[where], x1[where], x2[where])
# 由于多个连续区域的边缘效应。
fig, [ax, ax1] = plt.subplots(1, 2, sharey=True, figsize=(6, 6))
ax.plot(x1, y, x2, y, color='black')
ax.fill_betweenx(y, x1, x2, where=x2 >= x1, facecolor='green')
ax.fill_betweenx(y, x1, x2, where=x2 <= x1, facecolor='red')
ax.set_title('fill_betweenx where')

# 对屏蔽阵列的测试支持。
x2 = np.ma.masked_greater(x2, 1.0)
ax1.plot(x1, y, x2, y, color='black')
ax1.fill_betweenx(y, x1, x2, where=x2 >= x1, facecolor='green')
ax1.fill_betweenx(y, x1, x2, where=x2 <= x1, facecolor='red')
ax1.set_title('regions with x2 > 1 are masked')

# 这个例子说明了一个问题。由于数据网格化,交叉处有不希望的未填充三角形点。暴力解决方案是将所有在绘制之前将其排列成非常精细的网格。

plt.show()

在这里插入图片描述
在这里插入图片描述

填充直方图(Hatch-filled histograms)

绘制直方图的阴影功能。

import itertools
from collections import OrderedDict
from functools import partial

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from cycler import cycler


def filled_hist(ax, edges, values, bottoms=None, orientation='v',
                **kwargs):
    """
    Draw a histogram as a stepped patch.

    Extra kwargs are passed through to `fill_between`

    Parameters
    ----------
    ax : Axes
        The axes to plot to

    edges : array
        A length n+1 array giving the left edges of each bin and the
        right edge of the last bin.

    values : array
        A length n array of bin counts or values

    bottoms : float or array, optional
        A length n array of the bottom of the bars.  If None, zero is used.

    orientation : {'v', 'h'}
       Orientation of the histogram.  'v' (default) has
       the bars increasing in the positive y-direction.

    Returns
    -------
    ret : PolyCollection
        Artist added to the Axes
    """
    print(orientation)
    if orientation not in 'hv':
        raise ValueError("orientation must be in {{'h', 'v'}} "
                         "not {o}".format(o=orientation))

    kwargs.setdefault('step', 'post')
    edges = np.asarray(edges)
    values = np.asarray(values)
    if len(edges) - 1 != len(values):
        raise ValueError('Must provide one more bin edge than value not: '
                         'len(edges): {lb} len(values): {lv}'.format(
                             lb=len(edges), lv=len(values)))

    if bottoms is None:
        bottoms = 0
    bottoms = np.broadcast_to(bottoms, values.shape)

    values = np.append(values, values[-1])
    bottoms = np.append(bottoms, bottoms[-1])
    if orientation == 'h':
        return ax.fill_betweenx(edges, values, bottoms,
                                **kwargs)
    elif orientation == 'v':
        return ax.fill_between(edges, values, bottoms,
                               **kwargs)
    else:
        raise AssertionError("you should never be here")


def stack_hist(ax, stacked_data, sty_cycle, bottoms=None,
               hist_func=None, labels=None,
               plot_func=None, plot_kwargs=None):
    """
    Parameters
    ----------
    ax : axes.Axes
        The axes to add artists too

    stacked_data : array or Mapping
        A (N, M) shaped array.  The first dimension will be iterated over to
        compute histograms row-wise

    sty_cycle : Cycler or operable of dict
        Style to apply to each set

    bottoms : array, default: 0
        The initial positions of the bottoms.

    hist_func : callable, optional
        Must have signature `bin_vals, bin_edges = f(data)`.
        `bin_edges` expected to be one longer than `bin_vals`

    labels : list of str, optional
        The label for each set.

        If not given and stacked data is an array defaults to 'default set {n}'

        If stacked_data is a mapping, and labels is None, default to the keys
        (which may come out in a random order).

        If stacked_data is a mapping and labels is given then only
        the columns listed by be plotted.

    plot_func : callable, optional
        Function to call to draw the histogram must have signature:

          ret = plot_func(ax, edges, top, bottoms=bottoms,
                          label=label, **kwargs)

    plot_kwargs : dict, optional
        Any extra kwargs to pass through to the plotting function.  This
        will be the same for all calls to the plotting function and will
        over-ride the values in cycle.

    Returns
    -------
    arts : dict
        Dictionary of artists keyed on their labels
    """
    # deal with default binning function
    if hist_func is None:
        hist_func = np.histogram

    # deal with default plotting function
    if plot_func is None:
        plot_func = filled_hist

    # deal with default
    if plot_kwargs is None:
        plot_kwargs = {}
    print(plot_kwargs)
    try:
        l_keys = stacked_data.keys()
        label_data = True
        if labels is None:
            labels = l_keys

    except AttributeError:
        label_data = False
        if labels is None:
            labels = itertools.repeat(None)

    if label_data:
        loop_iter = enumerate((stacked_data[lab], lab, s)
                              for lab, s in zip(labels, sty_cycle))
    else:
        loop_iter = enumerate(zip(stacked_data, labels, sty_cycle))

    arts = {}
    for j, (data, label, sty) in loop_iter:
        if label is None:
            label = 'dflt set {n}'.format(n=j)
        label = sty.pop('label', label)
        vals, edges = hist_func(data)
        if bottoms is None:
            bottoms = np.zeros_like(vals)
        top = bottoms + vals
        print(sty)
        sty.update(plot_kwargs)
        print(sty)
        ret = plot_func(ax, edges, top, bottoms=bottoms,
                        label=label, **sty)
        bottoms = top
        arts[label] = ret
    ax.legend(fontsize=10)
    return arts


# set up histogram function to fixed bins
edges = np.linspace(-3, 3, 20, endpoint=True)
hist_func = partial(np.histogram, bins=edges)

# set up style cycles
color_cycle = cycler(facecolor=plt.rcParams['axes.prop_cycle'][:4])
label_cycle = cycler(label=['set {n}'.format(n=n) for n in range(4)])
hatch_cycle = cycler(hatch=['/', '*', '+', '|'])

# Fixing random state for reproducibility
np.random.seed(19680801)

stack_data = np.random.randn(4, 12250)
dict_data = OrderedDict(zip((c['label'] for c in label_cycle), stack_data))

使用普通数组

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 4.5), tight_layout=True)
arts = stack_hist(ax1, stack_data, color_cycle + label_cycle + hatch_cycle,
                  hist_func=hist_func)

arts = stack_hist(ax2, stack_data, color_cycle,
                  hist_func=hist_func,
                  plot_kwargs=dict(edgecolor='w', orientation='h'))
ax1.set_ylabel('counts')
ax1.set_xlabel('x')
ax2.set_xlabel('counts')
ax2.set_ylabel('x')

在这里插入图片描述

Out:

{}
{'facecolor': '#1f77b4', 'hatch': '/'}
{'facecolor': '#1f77b4', 'hatch': '/'}
v
{'facecolor': '#ff7f0e', 'hatch': '*'}
{'facecolor': '#ff7f0e', 'hatch': '*'}
v
{'facecolor': '#2ca02c', 'hatch': '+'}
{'facecolor': '#2ca02c', 'hatch': '+'}
v
{'facecolor': '#d62728', 'hatch': '|'}
{'facecolor': '#d62728', 'hatch': '|'}
v
{'edgecolor': 'w', 'orientation': 'h'}
{'facecolor': '#1f77b4'}
{'facecolor': '#1f77b4', 'edgecolor': 'w', 'orientation': 'h'}
h
{'facecolor': '#ff7f0e'}
{'facecolor': '#ff7f0e', 'edgecolor': 'w', 'orientation': 'h'}
h
{'facecolor': '#2ca02c'}
{'facecolor': '#2ca02c', 'edgecolor': 'w', 'orientation': 'h'}
h
{'facecolor': '#d62728'}
{'facecolor': '#d62728', 'edgecolor': 'w', 'orientation': 'h'}
h

Text(0, 0.5, 'x')

使用标记数据

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 4.5),
                               tight_layout=True, sharey=True)

arts = stack_hist(ax1, dict_data, color_cycle + hatch_cycle,
                  hist_func=hist_func)

arts = stack_hist(ax2, dict_data, color_cycle + hatch_cycle,
                  hist_func=hist_func, labels=['set 0', 'set 3'])
ax1.xaxis.set_major_locator(mticker.MaxNLocator(5))
ax1.set_xlabel('counts')
ax1.set_ylabel('x')
ax2.set_ylabel('x')

plt.show()

在这里插入图片描述

{}
{'facecolor': '#1f77b4', 'hatch': '/'}
{'facecolor': '#1f77b4', 'hatch': '/'}
v
{'facecolor': '#ff7f0e', 'hatch': '*'}
{'facecolor': '#ff7f0e', 'hatch': '*'}
v
{'facecolor': '#2ca02c', 'hatch': '+'}
{'facecolor': '#2ca02c', 'hatch': '+'}
v
{'facecolor': '#d62728', 'hatch': '|'}
{'facecolor': '#d62728', 'hatch': '|'}
v
{}
{'facecolor': '#1f77b4', 'hatch': '/'}
{'facecolor': '#1f77b4', 'hatch': '/'}
v
{'facecolor': '#ff7f0e', 'hatch': '*'}
{'facecolor': '#ff7f0e', 'hatch': '*'}
v

条形图与渐变(Bar chart with gradients)

Matplotlib本身不支持渐变。但是,我们可以使用大小和颜色正确的AxesImage模拟渐变填充的矩形。特别是,我们使用颜色图来生成实际颜色。这样就足以在图像的角上定义基础值,并用三次三次插值法填充该区域。我们用单位矢量v定义梯度方向。然后通过在v上角矢量的投影长度获得角上的值。可以使用类似的方法为轴创建渐变背景。

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(19680801)


def gradient_image(ax, extent, direction=0.3, cmap_range=(0, 1), **kwargs):
    """
    根据颜色图绘制渐变图像。

    Parameters
    ----------
    ax : Axes
        要绘制的轴。
    extent
        图像的范围为(xmin,xmax,ymin,ymax)。
        默认情况下,这是在轴坐标中,但可能是
        使用* transform * kwarg进行了更改。
    direction : float
        渐变的方向。这是一个数字范围从0(垂直)到1(水平)。
    cmap_range : float, float
        色彩图的分数(cmin,cmax)应为
        用于渐变,其中完整的色彩图为(0,1)。
    **kwargs
        其他参数将传递给`.Axes.imshow()`。
        * cmap *特别有用。
    """
    phi = direction * np.pi / 2
    v = np.array([np.cos(phi), np.sin(phi)])
    X = np.array([[v @ [1, 0], v @ [1, 1]],
                  [v @ [0, 0], v @ [0, 1]]])
    a, b = cmap_range
    X = a + (b - a) / X.max() * X
    im = ax.imshow(X, extent=extent, interpolation='bicubic',
                   vmin=0, vmax=1, **kwargs)
    return im


def gradient_bar(ax, x, y, width=0.5, bottom=0):
    for left, top in zip(x, y):
        right = left + width
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=plt.cm.Blues_r, cmap_range=(0, 0.8))


xmin, xmax = xlim = 0, 10
ymin, ymax = ylim = 0, 1

fig, ax = plt.subplots()
ax.set(xlim=xlim, ylim=ylim, autoscale_on=False)

# background image
gradient_image(ax, direction=0, extent=(0, 1, 0, 1), transform=ax.transAxes,
               cmap=plt.cm.Oranges, cmap_range=(0.1, 0.6))

N = 10
x = np.arange(N) + 0.15
y = np.random.rand(N)
gradient_bar(ax, x, y, width=0.7)
ax.set_aspect('auto')
plt.show()

在这里插入图片描述

水平条形图的离散分布(Discrete distribution as horizontal bar chart)

堆叠的条形图可用于可视化离散分布。此示例以可视化方式显示了一项调查的结果,在调查中,人们可以按5个元素的等级对他们对问题的同意进行评分。通过为每个类别调用barh() 并通过左边的参数将起始点作为已经绘制的条形的累积总和来实现水平堆叠。

import numpy as np
import matplotlib.pyplot as plt


category_names = ['Strongly disagree', 'Disagree',
                  'Neither agree nor disagree', 'Agree', 'Strongly agree']
results = {
    'Question 1': [10, 15, 17, 32, 26],
    'Question 2': [26, 22, 29, 10, 13],
    'Question 3': [35, 37, 7, 2, 19],
    'Question 4': [32, 11, 9, 15, 33],
    'Question 5': [21, 29, 5, 5, 40],
    'Question 6': [8, 19, 5, 30, 38]
}


def survey(results, category_names):
    """
    Parameters
    ----------
    results : dict
        从问题标签到每个类别的答案列表的映射。
       	假定所有列表包含相同数量的条目,并且它与* category_names *的长度匹配。
    category_names : list of str
        类别标签。
    """
    labels = list(results.keys())
    data = np.array(list(results.values()))
    data_cum = data.cumsum(axis=1)
    category_colors = plt.get_cmap('RdYlGn')(
        np.linspace(0.15, 0.85, data.shape[1]))

    fig, ax = plt.subplots(figsize=(9.2, 5))
    ax.invert_yaxis()
    ax.xaxis.set_visible(False)
    ax.set_xlim(0, np.sum(data, axis=1).max())

    for i, (colname, color) in enumerate(zip(category_names, category_colors)):
        widths = data[:, i]
        starts = data_cum[:, i] - widths
        ax.barh(labels, widths, left=starts, height=0.5,
                label=colname, color=color)
        xcenters = starts + widths / 2

        r, g, b, _ = color
        text_color = 'white' if r * g * b < 0.5 else 'darkgrey'
        for y, (x, c) in enumerate(zip(xcenters, widths)):
            ax.text(x, y, str(int(c)), ha='center', va='center',
                    color=text_color)
    ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),
              loc='lower left', fontsize='small')

    return fig, ax


survey(results, category_names)
plt.show()

在这里插入图片描述

连接样式和封口样式(Join styles and cap styles)

此示例演示了可用的连接样式和封口样式。两者都用于Line2D和matplotlib.collections集合以及一些创建这些的函数,例如plot。

连接样式(Join styles)

连接样式定义如何绘制两个线段之间的连接。
请参阅相应的solid_joinstyle,dash_joinstyle或joinstyle参数。

import numpy as np
import matplotlib.pyplot as plt


def plot_angle(ax, x, y, angle, style):
    phi = np.radians(angle)
    xx = [x + .5, x, x + .5*np.cos(phi)]
    yy = [y, y, y + .5*np.sin(phi)]
    ax.plot(xx, yy, lw=12, color='tab:blue', solid_joinstyle=style)
    ax.plot(xx, yy, lw=1, color='black')
    ax.plot(xx[1], yy[1], 'o', color='tab:red', markersize=3)


fig, ax = plt.subplots(figsize=(8, 6))
ax.set_title('Join style')

for x, style in enumerate(['miter', 'round', 'bevel']):
    ax.text(x, 5, style)
    for y, angle in enumerate([20, 45, 60, 90, 120]):
        plot_angle(ax, x, y, angle, style)
        if x == 0:
            ax.text(-1.3, y, f'{angle} degrees')
ax.text(1, 4.7, '(default)')

ax.set_xlim(-1.5, 2.75)
ax.set_ylim(-.5, 5.5)
ax.set_axis_off()
plt.show()

在这里插入图片描述

封口样式(Cap styles)

封口样式定义如何绘制线条端点。请参阅相应的solid_capstyle,dash_capstyle或capstyle参数。

fig, ax = plt.subplots(figsize=(8, 2))
ax.set_title('Cap style')

for x, style in enumerate(['butt', 'round', 'projecting']):
    ax.text(x+0.25, 1, style, ha='center')
    xx = [x, x+0.5]
    yy = [0, 0]
    ax.plot(xx, yy, lw=12, color='tab:blue', solid_capstyle=style)
    ax.plot(xx, yy, lw=1, color='black')
    ax.plot(xx, yy, 'o', color='tab:red', markersize=3)
ax.text(2.25, 0.7, '(default)', ha='center')

ax.set_ylim(-.5, 1.5)
ax.set_axis_off()

在这里插入图片描述

自定义虚线样式(Customizing dashed line styles)

线的虚线通过虚线序列控制。可以使用Line2D.set_dashes对其进行修改。破折号序列是一系列以点为单位的开/关长度,例如[3, 1]是3pt长的行,由1pt的空格分隔。诸如Axes.plot之类的某些功能支持将Line属性作为关键字参数传递。在这种情况下,创建线时已经可以设置虚线。
注意:也可以通过property_cycle配置破折号样式,方法是将使用关键字破折号的破折号序列列表传递给循环仪。此示例中未显示。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 500)
y = np.sin(x)

fig, ax = plt.subplots()

# 使用set_dashes()修改现有行的虚线
line1, = ax.plot(x, y, label='Using set_dashes()')
line1.set_dashes([2, 2, 10, 2])  # 2pt line, 2pt break, 10pt line, 2pt break

# 创建线时使用plot(...,dashes = ...)设置破折号
line2, = ax.plot(x, y - 0.2, dashes=[6, 2], label='Using the dashes parameter')

ax.legend()
plt.show()

在这里插入图片描述

线形(Linestyles)

可以使用字符串“ solid”,“ dotted”,“ dashed”或“ dashdot”定义简单的线型。通过提供破折号元组 (偏移量, (on_off_seq)),可以实现更精细的控制。例如,(0, (3, 10, 1, 15)) 表示没有偏移的(3pt行, 10pt空间, 1pt行, 15pt空间)。另请参见Line2D.set_linestyle。
注意:还可以通过Line2D.set_dashes配置虚线样式,如定制虚线样式中所示,并使用关键字dashs将虚线序列列表传递给property_cycle中的循环器。

import numpy as np
import matplotlib.pyplot as plt

linestyle_str = [
     ('solid', 'solid'),      # Same as (0, ()) or '-'
     ('dotted', 'dotted'),    # Same as (0, (1, 1)) or '.'
     ('dashed', 'dashed'),    # Same as '--'
     ('dashdot', 'dashdot')]  # Same as '-.'

linestyle_tuple = [
     ('loosely dotted',        (0, (1, 10))),
     ('dotted',                (0, (1, 1))),
     ('densely dotted',        (0, (1, 1))),

     ('loosely dashed',        (0, (5, 10))),
     ('dashed',                (0, (5, 5))),
     ('densely dashed',        (0, (5, 1))),

     ('loosely dashdotted',    (0, (3, 10, 1, 10))),
     ('dashdotted',            (0, (3, 5, 1, 5))),
     ('densely dashdotted',    (0, (3, 1, 1, 1))),

     ('dashdotdotted',         (0, (3, 5, 1, 5, 1, 5))),
     ('loosely dashdotdotted', (0, (3, 10, 1, 10, 1, 10))),
     ('densely dashdotdotted', (0, (3, 1, 1, 1, 1, 1)))]


def plot_linestyles(ax, linestyles, title):
    X, Y = np.linspace(0, 100, 10), np.zeros(10)
    yticklabels = []

    for i, (name, linestyle) in enumerate(linestyles):
        ax.plot(X, Y+i, linestyle=linestyle, linewidth=1.5, color='black')
        yticklabels.append(name)

    ax.set_title(title)
    ax.set(ylim=(-0.5, len(linestyles)-0.5),
           yticks=np.arange(len(linestyles)),
           yticklabels=yticklabels)
    ax.tick_params(left=False, bottom=False, labelbottom=False)
    for spine in ax.spines.values():
        spine.set_visible(False)

    # 对于每种线型,添加一个文本偏移量,该偏移量与
    # 参考点(轴坐标为0,数据为y刻度值coords).
    for i, (name, linestyle) in enumerate(linestyles):
        ax.annotate(repr(linestyle),
                    xy=(0.0, i), xycoords=ax.get_yaxis_transform(),
                    xytext=(-6, -12), textcoords='offset points',
                    color="blue", fontsize=8, ha="right", family="monospace")


ax0, ax1 = (plt.figure(figsize=(10, 8))
            .add_gridspec(2, 1, height_ratios=[1, 3])
            .subplots())

plot_linestyles(ax0, linestyle_str[::-1], title='Named linestyles')
plot_linestyles(ax1, linestyle_tuple[::-1], title='Parametrized linestyles')

plt.tight_layout()
plt.show()

在这里插入图片描述

标记引用(Marker reference)

Matplotlib支持使用标记命令的marker参数选择的多种类别的标记:
未填充标记、填充标记、从TeX符号创建的标记、可以从路径创建自定义标记。

未填充标记(Unfilled markers)

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D


text_style = dict(horizontalalignment='right', verticalalignment='center',
                  fontsize=12, fontfamily='monospace')
marker_style = dict(linestyle=':', color='0.8', markersize=10,
                    markerfacecolor="tab:blue", markeredgecolor="tab:blue")


def format_axes(ax):
    ax.margins(0.2)
    ax.set_axis_off()
    ax.invert_yaxis()


def split_list(a_list):
    i_half = len(a_list) // 2
    return a_list[:i_half], a_list[i_half:]

fig, axs = plt.subplots(ncols=2)
fig.suptitle('Un-filled markers', fontsize=14)

# 过滤掉无用的填充标记和标记设置。
unfilled_markers = [m for m, func in Line2D.markers.items()
                    if func != 'nothing' and m not in Line2D.filled_markers]

for ax, markers in zip(axs, split_list(unfilled_markers)):
    for y, marker in enumerate(markers):
        ax.text(-0.5, y, repr(marker), **text_style)
        ax.plot([y] * 3, marker=marker, **marker_style)
    format_axes(ax)

plt.show()

在这里插入图片描述

填充标记(Filled markers)

fig, axs = plt.subplots(ncols=2)
fig.suptitle('Filled markers', fontsize=14)
for ax, markers in zip(axs, split_list(Line2D.filled_markers)):
    for y, marker in enumerate(markers):
        ax.text(-0.5, y, repr(marker), **text_style)
        ax.plot([y] * 3, marker=marker, **marker_style)
    format_axes(ax)

plt.show()

在这里插入图片描述

标记填充样式(Marker fill styles)

可以分别指定填充标记的边缘颜色和填充颜色。此外,fillstyle可以配置为在各个方向上不填充,完全填充或半填充。半填充样式使用markerfacecoloralt作为辅助填充颜色。

fig, ax = plt.subplots()
fig.suptitle('Marker fillstyle', fontsize=14)
fig.subplots_adjust(left=0.4)

filled_marker_style = dict(marker='o', linestyle=':', markersize=15,
                           color='darkgrey',
                           markerfacecolor='tab:blue',
                           markerfacecoloralt='lightsteelblue',
                           markeredgecolor='brown')

for y, fill_style in enumerate(Line2D.fillStyles):
    ax.text(-0.5, y, repr(fill_style), **text_style)
    ax.plot([y] * 3, fillstyle=fill_style, **filled_marker_style)
format_axes(ax)

plt.show()

在这里插入图片描述

从TeX符号创建的标记(Markers created from TeX symbols)

使用MathText,以使用自定义标记符号,例如“ $ \ u266B $”。有关STIX字体符号的概述,请参见STIX字体表。另请参见STIX字体演示

fig, ax = plt.subplots()
fig.suptitle('Mathtext markers', fontsize=14)
fig.subplots_adjust(left=0.4)

marker_style.update(markeredgecolor="None", markersize=15)
markers = ["$1$", r"$\frac{1}{2}$", "$f$", "$\u266B$", r"$\mathcal{A}$"]

for y, marker in enumerate(markers):
    # 转义美元,以便文本按“原样”而不是数学文本形式编写。
    ax.text(-0.5, y, repr(marker).replace("$", r"\$"), **text_style)
    ax.plot([y] * 3, marker=marker, **marker_style)
format_axes(ax)

plt.show()

在这里插入图片描述

Markevery演示(Markevery Demo)

本示例演示了使用Line2D对象的markevery属性在数据点子集上显示标记的各种选项。整数参数非常直观。例如markevery = 5将从第一个数据点开始每5个标记绘制一次。

浮点参数允许标记沿直线间隔大约相等的距离。沿标记之间的线的理论距离是通过将边界框对角轴的显示坐标距离乘以markevery的值确定的。将显示最接近理论距离的数据点。切片或列表/数组也可以与markevery一起使用以指定要显示的标记。

import numpy as np
import matplotlib.pyplot as plt

# 定义要绘制的每个案例的列表
cases = [None,
         8,
         (30, 8),
         [16, 24, 30], [0, -1],
         slice(100, 200, 3),
         0.1, 0.3, 1.5,
         (0.0, 0.1), (0.45, 0.1)]

# 定义图形尺寸和网格布局属性
figsize = (10, 8)
cols = 3
rows = len(cases) // cols + 1
# 定义笛卡尔图的数据
delta = 0.11
x = np.linspace(0, 10 - 2 * delta, 200) + delta
y = np.sin(x) + 1.0 + delta


def trim_axs(axs, N):
    """
    将*轴*减少为* N *轴。所有其他轴均从图中移除。
    """
    axs = axs.flat
    for ax in axs[N:]:
        ax.remove()
    return axs[:N]

为线性x和y比例绘制每个标记案例

axs = plt.figure(figsize=figsize, constrained_layout=True).subplots(rows, cols)
axs = trim_axs(axs, len(cases))
for ax, case in zip(axs, cases):
    ax.set_title('markevery=%s' % str(case))
    ax.plot(x, y, 'o', ls='-', ms=4, markevery=case)

在这里插入图片描述

绘制每个标记案例的对数x和y标度

axs = plt.figure(figsize=figsize, constrained_layout=True).subplots(rows, cols)
axs = trim_axs(axs, len(cases))
for ax, case in zip(axs, cases):
    ax.set_title('markevery=%s' % str(case))
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.plot(x, y, 'o', ls='-', ms=4, markevery=case)

在这里插入图片描述

为线性x和y比例绘制每个标记案例,但是放大时请注意放大时的行为。指定开始标记偏移时,总是相对于第一个数据点进行解释,该偏移可能与第一个可见数据点不同。

axs = plt.figure(figsize=figsize, constrained_layout=True).subplots(rows, cols)
axs = trim_axs(axs, len(cases))
for ax, case in zip(axs, cases):
    ax.set_title('markevery=%s' % str(case))
    ax.plot(x, y, 'o', ls='-', ms=4, markevery=case)
    ax.set_xlim((6, 6.7))
    ax.set_ylim((1.1, 1.7))

# define data for polar plots
r = np.linspace(0, 3.0, 200)
theta = 2 * np.pi * r

在这里插入图片描述

为极坐标图绘制每个标记案例

axs = plt.figure(figsize=figsize, constrained_layout=True).subplots(
    rows, cols, subplot_kw={'projection': 'polar'})
axs = trim_axs(axs, len(cases))
for ax, case in zip(axs, cases):
    ax.set_title('markevery=%s' % str(case))
    ax.plot(theta, r, 'o', ls='-', ms=4, markevery=case)

plt.show()

在这里插入图片描述

绘制遮罩值和NaN值(Plotting masked and NaN values)

有时您需要绘制缺少值的数据。一种可能性是简单地删除不需要的数据点。通过剩余数据绘制的线将是连续的,并不表示丢失的数据位于何处。如果在缺少数据的行中留有空隙很有用,则可以使用掩码数组或将其值设置为NaN来指示不需要的点。 x或y被遮盖的位置将不会绘制标记,如果用线绘制,则该标记将在此处断开。

下面的示例说明了三种情况:

  1. 去除点(Removing points).
  2. 掩模点(Masking points)。
  3. 设置为NaN(Setting to NaN)。
import matplotlib.pyplot as plt
import numpy as np


x = np.linspace(-np.pi/2, np.pi/2, 31)
y = np.cos(x)**3

# 1) 删除y> 0.7的点
x2 = x[y <= 0.7]
y2 = y[y <= 0.7]

# 2) y> 0.7的遮罩点
y3 = np.ma.masked_where(y > 0.7, y)

# 3) 设置为NaN,其中y> 0.7
y4 = y.copy()
y4[y3 > 0.7] = np.nan

plt.plot(x*0.1, y, 'o-', color='lightgrey', label='No mask')
plt.plot(x2*0.4, y2, 'o-', label='Points removed')
plt.plot(x*0.7, y3, 'o-', label='Masked values')
plt.plot(x*1.0, y4, 'o-', label='NaN values')
plt.legend()
plt.title('Masked and NaN data')
plt.show()

在这里插入图片描述

彩色线条(Multicolored lines)

此示例演示如何生成多色线。在本例中,线是基于其导数着色的。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm

x = np.linspace(0, 3 * np.pi, 500)
y = np.sin(x)
dydx = np.cos(0.5 * (x[:-1] + x[1:]))  # 一阶导数

# 创建一组线段,以便我们可以分别为其着色
# 这会将点创建为N x 1 x 2数组,以便我们可以堆叠点
# 轻松地获得细分。用于线收集的segments数组
# 需要是 (numlines) x (points per line) x 2 (for x and y)
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

fig, axs = plt.subplots(2, 1, sharex=True, sharey=True)

# 改用边界范数
norm = plt.Normalize(dydx.min(), dydx.max())
lc = LineCollection(segments, cmap='viridis', norm=norm)
# 设置用于颜色映射的值
lc.set_array(dydx)
lc.set_linewidth(2)
line = axs[0].add_collection(lc)
fig.colorbar(line, ax=axs[0])

#改用边界范数
cmap = ListedColormap(['r', 'g', 'b'])
norm = BoundaryNorm([-1, -0.5, 0.5, 1], cmap.N)
lc = LineCollection(segments, cmap=cmap, norm=norm)
lc.set_array(dydx)
lc.set_linewidth(2)
line = axs[1].add_collection(lc)
fig.colorbar(line, ax=axs[1])

axs[0].set_xlim(x.min(), x.max())
axs[0].set_ylim(-1.1, 1.1)
plt.show()

在这里插入图片描述

散点自定义符号(Scatter Custom Symbol)

在散点图中创建自定义椭圆符号。

import matplotlib.pyplot as plt
import numpy as np


# 修复随机状态以提高可重复性
np.random.seed(19680801)

# 单位面积椭圆
rx, ry = 3., 1.
area = rx * ry * np.pi
theta = np.arange(0, 2 * np.pi + 0.01, 0.1)
verts = np.column_stack([rx / area * np.cos(theta), ry / area * np.sin(theta)])

x, y, s, c = np.random.rand(4, 30)
s *= 10**2.

fig, ax = plt.subplots()
ax.scatter(x, y, s, c, marker=verts)

plt.show()

在这里插入图片描述

散点图(Scatter Demo2)

具有不同标记颜色和大小的散点图演示。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook

# 从Yahoo csv数据中加载具有日期,打开,关闭卷,来自mpl-data / example目录的adj_close。记录数组
#将日期以np.datetime64的形式存储在日期列中,日期单位为“ D”。
price_data = (cbook.get_sample_data('goog.npz', np_load=True)['price_data']
              .view(np.recarray))
price_data = price_data[-250:]  # 得到最近的250个交易日

delta1 = np.diff(price_data.adj_close) / price_data.adj_close[:-1]

# 标记大小,以点为单位^ 2
volume = (15 * price_data.volume[:-2] / price_data.volume[0])**2
close = 0.003 * price_data.close[:-2] / 0.003 * price_data.open[:-2]

fig, ax = plt.subplots()
ax.scatter(delta1[:-1], delta1[1:], c=close, s=volume, alpha=0.5)

ax.set_xlabel(r'$\Delta_i$', fontsize=15)
ax.set_ylabel(r'$\Delta_{i+1}$', fontsize=15)
ax.set_title('Volume and percent change')

ax.grid(True)
fig.tight_layout()

plt.show()

在这里插入图片描述

散射遮罩图(Scatter Masked)

遮罩一些数据点,并添加一条线去标记遮罩的区域。

import matplotlib.pyplot as plt
import numpy as np

# 修复随机状态以提高可重复性
np.random.seed(19680801)


N = 100
r0 = 0.6
x = 0.9 * np.random.rand(N)
y = 0.9 * np.random.rand(N)
area = (20 * np.random.rand(N))**2  # 0至10点半径
c = np.sqrt(area)
r = np.sqrt(x ** 2 + y ** 2)
area1 = np.ma.masked_where(r < r0, area)
area2 = np.ma.masked_where(r >= r0, area)
plt.scatter(x, y, s=area1, marker='^', c=c)
plt.scatter(x, y, s=area2, marker='o', c=c)
# 显示区域之间的边界:
theta = np.arange(0, np.pi / 2, 0.01)
plt.plot(r0 * np.cos(theta), r0 * np.sin(theta))

plt.show()

在这里插入图片描述

堆栈图和流图(Stackplots and streamgraphs)

堆栈图(Stackplots)

Stackplots将多个数据集绘制为垂直堆叠的区域。当单个数据值及其累加值受到关注时,这很有用。

import numpy as np
import matplotlib.pyplot as plt

# 联合国世界人口前景数据(2019年修订)
# https://population.un.org/wpp/, license: CC BY 3.0 IGO
year = [1950, 1960, 1970, 1980, 1990, 2000, 2010, 2018]
population_by_continent = {
    'africa': [228, 284, 365, 477, 631, 814, 1044, 1275],
    'americas': [340, 425, 519, 619, 727, 840, 943, 1006],
    'asia': [1394, 1686, 2120, 2625, 3202, 3714, 4169, 4560],
    'europe': [220, 253, 276, 295, 310, 303, 294, 293],
    'oceania': [12, 15, 19, 22, 26, 31, 36, 39],
}

fig, ax = plt.subplots()
ax.stackplot(year, population_by_continent.values(),
             labels=population_by_continent.keys())
ax.legend(loc='upper left')
ax.set_title('World population')
ax.set_xlabel('Year')
ax.set_ylabel('Number of people (millions)')

plt.show()

在这里插入图片描述

流图(Streamgraphs)

使用基线参数,可以将基线为0的普通堆叠区域图转换为流图。

# Fixing random state for reproducibility
np.random.seed(19680801)


def gaussian_mixture(x, n=5):
    """返回* n *高斯的随机混合,在位置* x *处评估。"""
    def add_random_gaussian(a):
        amplitude = 1 / (.1 + np.random.random())
        dx = x[-1] - x[0]
        x0 = (2 * np.random.random() - .5) * dx
        z = 10 / (.1 + np.random.random()) / dx
        a += amplitude * np.exp(-(z * (x - x0))**2)
    a = np.zeros_like(x)
    for j in range(n):
        add_random_gaussian(a)
    return a


x = np.linspace(0, 100, 101)
ys = [gaussian_mixture(x) for _ in range(3)]

fig, ax = plt.subplots()
ax.stackplot(x, ys, baseline='wiggle')
plt.show()

在这里插入图片描述

饼图和极坐标图(Pie and polar charts)

基本饼图(Basic pie chart)

基本饼图演示以及一些其他功能。除了基本的饼图,此演示还显示了一些可选功能:

  1. 切片标签
  2. 自动标记百分比
  3. 用“爆炸”偏移切片
  4. 阴影
  5. 自定义起始角度

关于自定义起始角度的注意事项:
默认起始角度为0,它将在正x轴上开始“Frogs”切片。本示例将startangle = 90设置为使所有内容都逆时针旋转90度,并且frog slice从正y轴开始。

import matplotlib.pyplot as plt

# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')

fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
        shadow=True, startangle=90)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.show()

在这里插入图片描述

matplotlib.axes.Axes.pie
Axes.pie(self, x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=0, 0, frame=False, rotatelabels=False, *, normalize=None, data=None): 绘制饼图。

制作一个数组 x x x的饼图。每个楔形的分数面积由 x / s u m ( x ) x / sum(x) x/sum(x)给出。如果 s u m ( x ) < 1 sum(x)<1 sum(x)<1,则x的值将直接给出小数面积,并且该数组将不被标准化。结果饼图将具有大小为 1 − s u m ( x ) 1-sum(x) 1sum(x)的空楔形。默认情况下,楔形是从x轴开始逆时针绘制的。

  1. x: 1D array-like – 楔形尺寸。
  2. explode: array-like, default: None – 如果不是None,则是len(x) 数组,它指定偏移每个楔形的半径的分数。
  3. labels: list, default: None – 为每个楔块提供标签的一系列字符串。
  4. colors: array-like, default: None – 饼图将循环显示的一系列颜色。如果为无,将使用当前活动周期中的颜色。
  5. autopct: None or str or callable, default: None – 如果不是None,则为字符串或函数,用于使用楔形数值标记楔形。标签将放置在楔形物内。如果是格式字符串,则标签将为fmt%pct。如果它是一个函数,它将被调用。
  6. pctdistance: float, default: 0.6 – 每个饼图切片的中心与autopct生成的文本开头之间的比率。如果autopct为None则忽略。
  7. shadow: bool, default: False – 在饼下面绘制阴影。
  8. normalize: None or bool, default: None – 为True时,始终通过标准化x来使整个饼状,这样sum(x)==1; 如果为None,则如果sum(x)> = 1,则默认为True;如果sum(x)<1,则默认为False。
  9. labeldistance: float或无,默认值:1.1 – 绘制饼形标签的径向距离。
  10. startangle: float, default: 0 degrees – 饼的起点从x轴逆时针旋转的角度。
  11. radius: float,默认值:1 – 饼的半径。
  12. counterclock: bool,默认值:True – 指定分数方向,顺时针或逆时针。

饼图示例2(Pie Demo2)

使用饼状图制作饼图。 本示例演示了一些饼图功能,例如标签,尺寸变化,自动标注百分比,偏移切片并添加阴影。

import matplotlib.pyplot as plt

# 一些数据
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]

# 制作图形和轴
fig, axs = plt.subplots(2, 2)

# 标准饼图
axs[0, 0].pie(fracs, labels=labels, autopct='%1.1f%%', shadow=True)

# 使用explode移动第二个切片
axs[0, 1].pie(fracs, labels=labels, autopct='%.0f%%', shadow=True,
              explode=(0, 0.1, 0, 0))

# Adapt radius and text size for a smaller pie
patches, texts, autotexts = axs[1, 0].pie(fracs, labels=labels,
                                          autopct='%.0f%%',
                                          textprops={'size': 'smaller'},
                                          shadow=True, radius=0.5)
# 使百分比文本更小
plt.setp(autotexts, size='x-small')
autotexts[0].set_color('white')

# 使用较小的explode和阴影转角以提高可见度
patches, texts, autotexts = axs[1, 1].pie(fracs, labels=labels,
                                          autopct='%.0f%%',
                                          textprops={'size': 'smaller'},
                                          shadow=False, radius=0.5,
                                          explode=(0, 0.05, 0, 0))
plt.setp(autotexts, size='x-small')
autotexts[0].set_color('white')

plt.show()

在这里插入图片描述

条形饼图(Bar of pie)

制作一个“饼状条形图”,将饼状图的第一个部分“分解”成条形图,并进一步细分该部分的特征。该示例演示了如何使用具有多组轴的图形以及如何使用轴补丁列表添加两个ConnectionPatch来链接子图图表。

import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch
import numpy as np

# make figure and assign axis objects
fig = plt.figure(figsize=(9, 5))
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
fig.subplots_adjust(wspace=0)

# 饼图参数
ratios = [.27, .56, .17]
labels = ['Approve', 'Disapprove', 'Undecided']
explode = [0.1, 0, 0]
# rotate so that first wedge is split by the x-axis
angle = -180 * ratios[0]
ax1.pie(ratios, autopct='%1.1f%%', startangle=angle,
        labels=labels, explode=explode)

# 条形图参数

xpos = 0
bottom = 0
ratios = [.33, .54, .07, .06]
width = .2
colors = [[.1, .3, .5], [.1, .3, .3], [.1, .3, .7], [.1, .3, .9]]

for j in range(len(ratios)):
    height = ratios[j]
    ax2.bar(xpos, height, width, bottom=bottom, color=colors[j])
    ypos = bottom + ax2.patches[j].get_height() / 2
    bottom += height
    ax2.text(xpos, ypos, "%d%%" % (ax2.patches[j].get_height() * 100),
             ha='center')

ax2.set_title('Age of approvers')
ax2.legend(('50-65', 'Over 65', '35-49', 'Under 35'))
ax2.axis('off')
ax2.set_xlim(- 2.5 * width, 2.5 * width)

# 使用ConnectionPatch在两个图之间绘制线
# 获取楔形数据
theta1, theta2 = ax1.patches[0].theta1, ax1.patches[0].theta2
center, r = ax1.patches[0].center, ax1.patches[0].r
bar_height = sum([item.get_height() for item in ax2.patches])

# draw top connecting line
x = r * np.cos(np.pi / 180 * theta2) + center[0]
y = r * np.sin(np.pi / 180 * theta2) + center[1]
con = ConnectionPatch(xyA=(-width / 2, bar_height), coordsA=ax2.transData,
                      xyB=(x, y), coordsB=ax1.transData)
con.set_color([0, 0, 0])
con.set_linewidth(4)
ax2.add_artist(con)

# 绘制底部连接线
x = r * np.cos(np.pi / 180 * theta1) + center[0]
y = r * np.sin(np.pi / 180 * theta1) + center[1]
con = ConnectionPatch(xyA=(-width / 2, 0), coordsA=ax2.transData,
                      xyB=(x, y), coordsB=ax1.transData)
con.set_color([0, 0, 0])
ax2.add_artist(con)
con.set_linewidth(4)

plt.show()

在这里插入图片描述

嵌套饼图(Nested pie charts)

以下示例显示了两种在Matplotlib中构建嵌套饼图的方法。这样的图表通常称为甜甜圈图。

import matplotlib.pyplot as plt
import numpy as np

建立饼图的最直接方法是使用饼图方法。

在这种情况下,pie采用与组中的计数相对应的值。我们将首先生成一些假数据,分别对应三个组。在内部圈子中,我们将每个数字都视为属于其自己的组。在外圈中,我们将它们绘制为原始3组的成员。

甜甜圈形状的效果是通过楔子属性参数设置饼图的楔子的宽度来实现的。

fig, ax = plt.subplots()

size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])

cmap = plt.get_cmap("tab20c")
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap([1, 2, 5, 6, 9, 10])

ax.pie(vals.sum(axis=1), radius=1, colors=outer_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(vals.flatten(), radius=1-size, colors=inner_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()

在这里插入图片描述

但是,可以通过在带有极坐标系的轴上使用条形图来实现相同的输出。这可以为绘图的确切设计提供更大的灵活性。在这种情况下,我们需要将条形图的x值映射到圆的弧度上。

fig, ax = plt.subplots(subplot_kw=dict(polar=True))

size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])
#将val标准化为2 pi
valsnorm = vals/np.sum(vals)*2*np.pi
#获取条形边缘的纵坐标
valsleft = np.cumsum(np.append(0, valsnorm.flatten()[:-1])).reshape(vals.shape)

cmap = plt.get_cmap("tab20c")
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap([1, 2, 5, 6, 9, 10])

ax.bar(x=valsleft[:, 0],
       width=valsnorm.sum(axis=1), bottom=1-size, height=size,
       color=outer_colors, edgecolor='w', linewidth=1, align="edge")

ax.bar(x=valsleft.flatten(),
       width=valsnorm.flatten(), bottom=1-2*size, height=size,
       color=inner_colors, edgecolor='w', linewidth=1, align="edge")

ax.set(title="Pie plot with `ax.bar` and polar coordinates")
ax.set_axis_off()
plt.show()

在这里插入图片描述

极轴上的条形图(Bar chart on polar axis)

条形图在极轴上的演示。

import numpy as np
import matplotlib.pyplot as plt


# 修复随机状态以提高可重复性
np.random.seed(19680801)

# 计算饼图
N = 20
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N)
colors = plt.cm.viridis(radii / 10.)

ax = plt.subplot(111, projection='polar')
ax.bar(theta, radii, width=width, bottom=0.0, color=colors, alpha=0.5)

plt.show()

在这里插入图片描述

极坐标演示(Polar Demo)

极轴上的线图演示。

import numpy as np
import matplotlib.pyplot as plt


r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.plot(theta, r)
ax.set_rmax(2)
ax.set_rticks([0.5, 1, 1.5, 2])  # 较少的径向刻度
ax.set_rlabel_position(-22.5)  # 将径向标签从绘图线移开
ax.grid(True)

ax.set_title("A line plot on a polar axis", va='bottom')
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值