I generate a plot using the following code:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
index=pd.date_range('2018-01-01',periods=200)
data=pd.Series(np.random.randn(200),index=index)
plt.figure()
plt.plot(data)
Which gives me a plot, looking as follows:
It looks like Matplotlib has decided to format the x-ticks as %Y-%m (source)
I am looking for a way to retrieve this date format. A function like ax.get_xtickformat(), which would then return %Y-%m. Which is the smartest way to do this?
There is no built-in way to obtain the date format used to label the axes. The reason is that this format is determined at drawtime and may even change as you zoom in or out of the plot.
However you may still determine the format yourself. This requires to draw the figure first, such that the ticklocations are fixed. Then you may query the formats used in the automatic formatting and select the one which would be chosen for the current view.
Note that the following assumes that an AutoDateFormatter or a formatter subclassing this is in use (which should be the case by default).
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
index=pd.date_range('2018-01-01',periods=200)
data=pd.Series(np.random.randn(200),index=index)
plt.figure()
plt.plot(data)
def get_fmt(axis):
axis.axes.figure.canvas.draw()
formatter = axis.get_major_formatter()
locator_unit_scale = float(formatter._locator._get_unit())
fmt = next((fmt for scale, fmt in sorted(formatter.scaled.items())
if scale >= locator_unit_scale),
formatter.defaultfmt)
return fmt
print(get_fmt(plt.gca().xaxis))
plt.show()
This prints %Y-%m.
If you want to edit the format of the date in myFmt = DateFormatter("%d-%m-%Y"):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
index=pd.date_range('2018-01-01',periods=200)
data=pd.Series(np.random.randn(200),index=index)
fig, ax = plt.subplots()
ax.plot(index, data)
myFmt = DateFormatter("%d-%m-%Y")
ax.xaxis.set_major_formatter(myFmt)
fig.autofmt_xdate()
plt.show()
Related
Currently I'm doing some data visualization using python, matplotlib and mplcursor that requires to show different parameters and values at the same time in a certain time period.
Sample CSV data that was extracted from a system:
https://i.stack.imgur.com/fjd1d.png
My expected output would look like this:
https://i.stack.imgur.com/zXGXA.png
Found the same case but they were using numpy functions: Add the vertical line to the hoverbox (see pictures)
Hoping someone will suggest what is the best approach of my problem.
Code below:
import matplotlib.pyplot as plt
import numpy as np
import mplcursors
import pandas as pd
fig, ax=plt.subplots()
y1=ax.twinx()
y2=ax.twinx()
y2.spines.right.set_position(("axes", 1.05))
df=pd.read_csv(r"C:\Users\OneDrive\Desktop\sample.csv")
time=df['Time']
yd1=df['Real Power']
yd2=df['Frequency']
yd3=df['SOC']
l1=ax.plot(time,yd1,color='black', label='Real Power')
l2=y1.plot(time,yd2, color='blue', label='Frequency')
l3=y2.plot(time,yd3, color='orange', label='SOC')
df=pd.DataFrame(df)
arr=df.to_numpy()
print(arr)
def show_annotation(sel):
x=sel.target[0]
annotation_str = df['Real Power'][sel.index]
#sel.annotation.set_text(annotation_str)
fig.autofmt_xdate()
cursor=mplcursors.cursor(hover=True)
cursor.connect('add', show_annotation)
plt.show()```
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
load_file=pd.read_excel(r'E:\CCNC\CCNCCodes\Modulated
output\plot_oriented_ss_data.xlsx',header=0)
load_file.columns
s=load_file.loc[0:49,['Timeseries','ccn_0.1']] s
s1=s
s['Timeseries'] = s['Timeseries'].astype(str)
plt.plot(s1[0:49]['Timeseries'],s1[0:5762]['ccn_0.1'],color='b')
plt.grid()
plt.show()
Please tell me where do I exact need to make the change to avoid the overlapping of time series in x-axis.
Instead of converting your 'Timeseries' to str, you should convert them to datetime using:
s['Timeseries'] = pd.to_datetime(s['Timeseries'])
I am trying to plot more than 10k data points, where I want to plot a data properties versus Timestamp. But on the x-axis the timestamps are overlapping and not visible.
How can I reduce the amount of labels on the x-axis, so that they are legible?
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
sns.set_style("whitegrid")
data = pd.read_csv('0912Testday4.csv',header=2)
for i in data.columns:
if i!='TIMESTAMP':
sns.lineplot(x="TIMESTAMP",y=i,data = data)
plt.title(f"{i} vs TIMESTAMP")
plt.show()
Example plot demonstrating the problem:
Update:TIMESTAMP was in string format by converting into datatime format it resolves the problem.
data['TIMESTAMP'] = pd.to_datetime(data['TIMESTAMP'])
Update:TIMESTAMP was in string format by converting into datetime format it resolves the problem.
data['TIMESTAMP'] = pd.to_datetime(data['TIMESTAMP'])
Please make sure that TIMESTAMP is a datetime object. This should not happen when the x axis is a datetime. (You can use pd.to_datetime to convert int, float, str, and ... to datetime.)
If TIMESTAMP is a datetime, you can use the autofmt_xdate() method:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots() # Create a figure and a set of subplots.
sns.set_style("whitegrid")
data = pd.read_csv('0912Testday4.csv',header=2)
# Use the following line if the TIMESTAMP is not a datetime.
# (You may need to change the format from "%Y-%m-%d %H:%M:%S+00:00".)
# data['TIMESTAMP'] = pd.to_datetime(data.TIMESTAMP, format="%Y-%m-%d %H:%M:%S+00:00")
for i in data.columns:
if i!='TIMESTAMP':
sns.lineplot(x="TIMESTAMP", y=i, data=data, ax=ax)
fig.autofmt_xdate() # rotate and right align date ticklabels
plt.title(f"{i} vs TIMESTAMP")
plt.show()
I didn't encounter such problem with sns.lineplot
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")
# example data
time_stamps = pd.date_range('2019-01-01', '2020-01-01', freq='H')
vals =[np.random.randint(0, 1000) for i in time_stamps]
data_df = pd.DataFrame()
data_df['time'] = time_stamps
data_df['value'] = vals
print(data_df.shape)
# plotting
fig, ax = plt.subplots()
sns.lineplot(x='time', y='value', data=data_df)
plt.show()
sns automatically selects the x ticks and x labels.
alternatively, you can use ax.set_xticks and ax.set_xlabels to set the x ticks and x labels manually.
Also you may use fig.autofmt_xdate() to rotate the x labels
I am trying to develop a candlestick chart with matplotlib but for some reason, dates are not coming up in the x-axis. After searching in stackoverflow, I understood that the dates need to be converted to float numbers so i converted them as well but still it's not working. New to this python and matplotlib. ANy help would be greatly appreciated.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ohlc
import matplotlib.dates as dts
import matplotlib.ticker as mTicker
from datetime import datetime
my_file=pd.read_csv("C:\\path\\to\\file\\file.csv",sep=",",names=['Date','Open','High','Low','Close','AdjClose','Volume'],skiprows=1)
dateseries=[]
for i in my_file['Date']:
dateseries.append(dts.date2num(datetime.strptime(i,'%Y-%m-%d')))
print(dateseries)
fig,ax1=plt.subplots()
candlestick2_ohlc(ax1,my_file['Open'], my_file['High'],my_file['Low'], my_file['Close'], width=0.7,colorup='#008000', colordown='#FF0000')
plt.show()
Sample data:
Date,Open,High,Low,Close,Volume1,Volume2
2017-05-08,149.029999,153.699997,149.029999,153.009995,153.009995,48752400
2017-05-09,153.869995,154.880005,153.449997,153.990005,153.990005,39130400
2017-05-10,153.630005,153.940002,152.110001,153.259995,153.259995,25805700
In general, you are right about "the dates need to be converted to float numbers". Then to display dates on x-axis, you would need to "convert" them back. If you don't mind using candlestick_ohlc, that might be easier for setting the x-axis for your case here:
import io
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick_ohlc
from matplotlib.dates import date2num, DayLocator, DateFormatter
import pandas as pd
s = """Date,Open,High,Low,Close,Volume1,Volume2
2017-05-08,149.029999,153.699997,149.029999,153.009995,153.009995,48752400
2017-05-09,153.869995,154.880005,153.449997,153.990005,153.990005,39130400
2017-05-10,153.630005,153.940002,152.110001,153.259995,153.259995,25805700"""
my_file = pd.read_table(io.StringIO(s), sep=',', header=0)
my_file['Date'] = date2num(pd.to_datetime(my_file['Date']).tolist())
fig, ax=plt.subplots()
candlestick_ohlc(ax, my_file.as_matrix())
ax.xaxis.set_major_locator(DayLocator())
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
plt.show()
I have the following code to plot a chart with matplotlib
#!/usr/bin/env python
import matplotlib.pyplot as plt
import urllib2
import json
req = urllib2.urlopen("http://localhost:17668/retrieval/data/getData.json? pv=LNLS:ANEL:corrente&donotchunk")
data = json.load(req)
secs = [x['secs'] for x in data[0]['data']]
vals = [x['val'] for x in data[0]['data']]
plt.plot(secs, vals)
plt.show()
The secs arrays is epoch time.
What I want is to plot the data in the x axis (secs) as a date (DD-MM-YYYY HH:MM:SS).
How can I do that?
To plot date-based data in matplotlib you must convert the data to the correct format.
One way is to first convert your data to datetime objects, for an epoch timestamp you should use datetime.datetime.fromtimestamp().
You must then convert the datetime objects to the right format for matplotlib, this can be handled using matplotlib.date.date2num.
Alternatively you can use matplotlib.dates.epoch2num and skip converting your date to datetime objects in the first place (while this will suit your use-case better initially, I would recommend trying to keep date based date in datetime objects as much as you can when working, it will save you a headache in the long run).
Once you have your data in the correct format you can plot it using plot_date.
Finally to format your x-axis as you wish you can use a matplotlib.dates.DateFormatter object to choose how your ticks will look.
import matplotlib.pyplot as plt
import matplotlib.dates as mdate
import numpy as np
# Generate some random data.
N = 40
now = 1398432160
raw = np.array([now + i*1000 for i in range(N)])
vals = np.sin(np.linspace(0,10,N))
# Convert to the correct format for matplotlib.
# mdate.epoch2num converts epoch timestamps to the right format for matplotlib
secs = mdate.epoch2num(raw)
fig, ax = plt.subplots()
# Plot the date using plot_date rather than plot
ax.plot_date(secs, vals)
# Choose your xtick format string
date_fmt = '%d-%m-%y %H:%M:%S'
# Use a DateFormatter to set the data to the correct format.
date_formatter = mdate.DateFormatter(date_fmt)
ax.xaxis.set_major_formatter(date_formatter)
# Sets the tick labels diagonal so they fit easier.
fig.autofmt_xdate()
plt.show()
You can change the ticks locations and formats on your plot:
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
import time
secs = [10928389,102928123,383827312,1238248395]
vals = [12,8,4,12]
plt.plot(secs,vals)
plt.gcf().autofmt_xdate()
plt.gca().xaxis.set_major_locator(mtick.FixedLocator(secs))
plt.gca().xaxis.set_major_formatter(
mtick.FuncFormatter(lambda pos,_: time.strftime("%d-%m-%Y %H:%M:%S",time.localtime(pos)))
)
plt.tight_layout()
plt.show()