Thomas
Thomas

Reputation: 539

Step plot by reading from file

I am a newbie to matplotlib. I am trying to plot step function and having some trouble. Right now I am able to read from the file and plot it as shown below. But the graph in the top is not in steps and the one below is not a proper step. I saw examples to plot step function by giving x & y value. I am not sure how to do it by reading from a file though. Can someone help me?

from pylab import plotfile, show, gca
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook

fname = cbook.get_sample_data('sample.csv', asfileobj=False)

plotfile(fname, cols=(0,1), delimiter=' ')
plotfile(fname, cols=(0,2), newfig=False, delimiter=' ')
plt.show()

Sample inputs(3 columns):

27023927    3   0
27023938    2   0
27023949    3   0
27023961    2   0
27023972    3   0
27023984    2   0
27023995    3   0
27024007    2   0
27024008    2   1
27024018    3   1
27024030    2   1
27024031    2   0
27024041    3   0
27024053    2   0
27024054    2   1
27024098    2   0

Note: I have made the y-axis1 values as 3 & 2 so that this graph can occur in the top and another y-axis2 values 0 & 1 so that it comes in the bottom as shown below


Waveform as it looks now enter image description here

Upvotes: 1

Views: 740

Answers (3)

Thomas
Thomas

Reputation: 539

Thanks for the suggestions. I was able to plot it after some research and here is my code,

import csv
import datetime
import matplotlib.pyplot as plt
import numpy as np
import dateutil.relativedelta as rd
import bisect
import scipy as sp

fname = "output.csv"


portfolio_list = []
x = []
a = []
b = []

portfolio = csv.DictReader(open(fname, "r"))
portfolio_list.extend(portfolio)


for data in portfolio_list:
    x.append(data['i'])
    a.append(data['a'])
    b.append(data['b'])

stepList = [0, 1,2,3]

fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111)

plt.step(x, a, 'g', where='post')
plt.step(x, b, 'r', where='post')

plt.show()

and got the image like, enter image description here

Upvotes: 0

Greg
Greg

Reputation: 12234

Essentially your resolution is too low, for the lower plot the steps (except the last one) occur over 1 unit in x, while the steps are about an order of magnitude larger. This gives the appearance of steps while if you zoom in you will see the vertical lines have a non-infinite gradient (true steps change with an infinite gradient).

This is the same problem for both the top and bottom plots. We can easily remedy this by using the step function. You will generally find it easier to import the data, in this example I use the powerful numpy genfromtxt. This loads the data as an array data:

import numpy as np
import matplotlib.pylab as plt

data = np.genfromtxt('test.csv', delimiter=" ")

ax1 = plt.subplot(2,1,1)
ax1.step(data[:,0], data[:,1])

ax2 = plt.subplot(2,1,2)
ax2.step(data[:,0], data[:,2])

plt.show()

enter image description here

If you are new to python then there may be two things to mention, we use two subplots (ax1 and ax2) to plot the data rather than plotting on the same plot (this means you wouldn't need to add values to spatially separate them). We access the elements of the array through the [] this gives the [column, row] with : meaning all columns and and index i being the ith column

Upvotes: 1

thorink
thorink

Reputation: 744

I would propose to load the data to a numpy array

import numpy as np
data = np.loadtxt('sample.csv')

And than plot it:

# first point
ax = [data[0,0]]
ay = [data[0,1]]

for i in range(1, data.shape[0]):
    if ay[-1] != data[i,1]: # if y value has changed
        # add current x and old y
        ax.append(data[i,0])
        ay.append(ay[-1])
        # add current x and current y
        ax.append(data[i,0])
        ay.append(data[i,1])

import matplotlib.pyplot as plt

plt.plot(ax,ay)
plt.show()

What my solution differs from yours, is that I plot two points for every change in y. The two points produce this 90 degree bend. I Only plot the first curve. Change [?,1] to [?,2] for the second one.

Upvotes: 0

Related Questions