условная matplotlib fill_between для фрейма данных - PullRequest
0 голосов
/ 06 июля 2018

Казалось, легко, но я борюсь. Я хочу условно раскрасить оси, то есть заполнить область зеленым или красным и полностью заполнить. Я использую некоторый логический столбец df для определения цвета

df = pd.DataFrame([1,1,1,1,1,0,0,1,1,0,1,1,0,1,0,1], columns=['grow'])
df['green']=(df.grow>0) | (df.grow.shift(1)>0)
df['red']= (df.grow<=0) | (df.grow.shift(1)<=0) 

Но когда я использую это условие для заполнения между этим:

fig, axes = plt.subplots(nrows=1, ncols=1)
axes.fill_between(df.index, 0, 1,  
                 where=(df.grow>0) , color = 'green', alpha = 0.1)
axes.fill_between(df.index, 0, 1,  
                 where=(df.grow<=0) , color = 'red', alpha = 0.1)

они не полностью заполнены. Как мне изменить лимит того, где можно получить хорошее наполнение? enter image description here

1 Ответ

0 голосов
/ 06 июля 2018

Причина, по которой заполненные области не являются непрерывными, становится очевидной, когда вы изображаете pd.grow как линейный график. При использовании fill_between() вы неявно предполагаете, что ваши данные напоминают пошаговую функцию, но на самом деле это скорее зуб пилы (края не «острые»). Один из способов обойти это - заполнить функцию большим количеством повторяющихся значений и, таким образом, сделать переходы между 0 и 1 более четкими. numpy - практический инструмент для подобных операций. Вот пример того, как это сделать:

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame([1,1,1,1,1,0,0,1,1,0,1,1,0,1,0,1], columns=['grow'])
df['green']=(df.grow>0) | (df.grow.shift(1)>0)
df['red']= (df.grow<=0) | (df.grow.shift(1)<=0)

fig, axes = plt.subplots(
    nrows=2, ncols=2, gridspec_kw = {'height_ratios':[1, 3]}
)

axes[0,0].plot(df.index, df.grow)
axes[0,0].set_title('original function')

axes[1,0].fill_between(df.index, 0, 1,  
                 where=(df.grow>0) , color = 'green', alpha = 0.1)
axes[1,0].fill_between(df.index, 0, 1,  
                 where=(df.grow<=0) , color = 'red', alpha = 0.1)
axes[1,0].set_title('original shading')

N=100
x = np.linspace(df.index[0],df.index[-1],N*len(df.index))
y = np.repeat(df.grow, N)

axes[0,1].plot(x,y)
axes[0,1].set_title('sharper step function')

axes[1,1].fill_between(x, 0, 1,  
                 where=(y>0) , color = 'green', alpha = 0.1, lw=0)
axes[1,1].fill_between(x, 0, 1,  
                 where=(y<=0) , color = 'red', alpha = 0.1,lw=0)
axes[1,1].set_title('new_shading')


plt.show()

... и результат выглядит так:

result of the above code

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...