- The issue with the current implementation is you only get a result for
'A1' and then presumably you have repeat the code to get the other data.
pandas.wide_to_long will allow for all the columns with a stub following the date, to be transformed.
- This requires that the stub be at the front, which can be adjusted with a list comprehension on the column names.
suffix='\d+\/\d+\/\d+' matches the date format to be extracted.
- Once the dataframe is transformed, it's easier to use and access all of the data.
- Use
pandas.DataFrame.pivot to reshape the data to plot '(LP%)'
- Plot directly with
pandas.DataFrame.plot
- The line plot x-axis data format is
%M-%D %H because there is only a small amount data. The format will update when there are more days of data.
- The index will be the x-axis, so it's not necessary to specify
x=.
- Use
y= to specify column names, or don't use it and all the columns will be plotted.
- Tested in
python 3.8.11, pandas 1.3.2, matplotlib 3.4.3, seaborn 0.11.2
import pandas as pd
# sample data
data = {'RowName': ['A1', 'A2', 'A3'], '20/09/21 (LP%)': [120, 0, 0], '20/09/21 (Vol)': [13, 1, 31], '20/09/21 (OI)': [0, 0, 0], '21/09/21 (LP%)': [135.0, 143.43, 143.43], '21/09/21 (Vol)': [68.6, 63.81, 58.1], '21/09/21 (OI)': [0, 0, 0], '22/09/21 (LP%)': [130, 0, 0], '22/09/21 (Vol)': [0, 0, 0], '22/09/21 (OI)': [75, 80, 85]}
df = pd.DataFrame(data)
# adjust the column names so the stub is before the date
df.columns = [' '.join(col.split(' ')[::-1]) if len(col.split(' ')) > 1 else col for col in df.columns]
# convert to long form
df = pd.wide_to_long(df, stubnames=['(LP%)', '(Vol)', '(OI)'], i=['RowName'], sep=' ', j='Date', suffix='\d+\/\d+\/\d+').reset_index()
# convert the Date column to a datetime dtype
df.Date = pd.to_datetime(df.Date).dt.date
# display(df.head())
RowName Date (LP%) (Vol) (OI)
0 A1 2021-09-20 120.00 13.00 0
1 A2 2021-09-20 0.00 1.00 0
2 A3 2021-09-20 0.00 31.00 0
3 A1 2021-09-21 135.00 68.60 0
4 A2 2021-09-21 143.43 63.81 0
# pivot the LP% column
dlp = df.pivot(index='Date', columns='RowName', values='(LP%)')
# display(dlp)
RowName A1 A2 A3
Date
2021-09-20 120.0 0.00 0.00
2021-09-21 135.0 143.43 143.43
2021-09-22 130.0 0.00 0.00
# plot any specific column
dlp.plot(y=['A1'], rot=0, figsize=(10, 5), marker='o', title='LP%: A1')

# or all 3
dlp.plot(rot=0, figsize=(10, 5), marker='o', title='LP%')
- The
'A3' line covers the 'A2' line because the data is the same

# specify the kind parameter for a bar plot
dlp.plot(kind='bar', rot=0, figsize=(10, 5), title='LP%')

- Add one more step and use
pandas.DataFrame.melt to reshape the df into a completely long form to easily plot all of the data with seaborn.relplot.
seaborn is a high-level API for matplotlib.
import seaborn as sns
# melt
dfm = df.melt(id_vars=['RowName', 'Date'])
# display(dfm.head())
RowName Date variable value
0 A1 2021-09-20 (LP%) 120.00
1 A2 2021-09-20 (LP%) 0.00
2 A3 2021-09-20 (LP%) 0.00
3 A1 2021-09-21 (LP%) 135.00
4 A2 2021-09-21 (LP%) 143.43
# plot
sns.relplot(kind='line', data=dfm, x='Date', y='value', marker='o', row='variable', hue='RowName', height=3.5, aspect=2.25)
