4

I have a list of dates in format 15/10/2017

I have tried the following

from matplotlib import pyplot
import pandas as pd

dates = ['15/10/2016', '16/10/2016', "17/10/2015", "15/10/2014"]
dates_formatted = [pd.to_datetime(d) for d in dates ]
x = [1,2,3,4]
z = [5,6,7,8]

pyplot.scatter(x, dates_formatted, z)
pyplot.show()

It throws an error TypeError: ufunc 'sqrt' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

It shows if it is 2D. e.g. pyplot.scatter(x, dates_formatted)

I have also tried the following

ax = Axes3D(fig)
ax = fig.add_subplot(111,projection='3d')
ax.scatter(x, dates_formatted, y)
pyplot.show()

It throws an error Float() argument must be a string or number

2
  • I suspect you're actually calling the scatter method of the regular Axes object. Try creating a Axes3d object with ax = fig.add_subplot(111,projection='3d') then doing what you've done. Commented Mar 8, 2017 at 18:12
  • Have tried it and updated the question Commented Mar 9, 2017 at 12:36

2 Answers 2

9

It's not always trivial to tell matplotlib how to translate strings into a coordinate system. Why not simply set custom tick labels for the axes?

import pandas as pd
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure('scatter dates')
ax = fig.add_subplot(111, projection='3d')
dates = ['15/10/2016', '16/10/2016', "17/10/2015", "15/10/2014"]
dates_formatted = [pd.to_datetime(d) for d in dates ]
x = [1,2,3,4]
y = [9,10,11,12]
z = [5,6,7,8]

ax.scatter(x, y, z)
ax.xaxis.set_ticks(x)
ax.xaxis.set_ticklabels(dates_formatted)
plt.show()

enter image description here

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

2 Comments

So if I understand the solution correctly, the list of values on x are just arbitrary number such that we conform to the supported value for the scatter() function. Thereafter we just need to set a custom label(date) for the x axes to sort of 'replace' the values.
@MaTaKazer pretty much so, yes. In principle, you can calculate x values directly from a time string too, which would be a more meaningful way doing it.
4

Scatter expects a number. So you can convert your dates to as number as follows:

y = [ (d-min(dates_formatted)).days for d in dates_formatted]

Now you can plot the data as

pyplot.scatter(x, y)

For a 3D plot, you can try something like this ...

import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

plt.ion()
x = [1,2,3,4]
z = [5,6,7,8]
dates = ['15/10/2016', '16/10/2016', "17/10/2015", "15/10/2014"]
dates_formatted = [pd.to_datetime(d) for d in dates]

y = [ (d-min(dates_formatted)).days for d in dates_formatted]

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
plt.scatter(x, y, z)

The y axis in now in days. You can change that by finding the date string, and changing it back ...

dt = [ pd.Timedelta(d) + min(dates_formatted)  for d in  ax.get_yticks()]

Convert these into strings ...

dtStr = [d.isoformat() for d in dt]

And put them back

ax.set_yticklabels(dtStr)

Comments

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.