Skip to content

fill_between issue with interpolation & NaN #18986

@lcnittl

Description

@lcnittl

Bug report

Bug summary

When fill_between encounters NaN in the y values (x valued not tested), with interpolate=True the produces output does not look like it should.

This behavior was already mentioned in #11781, which was closed as "resolved" when using a (back then) more up to date NumPy version, however, the issue is still there (or there again).

One more note: It seems that not all NaN containing fill_between produce a faulty output.

Code for reproduction

from io import StringIO

import jupyterlab as jpl
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

csv_file = StringIO("""\
x,y1,y2
0,8,18
1,18,11
2,24,8
3,18,11
4,8,18
5,18,26
6,24,42
7,18,
8,8,
9,18,
""")

df = pd.read_csv(csv_file)


fig, axes = plt.subplots(2, 2, sharex="all", sharey="all", figsize=(12, 6))
fig.patch.set_facecolor("#ffffff")  

for row_idx, row in enumerate(axes):
    for col_idx, axis in enumerate(row):
        for y in ["y1", "y2"]:
            axis.plot(
                df["x"],
                df[y],
                label=r"$ " + y + r" $",
            )
            
        if row_idx == 0:
            axis.fill_between(
                df["x"],
                df["y1"],
                df["y2"],
                where=df["y1"] <= df["y2"],
                facecolor="#94C154",
                interpolate=True,
            )
            axis.set_title((axis.get_title() + " & " if axis.get_title() else "") + "'where <='")
        if col_idx == 0:
            axis.fill_between(
                df["x"],
                df["y1"],
                df["y2"],
                where=df["y1"] >= df["y2"],
                facecolor="#DD4814",
                interpolate=True,
            )
            axis.set_title((axis.get_title() + " & " if axis.get_title() else "") + "'where >='")
        if row_idx == 1 and col_idx == 1:
            axis.fill_between(
                df["x"],
                df["y1"],
                df["y2"],
                facecolor="#F6A800",
                interpolate=True,
            )
            axis.set_title("without 'where'")

        if any(axis.get_legend_handles_labels()):
            axis.legend()

fig.suptitle(
    "matplotlib: v" + mpl.__version__ + " (" + mpl.get_backend() + ")" + "\n"
    + "jupyterlab: v" + jpl.__version__ + "\n"
    + "numpy: v" + np.__version__ + "\n"
    + "pandas: v" + pd.__version__,
    #y=1.15
)

fig.tight_layout()
plt.show(fig)

Actual outcome

image

Expected outcome

No intersecting areas, with correctly fillings.

Matplotlib version

  • Operating system: Windows 10
  • Matplotlib version: 3.3.3
  • Matplotlib backend (print(matplotlib.get_backend())): module://ipykernel.pylab.backend_inline
  • Python version: 3.8.5
  • Jupyter version (if applicable): 2.2.8 (Equal output when executed from plain python script)
  • Other libraries:
    • Pandas version: 1.1.4
    • NumPy version: 1.19.3 (Not actively used in MWE)

Everything installed via pip (20.2.4).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions