Seaborn: избегайте отображения пропущенных значений (линейный график) - PullRequest
0 голосов
/ 30 августа 2018

Я хочу, чтобы линейный график показывал, что часть данных отсутствует, например: enter image description here

Однако приведенный ниже код заполняет недостающие данные, создавая потенциально вводящую в заблуждение диаграмму: enter image description here

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

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

На основании ответа Дензилое:

есть три варианта:

1) Используйте pandas или matplotlib.

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()

График, построенный на данных из вопроса, будет выглядеть следующим образом: enter image description here

Плюсы:

  • легко реализовать
  • выброс в данных, который окружен None , будет легко заметить на графике

Минусы:

  • создание такого графика занимает много времени (по сравнению с lineplot)
  • когда точек много, читать такие графики становится трудно

3) Если вам нужно seaborn и вам нужно lineplot: Аргумент 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=["blue"]*sum(df["Data"].isna())
    , legend=False, markers=True
)

ax.set_xticklabels([])

plt.show()

Плюсы:

  • lineplot
  • легко читается
  • генерируется быстрее, чем точечный график

Минусы:

  • выброс в данных, который окружен None , не будет нарисован на графике

График будет выглядеть следующим образом: enter image description here

0 голосов
/ 30 августа 2018
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) Используйте pandas или matplotlib.

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()

enter image description here

3) Если вам нужно seaborn и вам нужно lineplot: я посмотрел исходный код, и похоже, что lineplot удаляет nans из DataFrame перед построением графика. Так что, к сожалению, это невозможно сделать правильно. Вы можете использовать некоторые дополнительные хакеры и использовать аргумент 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()

enter image description here

К сожалению, аргумент markers в настоящее время не работает, поэтому вам нужно исправить его, если вы хотите видеть даты, которые имеют nans с обеих сторон.

...