1

Good day,

I am trying to plot two arrays (timesin and locations) as a scatter of points. However, because timesin is a datetime object (of which I want time only), I find that I can only plot it properly using pyplot.plot(), not pyplot.scatter(). The issue arrises when I want to color the points on this plot with a third variable, idx. I know pyplot.scatter() is capable of doing this quite easily, but I don't know how to do it with pyplot.plot().

My excerpt of code:

import os
import tempfile
from datetime import datetime
import numpy as np
os.environ['MPLCONFIGDIR'] = tempfile.mkdtemp()

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

pp = PdfPages('output.pdf')
names = ['WestHall', 'Elevator', 'EastHall', 'MathLounge']
locations = np.arange(4)+1
plt.scatter(timesin, locations, c=idx, marker="o")
plt.xlabel("Time of day")
plt.ylabel("Location")
plt.yticks(np.arange(4)+1, names)
plt.gcf().autofmt_xdate()
pp.savefig()
plt.close()
pp.close()

When I try this, I get an error, because it tries to interpret idx as rgba:

ValueError: to_rgba: Invalid rgba arg "[...]"
number in rbg sequence outside 0-1 range

How do I get it to interpret idx as conditional coloring without using pyplot.scatter()?

Thanks

Update:

As suggested by Hun, I actually can use pyplot.scatter() in this context by converting the datetime objects to numbers using matplotlibs dates library. Thus, figuring out how to use pyplot.plot() for conditional coloring was unnecessary.

1
  • You marked Hun's answer as the answer, but this doesn't answer your question. You should change your question to claim that Hun have answered it. Commented Apr 10, 2016 at 20:34

2 Answers 2

2

It would be easier if you use plt.scatter(). But you need to convert the datetime to something scatter() can understand. There is a way to do it.

>>> dt # datetime numpy array
array(['2005-02-01', '2005-02-02', '2005-02-03', '2005-02-04'], dtype='datetime64[D]')

>>> dt.tolist() # need to be converted to list
[datetime.date(2005, 2, 1), datetime.date(2005, 2, 2), datetime.date(2005, 2, 3), datetime.date(2005, 2, 4)]

# convert the list to internal time information for matplotlib. But this is float.
>>> dt1 = matplotlib.dates.date2num(dt.tolist())
array([ 731978.,  731979.,  731980.,  731981.])

With this dt1 you can use plt.scatter()

Sign up to request clarification or add additional context in comments.

6 Comments

Do they plot as numbers or as time?
I will be plotted as number. Since you know what those number means you can use x-axis label formatter to display datetime. You can use num2date() matplotlib function. Extra work but I don't see any other way of doing it for your case.
It seems date2num() and num2date() are made for this kind of purpose.
Would you mind adding an example of setting the x-axis by num2date() please?
Have you tried to look up the document on your own?
|
0

I think that it is not possible to do this at once with matplotlib.pyplot.plot. However, here is my solution:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm

def scatterplot(x,y,prop):
    prop = cm.jet((prop-np.min(prop))/(np.max(prop)-np.min(prop)))
    ax = plt.gca()
    for i in xrange(len(x)):
        ax.plot(x[i],y[i],color=prop[i], marker='o')
    return

x = np.random.rand(100)
y = np.random.rand(100)
prop = -20+40*np.random.rand(100)

fig = plt.figure(1,figsize=(5,5))
ax  = fig.add_subplot(111)
scatterplot(x,y,prop)
plt.show()

which produces:

enter image description here

The only drawback of this approach is that if you have several particles, the process of walk through all of them can be relatively slow.

EDIT (In response to @Nathan Goedeke's comment:

I tried the same implementation but using a datetime object:

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

x = np.array([dt.datetime(2016, 10, 19, 10, 0, 0),
              dt.datetime(2016, 10, 19, 10, 0, 1),
              dt.datetime(2016, 10, 19, 10, 0, 2),
              dt.datetime(2016, 10, 19, 10, 0, 3)])

fig = plt.figure()
y = np.array([1, 3, 4, 2])
prop = np.array([2.,5.,3.,1.])
scatterplot(x,y,prop)
plt.show()

and it works as well.

7 Comments

Because my data to plot are datetime objects, I get an error when I try to implement this: ValueError: ordinal must be >= 1
Could you please write a minimum working example? I can not test it with your example...
You said that pyplot.plot worked for you, so I don't see why now you complain about this implementation, which actually uses pyplot.plot.
My example is the same as the code in my question only with the addition of timesin being an array of datetime objects.
I know pyplot.plot works, but for some reason when I tried your implementation I got a long traceback ending with File "/usr/lib/pymodules/python2.7/matplotlib/dates.py", line 203, in _from_ordinalf dt = datetime.datetime.fromordinal(ix) ValueError: ordinal must be >= 1
|

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.