Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotting CDF for Discrete Variable - Step Plot with Alternating Lines

I would like to draw a graph that looks like:

enter image description here

The data is given in a .csv file, which I already imported to data and used as x in the graph.

Y is calculated as following:

y = np.arange(1, len(data)+1)/len(data)

And then plotted using:

plt.step((data), y)
plt.show(block="false")

My problem is now, that the graph looks like a normal step graph like this one (not my actual data).

How do I format this to look like the one mentioned, i.e. coming from the left on the y = 0 line and extending on the right on the y = 1 line, dotted vs. solid lines and points on the graph?

I have googled around and found many solutions for the graph that I already have, but I would like to format it as mentioned.

I'm new to the general subject, so if the setup is wrong, any help there is appreciated as well!

Thanks!

like image 520
BastianZim Avatar asked May 02 '26 14:05

BastianZim


1 Answers

I'm not sure if step() can do this; it's really just a few lines of code wrapped around plt.plot().

Alternately, you could use vlines() and hlines(). The logic of slicing varies based on how you want the steps "configured," (as in how you would specify the where argument to step(), but here is a close reproduction of the example from your question:

import numpy as np
import matplotlib.pyplot as plt

data = np.arange(0, 7)
y = np.array([.07, .21, .42, .68, 1.])
yn = np.insert(y, 0, 0)

fig, ax = plt.subplots()
ax.set_facecolor('white')

# https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.hlines.html
ax.hlines(y=yn, xmin=data[:-1], xmax=data[1:],
          color='red', zorder=1)

# https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.vlines.html
ax.vlines(x=data[1:-1], ymin=yn[:-1], ymax=yn[1:], color='red',
          linestyle='dashed', zorder=1)

ax.scatter(data[1:-1], y, color='red', s=18, zorder=2)
ax.scatter(data[1:-1], yn[:-1], color='white', s=18, zorder=2,
           edgecolor='red')
ax.grid(False)
ax.set_xlim(data[0], data[-1])
ax.set_ylim([-0.01, 1.01])

enter image description here

zorder makes sure the scatter points are overlaid on top of lines.

As it stands, your creation of y doesn't really follow suite with what the image you showed looks like, but this example tries to mimic the image itself.

like image 140
Brad Solomon Avatar answered May 05 '26 03:05

Brad Solomon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!