Matplotlib plotting multiple line graph into one axes

I’m very new to Matplotlib and it seems I don’t understand how to plot graphs with customized x,y axis. I have a Dataframe (requested csv file) with 2 elements (time) for each day. I want to plot the elements pair wise using one x-axis. Here is my code:

#creating an example dataframe
low = ['08:20','11:50','09:44','11:12']
high = ['10:45','08:05','11:55','09:10']
low = pd.to_datetime(low).time
high = pd.to_datetime(high).time
col_name = ['lowtide','hightide']
ind_val = pd.date_range(start='01-01-2021',periods=4)

df = pd.DataFrame(data= zip(low,high),columns=col_name,index=ind_val)
print(df)

             lowtide  hightide
2021-01-01  08:20:00  10:45:00
2021-01-02  11:50:00  08:05:00
2021-01-03  09:44:00  11:55:00
2021-01-04  11:12:00  09:10:00

On the x axis there should be a timeline and the y axis just has the lowtide and hightide point. I transpose the DataFrame because I didnt know how to plot row wise and use the column.names as y axis value and made every element to a dtype=str, because Matplotlib argued about using datetime objects.

#transpose df for plotting because I don't know how to plot row wise
tides = df.T

print(tides)


          2021-01-01  2021-01-02  2021-01-03  2021-01-04
lowtide     08:20:00    11:50:00    09:44:00    11:12:00
hightide    10:45:00    08:05:00    11:55:00    09:10:00

#because of errors while trying to plot I convert all into str
tides = tides.astype(str)

my_xaxis=pd.date_range(start='08:00',end='12:00',freq='5min').time

fig,ax = plt.subplots()
plt.xticks(range(len(my_xaxis)), my_xaxis, rotation='vertical')
plt.yticks(range(len(tides.index)),tides.index)
for column in tides.columns:
    plt.plot(tides[column],tides.index)

The result I get is this: enter image description here

What I like to get would be this:

enter image description here

I appreciate any help

Answer

You should re-shape your dataframe in this way (maybe there is a simpler way for re-shaping I am not aware of):

df = df.reset_index()
    .melt(id_vars = 'index', var_name = 'tide', value_name = 'time')
    .set_index('time').pivot(columns = 'index', values = 'tide')
    .replace({'lowtide': 0, 'hightide': 1})

df.index = df.index.map(lambda x: datetime(year = 2021, month = 1, day = 1, 
                                           hour = x.hour, minute = x.minute, second = x.second))

So you have:

index                2021-01-01  2021-01-02  2021-01-03  2021-01-04
time                                                               
2021-01-01 08:05:00         NaN         1.0         NaN         NaN
2021-01-01 08:20:00         0.0         NaN         NaN         NaN
2021-01-01 09:10:00         NaN         NaN         NaN         1.0
2021-01-01 09:44:00         NaN         NaN         0.0         NaN
2021-01-01 10:45:00         1.0         NaN         NaN         NaN
2021-01-01 11:12:00         NaN         NaN         NaN         0.0
2021-01-01 11:50:00         NaN         0.0         NaN         NaN
2021-01-01 11:55:00         NaN         NaN         1.0         NaN

Now you can plot with:

fig, ax = plt.subplots()

for col in df.columns:
    df[~df[col].isna()][col].plot(label = col.date())

ax.legend(frameon = True)

ax.set_yticks([0, 1])
ax.set_yticklabels(['lowtide', 'hightide'])

ax.xaxis.set_major_locator(md.MinuteLocator(interval = 10))
ax.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)

plt.tight_layout()

plt.show()

Complete Code

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as md
from datetime import datetime


low = ['08:20','11:50','09:44','11:12']
high = ['10:45','08:05','11:55','09:10']
low = pd.to_datetime(low).time
high = pd.to_datetime(high).time
col_name = ['lowtide','hightide']
ind_val = pd.date_range(start='01-01-2021',periods=4)

df = pd.DataFrame(data= zip(low,high),columns=col_name,index=ind_val)


df = df.reset_index()
    .melt(id_vars = 'index', var_name = 'tide', value_name = 'time')
    .set_index('time').pivot(columns = 'index', values = 'tide')
    .replace({'lowtide': 0, 'hightide': 1})

df.index = df.index.map(lambda x: datetime(year = 2021, month = 1, day = 1,
                                           hour = x.hour, minute = x.minute, second = x.second))


fig, ax = plt.subplots()

for col in df.columns:
    df[~df[col].isna()][col].plot(label = col.date())

ax.legend(frameon = True)

ax.set_yticks([0, 1])
ax.set_yticklabels(['lowtide', 'hightide'])

ax.xaxis.set_major_locator(md.MinuteLocator(interval = 10))
ax.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)

plt.tight_layout()

plt.show()

enter image description here