【问题标题】:Seaborn: Avoid plotting missing values (line plot)Seaborn:避免绘制缺失值(线图)
【发布时间】:2019-02-05 11:42:27
【问题描述】:

我想要一个线图来指示是否缺少一条数据,例如:

但是,下面的代码填充了缺失的数据,从而创建了一个可能具有误导性的图表:

import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt

# load csv
df=pd.read_csv('data.csv')
# plot a graph
g = sns.lineplot(x="Date", y="Data", data=df)
plt.show()

我应该在我的代码中进行哪些更改以避免填充缺失值?

csv 如下所示:

Date,Data
01-12-03,100
01-01-04,
01-02-04,
01-03-04,
01-04-04,
01-05-04,39
01-06-04,
01-07-04,
01-08-04,53
01-09-04,
01-10-04,
01-11-04,
01-12-04,
01-01-05,28
   ...
01-04-18,14
01-05-18,12
01-06-18,8
01-07-18,8

.csv 链接: https://drive.google.com/file/d/1s-RJfAFYD90m4SrFDzIba7EQP4C-J0yO/view?usp=sharing

【问题讨论】:

  • 缺少数据是指nan的一行?
  • 分享一些最小的数据来重现情节并让我们玩这个图
  • 确定,上传数据

标签: python visualization seaborn


【解决方案1】:

尝试将 NaN 值设置为 np.inf -- Seaborn 不会绘制这些点,也不会将之前的点与之后的点连接起来。

【讨论】:

  • 这是正确的答案
【解决方案2】:

基于 Denziloe 的回答:

有三个选项:

1) 使用pandasmatplotlib

2) 如果您需要seaborn:不是它的用途,而是像上面这样的常规日期pointplot 可以开箱即用。

fig, ax = plt.subplots(figsize=(10, 5))

plot = sns.pointplot(
    ax=ax,
    data=df, x="Date", y="Data"
)

ax.set_xticklabels([])

plt.show()

基于问题数据构建的图表如下所示:

优点:

  • 易于实施
  • None包围的数据中的异常值在图表上很容易注意到

缺点:

  • 生成这样的图需要很长时间(与lineplot相比)
  • 当有很多点时,很难阅读这样的图表

3) 如果你需要seaborn 并且你需要lineplothue 参数可用于将单独的部分放在单独的存储桶中。我们使用 nans 的出现对部分进行编号。

fig, ax = plt.subplots(figsize=(10, 5))

plot = sns.lineplot(
    ax=ax
    , data=df, x="Date", y="Data"
    , hue=df["Data"].isna().cumsum()
    , palette=["blue"]*sum(df["Data"].isna())
    , legend=False, markers=True
)

ax.set_xticklabels([])

plt.show()

优点:

  • 线图
  • 易于阅读
  • 生成速度比点图快

缺点:

  • 数据中被None包围的异常值不会在图表上绘制

图表将如下所示:

【讨论】:

  • 这是一个很好的答案,但我会将palette 参数替换为palette = ["blue"] * df["Data"].isna().cumsum().nunique(),如果第一个值不是nan,则效果更好
【解决方案3】:
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns

# Make example data
s = """2018-01-01
2018-01-02,100
2018-01-03,105
2018-01-04
2018-01-05,95
2018-01-06,90
2018-01-07,80
2018-01-08
2018-01-09"""
df = pd.DataFrame([row.split(",") for row in s.split("\n")], columns=["Date", "Data"])
df = df.replace("", np.nan)
df["Date"] = pd.to_datetime(df["Date"])
df["Data"] = df["Data"].astype(float)

三个选项:

1) 使用pandasmatplotlib

2) 如果您需要seaborn:不是它的用途,而是像您这样的常规日期,您可以立即使用pointplot

fig, ax = plt.subplots(figsize=(10, 5))

plot = sns.pointplot(
    ax=ax,
    data=df, x="Date", y="Data"
)

ax.set_xticklabels([])

plt.show()

3) 如果你需要seaborn 并且你需要lineplot:我查看了源代码,看起来lineplot 在绘图之前从DataFrame 中删除了nans。所以不幸的是,不可能正确地做到这一点。不过,您可以使用一些高级黑客技术并使用 hue 参数将单独的部分放在单独的存储桶中。我们使用 nans 的出现对部分进行编号。

fig, ax = plt.subplots(figsize=(10, 5))

plot = sns.lineplot(
    ax=ax,
    data=df, x="Date", y="Data",
    hue=df["Data"].isna().cumsum(), palette=["black"]*sum(df["Data"].isna()), legend=False, markers=True
)
ax.set_xticklabels([])

plt.show()

不幸的是,markers 参数目前似乎已被破坏,因此如果您想查看两边都有 nan 的日期,则需要修复它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2021-03-18
    • 2017-11-17
    • 2021-05-19
    • 2018-01-11
    相关资源
    最近更新 更多