7

I am using matplotlib to plot some step functions from a dataframe

df['s1'].plot(c='b', drawstyle="steps-post")
df['s2'].plot(c='b', drawstyle="steps-post")
...

The result looks like

enter image description here

I would like to have this only plot the horizontal lines, not the vertical lines connecting the jump points. I could not find a straightforward parameter for plot that would seem to do that. Is there a way to do this?

2 Answers 2

8

There is no built-in option to produce a step function without vertical lines as far as I can tell. But you may easily build one yourself. The following uses the fact that np.nan is not plotted and cuts the line. So adding np.nan in between the steps suppresses the vertical line.

import matplotlib.pyplot as plt
import numpy as np

def mystep(x,y, ax=None, where='post', **kwargs):
    assert where in ['post', 'pre']
    x = np.array(x)
    y = np.array(y)
    if where=='post': y_slice = y[:-1]
    if where=='pre': y_slice = y[1:]
    X = np.c_[x[:-1],x[1:],x[1:]]
    Y = np.c_[y_slice, y_slice, np.zeros_like(x[:-1])*np.nan]
    if not ax: ax=plt.gca()
    return ax.plot(X.flatten(), Y.flatten(), **kwargs)
    
x = [1,3,4,5,8,10,11]
y = [5,4,2,7,6,4,4]

mystep(x,y, color="crimson")

plt.show()

enter image description here

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

2 Comments

This answer corresponds to the drawstyle='steps-post' keyword argument in plt.plot() for drawing step graphs i.e. the y-value of the flat line at any given x-value is equal to the y-value at the next smallest x-value from the passed x array. For example using the arrays in @ImportanceOfBeingErnest's answer, the y-value at x=1.5 equals the y-value at x=1 (i.e. y=5).
This is actually not true as drawstyle='steps-post' is adding vertical lines between the horizontal ones. I had to change one line in the mysteps-function so X could be also a object with datetime: Y = np.c_[y_slice, y_slice, np.zeros(x[:-1].shape)*np.nan]
5

Seems like hlines is the "correct" (built-in) way to do this:

import matplotlib.pyplot as plt

x = [1,3,4,5,8,10,11]
y = [5,4,2,7,6,4]

plt.hlines(y,x[:-1],x[1:])
plt.show()

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.