2

The following code draws the cdf for datetime values:

import matplotlib.pyplot as plt
import matplotlib.dates as dates
import numpy as np; np.random.seed(42)
import pandas as pd

objDate = dates.num2date(np.random.normal(735700, 300, 700))

ser = pd.Series(objDate)
ax = ser.hist(cumulative=True, density=1, bins=500, histtype='step')

plt.show()

cdf of datetime values

How can I remove the vertical line at the right-most end of graph? The approach mentioned here doesn't work as replacing line#9 with:

ax = ser.hist(cumulative=True, density=1, bins=sorted(objDate)+[np.inf], histtype='step')

gives

TypeError: can't compare datetime.datetime to float

SaadH
  • 1,158
  • 2
  • 23
  • 38

1 Answers1

1

The CDF is actually drawn as a polygon, which in matplotlib is defined by a path. A path is in turn defined by vertices (where to go) and codes (how to get there). The docs say that we should not directly alter these attributes, but we can make a new polygon derived from the old one that suits our needs.

poly = ax.findobj(plt.Polygon)[0]
vertices = poly.get_path().vertices

# Keep everything above y == 0. You can define this mask however
# you need, if you want to be more careful in your selection.
keep = vertices[:, 1] > 0

# Construct new polygon from these "good" vertices
new_poly = plt.Polygon(vertices[keep], closed=False, fill=False,
                       edgecolor=poly.get_edgecolor(),
                       linewidth=poly.get_linewidth())
poly.set_visible(False)
ax.add_artist(new_poly)
plt.draw()

You should arrive at something like the figure below:

CDF with offending points removed

bnaecker
  • 6,152
  • 1
  • 20
  • 33
  • Is there anything missing in the first line? It is giving me: `ValueError: ordinal must be >= 1` – SaadH Jun 06 '18 at 02:37
  • @SaadH It works just fine for me if I copy-and-paste your code and mine. It's possibly related to [this](https://github.com/matplotlib/matplotlib/pull/10084) matplotlib issue, which was fixed late 2017. What version are you running? – bnaecker Jun 06 '18 at 15:12
  • Was 2.1.1, upgraded to 2.2.2. Added your code, and then moved `plt.show()` to the last line, and it worked! – SaadH Jun 08 '18 at 13:27