Kil.Th Kil.Th - 2 months ago 24
Python Question

python - scatter plot with dates and 3rd variable as color

I am trying to plot an x-y plot, with x or y as date variable, and using a 3rd variable to color the points.
I managed to do it if none of the 3 variables are date, using:

ax.scatter(df['x'],df['y'],s=20,c=df['z'], marker = 'o', cmap = cm.jet )


After searching, I find out that for normal plot, we have to use plot_date(). Unfortunately, I haven't been able to color the points.
Can anybody help me?

Here is a small example:

import matplotlib, datetime
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import pandas as pd

todayTime=datetime.datetime.now();
df = pd.DataFrame({'x': [todayTime+datetime.timedelta(hours=i) for i in range(10)], 'y': range(10),'z' : [2*j for j in range(10)]});
xAlt=[0.5*i for i in range(10)];

fig, ax = plt.subplots()
ax.scatter(df['x'],df['y'],s=20,c=df['z'], marker = 'o', cmap = cm.jet )
plt.show()


You can replace df['x'] by xAlt to see the desired result

Thank you

Answer

As far as I know, one has to use scatter in order to color the points as you describe. One workaround could be to use a FuncFormatter to convert the tick labels into times on the x-axis. The code below takes the xAlt array and converts it into hour:minute format and replaces the x-axis ticks on your figure. Below is a modified version of your example - does this produce the kind of result you want?

import matplotlib, datetime
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import pandas as pd
from matplotlib.ticker import FuncFormatter

todayTime=datetime.datetime.now()
df = pd.DataFrame({'x': [todayTime+datetime.timedelta(hours=i) for i in  range(10)], 'y': range(10),'z' : [2*j for j in range(10)]})
xAlt=[i for i in range(10)] #we will plot using this array, but use 
                            #my_formatter below to make the x-tick 
                            #labels correspond to df['x']

def my_formatter(x, pos):
    """Convert scalar into hour:minute according to recipe used to create df['x']"""
    t = todayTime+datetime.timedelta(hours=x)
    val_str = '{0}:{1}'.format(t.hour,t.minute)
    return val_str

major_formatter=FuncFormatter(my_formatter)

fig, ax = plt.subplots()
ax.xaxis.set_major_formatter(major_formatter)
ax.scatter(xAlt,df['y'],s=20,c=df['z'], marker = 'o', cmap = cm.jet )
plt.show()
Comments