简体   繁体   中英

matplotlib 3d scatter plot date

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. eg 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

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()

在此输入图像描述

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)

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