0

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
roberto tomás
  • 4,435
  • 5
  • 42
  • 71
  • down votes should be accompanied with a comment – roberto tomás Sep 24 '18 at 12:59
  • Not the downvoter, but, please do show us where the stipulation for a comment with a downvote is? – SiHa Sep 24 '18 at 13:09
  • it actually tells you when you downvote, if you havent already added a comment – roberto tomás Sep 24 '18 at 13:10
  • Not to me, it doesn't. Regardless. There are threads aplenty on meta discussing this and the general consensus is that there is no *requirement* for a comment. – SiHa Sep 24 '18 at 13:13
  • I've tested incognito with an anonymous/new account, and, yes, it does suggest it. (Requirements adverbally correlate to "must", while suggestions correlate to "should".) if it does not for you, you have a custom style sheet or something blocking the content provided by stackoverflow. Besides .. do _you_ see anything meaningfully wrong with this question?? :) – roberto tomás Sep 24 '18 at 13:18
  • 1
    To be fair. No, I don't see anything particularly wrong with your question. – SiHa Sep 24 '18 at 14:57

1 Answers1

1

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

mskoh52
  • 152
  • 3
  • 6
  • Hi Mskoh52 -- I tried `ax.fill_between(len(u1[location]), u1[location])` -- it didnt actually fill any spaces (and took noticeably longer to render). It also split into two graphs, one with the apps lines and the other with the location data. Can you give me any more clarity? – roberto tomás Sep 24 '18 at 13:01
  • I'll add some sample data to look at – roberto tomás Sep 24 '18 at 13:02
  • Sorry, meant to write range(len(u1[location])), which sets the x position to fill. If your data is at a different x location, you'll need to change that. – mskoh52 Sep 25 '18 at 14:32
  • Fixed up some things and made a demo with your sample data – mskoh52 Sep 26 '18 at 14:51
  • Wow thank you! That's part of the actual data so, awesome – roberto tomás Sep 26 '18 at 16:04