简体   繁体   中英

Add different color markers by day of week to a Pandas time series plot

I made a time-series plot as below with customized x axis:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

df = pd.DataFrame({'points': np.random.randint(1,100, 61)}, 
index=pd.date_range(start='11-1-2017', end='12-31-2017', freq='D'))
df['dow'] = df.index.dayofweek

fig, ax = plt.subplots();
ax.plot_date(df.index, df.points, '-o')
ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=(0), interval=1))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('\n\n\n%b\n%Y'))

And the plot looked like this:

在此处输入图片说明

What I really wanted was to have the marker color different for each day of week (Mon, Tue...), so I modified the above code like this:

colors = dict(zip(df.dow.unique(), ['orange', 'yellow', 'green', 'blue', 'purple', 'black', 'red']))
ax.plot_date(df.index, df.points, '-o', color=df['dow'].apply(lambda x: colors[x]))

But it resulted in

ValueError: Invalid RGBA argument

Appreciate it if anyone has a solution!

The only way I have seen lines plotted with different color markers is by plotting the markers as a scatter plot and then plotting the line. In this situation I would plot the dates with the marker - and then make a scatter plot over the top like so:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

df = pd.DataFrame({'points': np.random.randint(1,100, 61)}, 
index=pd.date_range(start='11-1-2017', end='12-31-2017', freq='D'))
df['dow'] = df.index.dayofweek
colors = dict(zip(df.dow.unique(), ['orange', 'yellow', 'green', 'blue', 'purple', 'black', 'red']))


fig, ax = plt.subplots();
ax.plot_date(df.index, df.points, '-')
ax.scatter(df.index, df.points, color=df.dow.map(lambda x: colors[x]))
ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=(0), interval=1))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('\n\n\n%b\n%Y'))

在此处输入图片说明

Alternatively, you could create new line object via plot with markers only (line style is empty) and cycle through your colors list. plot applies a unique color to your line object hence one needs to create additional line objects or use scatter where you can assign a color for each point created.

fig, ax = plt.subplots()
# create a line plot first
ax.plot_date(df.index, df.points, '-')

# Desired color list
color_list = ['orange', 'yellow', 'green', 'blue', 'purple', 'black', 'red']

# create additional line object by showing only marker of different colors
for idc, d in enumerate(df.dow.unique()):
    this_dow = df.loc[df.dow == d, 'points']
    ax.plot_date(this_dow.index,this_dow, linestyle='', marker ='o', color=color_list[idc])

# axis esthetics
ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=(0), interval=1))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('\n\n\n%b\n%Y'))

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM