[matplotlib]: write dates on x axis - python

Here an example code in which I would like to draw the entire date on the x axis
import datetime
import matplotlib.pyplot as plt
import random
import numpy as np
from matplotlib.dates import DateFormatter
years = np.arange( 2005, 2016, 1)
years[1] = 2005
years[2] = 2005
months = [ 3, 2, 1, 5, 7, 12, 2, 3, 5, 2, 6]
dates = []
for Y in years:
dates = dates + [ datetime.datetime(Y, 6 , 4) ]
y = np.random.randn(len(dates))
fig, ax = plt.subplots()
ax.plot_date(dates, y, 'r+', ms = 2, mew = 12)
ax.fmt_xdata = DateFormatter('%y-%m-%d')
fig.autofmt_xdate()
plt.show()
Unfortunately the result is this
And what I need is to write all the date on the x axis like in this picture
What you suggest me to change on my code?

ax.fmt_xdata is the formatter for the dates usually only used for the hover functionality in interactive plots.
What you want here is to set the major formatter of the xaxis to a DateFormatter:
ax.xaxis.set_major_formatter(DateFormatter('%b-%d-%Y'))

Related

Plotting time series data with with 30sec break point and color

I am new in python programming. I can simply plot the input data shown in the figure with my code but how can I plot the time series data as mention in the figure. Any code and suggestions will be thankful.
My code is:
import matplotlib.pyplot as plt
import numpy as np
y_values = [5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1]
x_values = np.arange(30, 331, 30)
plt.figure()
plt.plot(x_values,y_values,"-x")
plt.show()
Although there is a way to draw a series of rectangular shapes, we used a general method and used horizontal bar charts. We added a list for the values in the bar chart and stacked the values. Class label names and class titles are now supported as annotations. You can try various other parameters.
import matplotlib.pyplot as plt
import numpy as np
y = [5]*11
y_values = [5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1]
x_values = np.arange(30, 331, 30)
fig, ax = plt.subplots(figsize=(12,1))
ax.barh(y=0, height=1.0, edgecolor='k', width=y[0], label='Time Interval')
for i in range(len(y)):
if y_values[i] == 5:
color = 'y'
else:
color = 'm'
ax.barh(y=0, left=sum(y[:i]), height=1.0, width=y[i], color=color, edgecolor='k', label='Time Interval')
for s in ['top','bottom','left','right']:
ax.spines[s].set_visible(False)
for i,(p,t) in enumerate(zip(y, y_values)):
ax.text(y=0.6, x=2.5+p*i, s=str(t))
ax.text(-0.08, 1, 'Class', transform=ax.transAxes)
ax.set_xticks([])
ax.set_yticks([])
ax.set_ylabel('Time Interval', rotation=0, labelpad=40, loc='center')
plt.show()
Try:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
y_values = ['class', 5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1]
x_values = np.arange(30, 331, 30)
x_values = np.concatenate((['Time'],x_values))
df = pd.DataFrame(data={'class': y_values, 'Time': x_values})
colors = {5: 'gold', 1: 'darkviolet'}
df['colors'] = df['class'].map(colors)
df['colors'].fillna('white', inplace=True)
df['Time'].iloc[1:] = ''
print(df)
fig, ax =plt.subplots(1,1)
ax.axis('tight')
ax.axis('off')
data = df.T.values
colors = [data[2].tolist()]
table = ax.table(cellText=[data[1].tolist()], colLabels=data[0].tolist(),loc="center", cellColours=colors)
table.set_fontsize(14)
for i in range(len(data[0])):
table[0, i].visible_edges = ''
table[1, 0].visible_edges = ''
table.scale(1.5, 1.5)
plt.show()

Why aren't my quiver arrows pointing the correct direction?

I am struggling to understand why my quiver arrows aren't pointing in the proper direction when plotting wind direction. I have provided an MWE below that has arrays dates, wind_dir, and wind_speed and plots their values over time. I use angles parameter as 'xy' so that arrows point from (x,y) to (x+u,y+v). Anyone have a minute to help?
from matplotlib.dates import date2num
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
from matplotlib.dates import DateFormatter, YearLocator, MonthLocator, DayLocator, HourLo
#from file.py import *
dates = [datetime(2020, 4, 22, 0, 53),
datetime(2020, 4, 22, 1, 53),
datetime(2020, 4, 22, 2, 53),
datetime(2020, 4, 22, 3, 53)]
idx = date2num(dates)
wind_dir = [170., 150., 130., 230.]
wind_speed = [3.6, 2.57, 4.12, 7.09 ]
U = wind_speed*np.cos(wind_dir)
V = wind_speed*np.sin(wind_dir)
fig, ax1 = plt.subplots()
qq = ax1.quiver(idx, np.ones(len(idx))*1,U,V,wind_speed,
pivot='mid',angles='xy',cmap=plt.cm.jet)
plt.colorbar(qq, cmap=plt.cm.jet)
ax1.plot(dates, wind_speed)
# format the x ticks
months = MonthLocator()
days = DayLocator()
hours = HourLocator(byhour=[0,1,2,3])
hours_each = HourLocator() # Find all hours
dateFmt = DateFormatter('%b %d\n%H:%M') # Tick label format style
ax1.xaxis.set_major_locator(hours)
ax1.xaxis.set_major_formatter(dateFmt) # Set the x-axis labels
ax1.xaxis.set_minor_locator(hours_each)
plt.xticks(rotation=30)
plt.show()

how to make graph

i want to make graph using matplotlib in python.
np.load(name.npy')
i searched many things and i tried
for example..just...
x = [dt.datetime(2003, 05, 01), dt.datetime(2008, 06, 01)]
df = np.load(r'file')
y = df
Replace the end date on the date-range to your desired graph, and the 'y' should be array loaded
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
start_date = '2003-05-01'
y = np.load(r'c:\python27\abnormal.npy')
x = pd.date_range(start=start_date, periods=len(y), freq='D')
plt.plot(x,y,'.')
plt.show()
If your input array does not contain ordered pairs such as [(0,1), (1,1), (2,2)] and only contains one set of numbers '[1, 2, 3, 4]`, you neeed to create a set of x-coordinates. For a time series in days, you could try something like this:
import datetime
import numpy as np
import matplotlib.pyplot as plt
def getData(fileName):
# Load the data file to serve as y-axis coordinates
y = np.load(fileName)
# For each y coordinate we need an x coordinate
time_offset = list(range(len(y)))
# Convert time_offset to a time-series
# We will assume x-values equal number of days since a beginDate
x = []
beginDate = datetime.date(2015, 6, 1) # The date to begin our time series
for n in time_offset:
date = beginDate + datetime.timedelta(n) # Date + number_of_Days_passed
x.append(date)
return x, y
def plot(x, y):
# Plot the data
fig = plt.figure()
ax = plt.subplot2grid((1,1), (0,0), rowspan=1, colspan=1)
ax.scatter(x, y)
for label in ax.xaxis.get_ticklabels():
label.set_rotation(90)
ax.grid(True)
plt.subplots_adjust(left=.10, bottom=.19, right=.93, top=.95, wspace=.20, hspace=0)
plt.show()
x, y = getData('abnormal.npy')
plot(x, y)

python matplotlib setting years in x axis

I have coded the following program with matplotlib to graph no.of elements with time.
import pylab
import numpy as np
import datetime
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
date1 = datetime.date(1995, 1, 1)
date2 = datetime.date(2004, 4, 12)
years = YearLocator() # every year
months = MonthLocator() # every month
yearsFmt = DateFormatter('%Y')
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)
ax.xaxis.set_minor_locator(months)
ax.autoscale_view()
pylab.ylim(0, 250)
plt.yticks(np.linspace(0,250,6,endpoint=True))
pylab.xlabel('YEAR')
pylab.ylabel('No. of sunspots')
pylab.title('SUNSPOT VS YEAR GRAPH')
a=[[50,50],[100,100],[250, 250],[200,200],[150,150]]
plt.plot(*zip(*a), marker='o', color='r', ls='')
The output is as follows
However,I was expecting it to display years instead of numbers in x-axis.
You are plotting years, but the years are 50, 100, 250, 200, and 150. These are the first element in the lists inside of a, which is passed to pyplot.plot as the x values.
You want to define your dates somewhere, though you'll also probably want to set the xticks to be the same as the dates you're plotting, as I can tell you care about the graph looking neat.
import pylab
import numpy as np
import datetime
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
Also, don't forget to import pyplot
import matplotlib.pyplot as plt
Here are some example dates. You can change them to whatever exact date you have for the sunspot measurements.
a=[[datetime.date(1995, 1, 1), 50],
[datetime.date(2000, 1, 1), 100],
[datetime.date(2005, 1, 1), 250],
[datetime.date(2010, 1, 1), 200],
[datetime.date(2015, 1, 1), 150]
]
years = YearLocator() # every year
months = MonthLocator() # every month
yearsFmt = DateFormatter('%Y')
Call gca to get current axis before you modify the axis.
ax = plt.gca()
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)
ax.xaxis.set_minor_locator(months)
ax.autoscale_view()
pylab.ylim(0, 250)
plt.yticks(np.linspace(0,250,6,endpoint=True))
Pick out the dates from the a array to use them as xtick labels.
dates = [date for date,sunspot in a]
plt.xticks(dates)
pylab.xlabel('YEAR')
pylab.ylabel('No. of sunspots')
pylab.title('SUNSPOT VS YEAR GRAPH')
plt.plot(*zip(*a), marker='o', color='r', ls='')
plt.show()

How do I change the range of the x-axis with datetimes in matplotlib?

I'm trying to plot a graph of dates on the x-axis and values on the y-axis. It works fine, except that I can't get the range of the x-axis to be appropriate. The x-axis range is always Jan 2012 to Jan 2016, despite my dates being from today. I am even specifying that xlim should be the first and last date.
I'm writing this for python-django, if that's relevant.
import datetime
import matplotlib.pyplot as plt
x = [datetime.date(2014, 1, 29), datetime.date(2014, 1, 29), datetime.date(2014, 1, 29)]
y = [2, 4, 1]
fig, ax = plt.subplots()
ax.plot_date(x, y)
ax.set_xlim([x[0], x[-1]])
canvas = FigureCanvas(plt.figure(1))
response = HttpResponse(content_type='image/png')
canvas.print_png(response)
return response
And here is the output:
Edit:
Having seen actual data from the OP, all of the values are at the same date/time. So matplotlib is automatically zooming the x-axis out. You can still manually set the x-axis limits with datetime objects
If I do something like this on matplotlib v1.3.1:
import datetime
import matplotlib.pyplot as plt
x = [datetime.date(2014, 1, 29)] * 3
y = [2, 4, 1]
fig, ax = plt.subplots()
ax.plot_date(x, y, markerfacecolor='CornflowerBlue', markeredgecolor='white')
fig.autofmt_xdate()
ax.set_xlim([datetime.date(2014, 1, 26), datetime.date(2014, 2, 1)])
ax.set_ylim([0, 5])
I get:
And the axes limits match the dates that I specified.
With help from Paul H's solution, I was able to change the range of my time-based x-axis.
Here is a more general solution for other beginners.
import matplotlib.pyplot as plt
import datetime as dt
# Set X range. Using left and right variables makes it easy to change the range.
#
left = dt.date(2020, 3, 15)
right = dt.date(2020, 7, 15)
# Create scatter plot of Positive Cases
#
plt.scatter(
x, y, c="blue", edgecolor="black",
linewidths=1, marker = "o", alpha = 0.8, label="Total Positive Tested"
)
# Format the date into months & days
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
# Change the tick interval
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=30))
# Puts x-axis labels on an angle
plt.gca().xaxis.set_tick_params(rotation = 30)
# Changes x-axis range
plt.gca().set_xbound(left, right)
plt.show()

Categories

Resources