如何避免在 matplotlib 中重叠误差线?

rev*_*evy 7 python matplotlib

我想为两个不同的数据集创建一个类似于此答案中提供的数据集的图:

在此处输入图片说明

在上图中,作者通过在 x 中添加一些小的随机散点到新数据集,设法解决了误差线的重叠问题。

在我的问题中,我必须绘制一个类似的图形,但在 x 轴上有一些分类数据:

在此处输入图片说明

关于如何使用 x 轴上的分类变量稍微移动第二个数据集的误差条的任何想法?我想避免条形之间的重叠以使可视化更容易。

Imp*_*est 9

您可以通过将默认数据转换添加到数据空间中的先前转换来转换每个误差条。当知道类别通常彼此相距一个数据单元时,这是可能的。

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

x = list("ABCDEF")
y1, y2 = np.random.randn(2, len(x))
yerr1, yerr2 = np.random.rand(2, len(x))*4+0.3

fig, ax = plt.subplots()

trans1 = Affine2D().translate(-0.1, 0.0) + ax.transData
trans2 = Affine2D().translate(+0.1, 0.0) + ax.transData
er1 = ax.errorbar(x, y1, yerr=yerr1, marker="o", linestyle="none", transform=trans1)
er2 = ax.errorbar(x, y2, yerr=yerr2, marker="o", linestyle="none", transform=trans2)

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

或者,您可以在应用数据变换后转换误差条,从而以点为单位移动它们。

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
from matplotlib.transforms import ScaledTranslation

x = list("ABCDEF")
y1, y2 = np.random.randn(2, len(x))
yerr1, yerr2 = np.random.rand(2, len(x))*4+0.3

fig, ax = plt.subplots()

trans1 = ax.transData + ScaledTranslation(-5/72, 0, fig.dpi_scale_trans)
trans2 = ax.transData + ScaledTranslation(+5/72, 0, fig.dpi_scale_trans)
er1 = ax.errorbar(x, y1, yerr=yerr1, marker="o", linestyle="none", transform=trans1)
er2 = ax.errorbar(x, y2, yerr=yerr2, marker="o", linestyle="none", transform=trans2)

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

虽然这两种情况的结果看起来相似,但它们根本不同。当以交互方式缩放轴或更改图形大小时,您将观察到这种差异。


Poo*_*lka 7

请看下面的方法来彰显情节-的组合errorbarfill_between非零透明度:

import random
import matplotlib.pyplot as plt

# create sample data
N = 8
data_1 = {
    'x': list(range(N)),
    'y': [10. + random.random() for dummy in range(N)],
    'yerr': [.25 + random.random() for dummy in range(N)]}
data_2 = {
    'x': list(range(N)),
    'y': [10.25 + .5 * random.random() for dummy in range(N)],
    'yerr': [.5 * random.random() for dummy in range(N)]}

# plot
plt.figure()
# only errorbar
plt.subplot(211)
for data in [data_1, data_2]:
    plt.errorbar(**data, fmt='o')
# errorbar + fill_between
plt.subplot(212)
for data in [data_1, data_2]:
    plt.errorbar(**data, alpha=.75, fmt=':', capsize=3, capthick=1)
    data = {
        'x': data['x'],
        'y1': [y - e for y, e in zip(data['y'], data['yerr'])],
        'y2': [y + e for y, e in zip(data['y'], data['yerr'])]}
    plt.fill_between(**data, alpha=.25)
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明