How do I plot a step function with Matplotlib in Python?
Question:
This should be easy but I have just started toying with matplotlib and python. I can do a line or a scatter plot but i am not sure how to do a simple step function. Any help is much appreciated.
x = 1,2,3,4
y = 0.002871972681775004, 0.00514787917410944, 0.00863476098280219, 0.012003316194034325
Answers:
Draw two lines, one at y=0, and one at y=1, cutting off at whatever x
your step function is for.
e.g. if you want to step from 0 to 1 at x=2.3
and plot from x=0
to x=5
:
import matplotlib.pyplot as plt
# _
# if you want the vertical line _|
plt.plot([0,2.3,2.3,5],[0,0,1,1])
#
# OR:
# _
# if you don't want the vertical line _
#plt.plot([0,2.3],[0,0],[2.3,5],[1,1])
# now change the y axis so we can actually see the line
plt.ylim(-0.1,1.1)
plt.show()
I think you want pylab.bar(x,y,width=1)
or equally pyplot
‘s bar method. if not checkout the gallery for the many styles of plots you can do. Each image comes with example code showing you how to make it using matplotlib.
It seems like you want step
.
E.g.
import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [0.002871972681775004, 0.00514787917410944,
0.00863476098280219, 0.012003316194034325]
plt.step(x, y)
plt.show()
If you have non-uniformly spaced data points, you can use the drawstyle
keyword argument for plot
:
x = [1,2.5,3.5,4]
y = [0.002871972681775004, 0.00514787917410944,
0.00863476098280219, 0.012003316194034325]
plt.plot(x, y, drawstyle='steps-pre')
Also available are steps-mid
and steps-post
.
In case someone just wants to stepify some data rather than actually plot it:
def get_x_y_steps(x, y, where="post"):
if where == "post":
x_step = [x[0]] + [_x for tup in zip(x, x)[1:] for _x in tup]
y_step = [_y for tup in zip(y, y)[:-1] for _y in tup] + [y[-1]]
elif where == "pre":
x_step = [_x for tup in zip(x, x)[:-1] for _x in tup] + [x[-1]]
y_step = [y[0]] + [_y for tup in zip(y, y)[1:] for _y in tup]
return x_step, y_step
New in matplotlib 3.4.0
There is a new plt.stairs
method to complement plt.step
:
plt.stairs
and the underlying StepPatch
provide a cleaner interface for plotting stepwise constant functions for the common case that you know the step edges.
This supersedes many use cases of plt.step
, for instance when plotting the output of np.histogram
.
Check out the official matplotlib gallery for how to use plt.stairs
and StepPatch
.
When to use plt.step
vs plt.stairs
-
Use the original plt.step
if you have reference points. Here the steps are anchored at [1,2,3,4]
and extended to the left:
plt.step(x=[1,2,3,4], y=[20,40,60,30])
-
Use the new plt.stairs
if you have edges. The previous [1,2,3,4]
step points correspond to [1,1,2,3,4]
stair edges:
plt.stairs(values=[20,40,60,30], edges=[1,1,2,3,4])
Using plt.stairs
with np.histogram
Since np.histogram
returns edges, it works directly with plt.stairs
:
data = np.random.normal(5, 3, 3000)
bins = np.linspace(0, 10, 20)
hist, edges = np.histogram(data, bins)
plt.stairs(hist, edges)
This should be easy but I have just started toying with matplotlib and python. I can do a line or a scatter plot but i am not sure how to do a simple step function. Any help is much appreciated.
x = 1,2,3,4
y = 0.002871972681775004, 0.00514787917410944, 0.00863476098280219, 0.012003316194034325
Draw two lines, one at y=0, and one at y=1, cutting off at whatever x
your step function is for.
e.g. if you want to step from 0 to 1 at x=2.3
and plot from x=0
to x=5
:
import matplotlib.pyplot as plt
# _
# if you want the vertical line _|
plt.plot([0,2.3,2.3,5],[0,0,1,1])
#
# OR:
# _
# if you don't want the vertical line _
#plt.plot([0,2.3],[0,0],[2.3,5],[1,1])
# now change the y axis so we can actually see the line
plt.ylim(-0.1,1.1)
plt.show()
I think you want pylab.bar(x,y,width=1)
or equally pyplot
‘s bar method. if not checkout the gallery for the many styles of plots you can do. Each image comes with example code showing you how to make it using matplotlib.
It seems like you want step
.
E.g.
import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [0.002871972681775004, 0.00514787917410944,
0.00863476098280219, 0.012003316194034325]
plt.step(x, y)
plt.show()
If you have non-uniformly spaced data points, you can use the drawstyle
keyword argument for plot
:
x = [1,2.5,3.5,4]
y = [0.002871972681775004, 0.00514787917410944,
0.00863476098280219, 0.012003316194034325]
plt.plot(x, y, drawstyle='steps-pre')
Also available are steps-mid
and steps-post
.
In case someone just wants to stepify some data rather than actually plot it:
def get_x_y_steps(x, y, where="post"):
if where == "post":
x_step = [x[0]] + [_x for tup in zip(x, x)[1:] for _x in tup]
y_step = [_y for tup in zip(y, y)[:-1] for _y in tup] + [y[-1]]
elif where == "pre":
x_step = [_x for tup in zip(x, x)[:-1] for _x in tup] + [x[-1]]
y_step = [y[0]] + [_y for tup in zip(y, y)[1:] for _y in tup]
return x_step, y_step
New in matplotlib 3.4.0
There is a new plt.stairs
method to complement plt.step
:
plt.stairs
and the underlyingStepPatch
provide a cleaner interface for plotting stepwise constant functions for the common case that you know the step edges.This supersedes many use cases of
plt.step
, for instance when plotting the output ofnp.histogram
.
Check out the official matplotlib gallery for how to use plt.stairs
and StepPatch
.
When to use plt.step
vs plt.stairs
-
Use the original
plt.step
if you have reference points. Here the steps are anchored at[1,2,3,4]
and extended to the left:plt.step(x=[1,2,3,4], y=[20,40,60,30])
-
Use the new
plt.stairs
if you have edges. The previous[1,2,3,4]
step points correspond to[1,1,2,3,4]
stair edges:plt.stairs(values=[20,40,60,30], edges=[1,1,2,3,4])
Using plt.stairs
with np.histogram
Since np.histogram
returns edges, it works directly with plt.stairs
:
data = np.random.normal(5, 3, 3000)
bins = np.linspace(0, 10, 20)
hist, edges = np.histogram(data, bins)
plt.stairs(hist, edges)