roberto tomás
roberto tomás

Reputation: 4687

how can I fill the area in this plot?

I'd like to fill the blue "location" sections in the plot below. The data itself marks the ocurrance of a significant location change, is time series in 15 minute samples, and repeats the last location until a new location change event occurs. So once for example"home" was regististered, its column remained at 1, everything else at 0. Then when "work" was visited next, that column became 1, and home joined the others at 0.

plot with locations

u1 = userLocAppDfs['user_3'].copy()
# https://stackoverflow.com/questions/11927715/how-to-give-a-pandas-matplotlib-bar-graph-custom-colors
locations = [(x/8.75, x/40.0, 0.85) for x in range(5)] # color grad

u1[[' bar', ' grocers', ' home', ' lunch', ' work']].plot(color=locations, figsize=(15,10))

u1[' app_3'].plot(color='orange')
u1[' app_1'].plot(color='r')

I notice that fillstyle='full' is not doing anything. Whats the right way to fill my graph areas?

sample data

    app_1   app_2   user    bar grocers home    lunch   park    relatives   work
date                                        
2017-08-29 14:00:00 0.013953    0.052472    user_1  0.0 0.0 0.0 0.0 0.0 0.0 1.0
2017-08-29 14:15:00 0.014070    0.052809    user_1  0.0 0.0 0.0 0.0 0.0 0.0 1.0
2017-08-29 14:30:00 0.014186    0.053146    user_1  0.0 0.0 1.0 0.0 0.0 0.0 0.0
2017-08-29 14:45:00 0.014302    0.053483    user_1  0.0 0.0 1.0 0.0 0.0 0.0 0.0
2017-08-29 15:00:00 0.014419    0.053820    user_1  0.0 0.0 1.0 0.0 0.0 0.0 0.0

Upvotes: 0

Views: 316

Answers (1)

mskoh52
mskoh52

Reputation: 150

I don't think is possible using pandas plotting directly from a DataFrame, but you can use fill_between from matplotlib. You would need to do this on each column of your dataframe ('bar', 'home', 'work', etc..). You can manually create an axis and tell matplotlib and pandas to plot onto that axis

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1)
for location in [' bar', 'grocers', ' home']:  # or whatever subset of columns you want
    ax.fill_between(range(len(u1[location]), u1[location], step='post')

u1[' app_3'].plot(ax=ax, color='orange')
# etc..

P.S. the fillstyle argument is for when you have a marker for each data point and you want to modify its appearance: https://matplotlib.org/gallery/lines_bars_and_markers/marker_fillstyle_reference.html


Edit: Updated example using the data you provided. I modified the data to add a stop at the bar between work and home to give a nicer looking plot.

import matplotlib.pyplot as plt
import pandas as pd

columns = ['date', 'app_1', 'app_2', 'user', 'bar', 'grocers', 'home', 'lunch', 'park', 'relatives', 'work']
data = [['2017-08-29 14:00:00', 0.013953, 0.052472, 'user_1', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], ['2017-08-29 14:15:00', 0.014070, 0.052809, 'user_1', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], ['2017-08-29 14:30:00', 0.014186, 0.053146, 'user_1', 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], ['2017-08-29 14:45:00', 0.014302, 0.053483, 'user_1', 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], ['2017-08-29 15:00:00', 0.014419, 0.053820, 'user_1', 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]]

df = pd.DataFrame(data, columns=columns)
height = df[['app_1', 'app_2']].max().max()

fig, ax = plt.subplots(1,1)

df['app_1'].plot(ax=ax, color='orange')
df['app_2'].plot(ax=ax, color='purple')
ax.fill_between(range(len(df['home'])), height * df['home'], step='post', color='blue')
ax.fill_between(range(len(df['work'])), height * df['work'], step='post', color='red')

plt.show()

Data looks like this:

                  date     app_1     app_2    user  bar  grocers  home  lunch  park  relatives  work
0  2017-08-29 14:00:00  0.013953  0.052472  user_1  0.0      0.0   0.0    0.0   0.0        0.0   1.0
1  2017-08-29 14:15:00  0.014070  0.052809  user_1  0.0      0.0   0.0    0.0   0.0        0.0   1.0
2  2017-08-29 14:30:00  0.014186  0.053146  user_1  1.0      0.0   0.0    0.0   0.0        0.0   0.0
3  2017-08-29 14:45:00  0.014302  0.053483  user_1  0.0      0.0   1.0    0.0   0.0        0.0   0.0
4  2017-08-29 15:00:00  0.014419  0.053820  user_1  0.0      0.0   1.0    0.0   0.0        0.0   0.0

Looks like this:

example

Upvotes: 1

Related Questions