29
votes

I am trying to plot using matplotlib. The plot showed a problem that the Y axis is not ordered.

Here is the code.

# -*- coding: UTF-8 -*-
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import numpy as np
I020 = [ line.strip('\n').split(",") for line in 
open(r'D:\Users\a0476\Anaconda3\TickData\PV5sdata1.csv')][1:]
Time = [ datetime.datetime.strptime(line[0],"%H%M%S%f") for line in I020 ]
Time1 = [ mdates.date2num(line) for line in Time ]
Solar = [ line[1] for line in I020 ]
order = np.argsort(Time1)
xs = np.array(Time1)[order]
ys = np.array(Solar)[order]
plt.title('Solar data')
plt.xlabel('Time')
plt.ylabel('Solar')
ax.plot_date(xs, ys, 'k-')
hfmt = mdates.DateFormatter('%H:%M:%S')
ax.xaxis.set_major_formatter(hfmt)
plt.show()

The CSV data

time        solar
7000000     50.35
8000000     41.01
9000000     69.16
10000000    94.5
11000000    111.9
12000000    103
13000000    98.6
14000000    36.45
15000000    34.74
16000000    34.17
17000000    34.6

enter image description here

1
Wow this is really strange. Unfortunately I cannot reproduce the behavior, as I cannot run your code without the data. Can you provide a minimal example that reproduces the behavior? - Amos Egel
This is because your data are strings. - DavidG
@DavidG read your answer and immediately facepalmed - jmoz
I just did the same thing jmoz. - Windy71

1 Answers

84
votes

The reason this happens is because your data is being plotted as strings.

The solution is to convert your y axis data to floats. This can be done by simply casting to a float in your list comprehension:

Solar = [float(line[1]) for line in I020]

I would also suggest to use matplotlib's auto formatting of the x -axis when using dates/times. This will rotate the labels etc to make the graph look better:

plt.gcf().autofmt_xdate()

Your example becomes:

I020 = [ line.strip('\n').split(",") for line in open('PV5sdata1.csv')][1:]
Time = [datetime.datetime.strptime(line[0],"%H%M%S%f") for line in I020]
Time1 = [mdates.date2num(line) for line in Time]
Solar = [float(line[1]) for line in I020]

xs = np.array(Time1)  # You don't really need to do this but I've left it in
ys = np.array(Solar)

fig, ax = plt.subplots() # using matplotlib's Object Oriented API

ax.set_title('Solar data')
ax.set_xlabel('Time')
ax.set_ylabel('Solar')
ax.plot_date(xs, ys, 'k-')

hfmt = mdates.DateFormatter('%H:%M:%S')
ax.xaxis.set_major_formatter(hfmt)
plt.gcf().autofmt_xdate()

plt.show()

Which gives:

enter image description here