2

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

1 Answer 1

2

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 converts the dates into numbers, makes the scatter plot, and uses a FuncFormatter to convert the tick labels back into dates.

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)]})

def my_formatter(x, pos=None):
    d = matplotlib.dates.num2date(x)
    if len(str(d.minute)) == 1:
        mn = '0{}'.format(d.minute)
    else:
        mn = str(d.minute)
    if len(str(d.hour)) == 1:
        hr = '0{}'.format(d.hour)
    else:
        hr = str(d.hour)
    return hr+':'+mn

major_formatter=FuncFormatter(my_formatter)

nums = np.array([matplotlib.dates.date2num(di) for di in df['x']])

fig, ax = plt.subplots()
ax.xaxis.set_major_formatter(major_formatter)
ax.scatter(nums,df['y'],s=20,c=df['z'], marker = 'o', cmap = cm.jet )
xmin = df['x'][0]-datetime.timedelta(hours=1)
xmax = df['x'][len(df['x'])-1]+datetime.timedelta(hours=1)
ax.set_xlim((xmin,xmax))
plt.show()
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for your answer. Unfortunately, this is not what I am expecting. It already works for xAlt. I would like to do: ax.scatter(df['x'],df['y'],s=20,c=df['z'], marker = 'o', cmap = cm.jet )
The point is to plot using xAlt, but then to convert xAlt -> df['x'] in the x-ticks by using the my_formatter function. This should produce a plot with times on the x-axis and with points colored by a third array. Did you try running the code snippet above? You cannot use scatter and df['x'], so you need to use a workaround like the one I suggested.
Ok I got it! Thank you very much
Great - no problem. I'd be appreciative if you accepted my answer if it solved your problem.
Ok the example I give should work for any list of times (presuming you want hour:minute as the format, but this could easily be changed)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.