Unable to display data in subplot

Question:

I’m currently trying to display two sets of data in a subplot with shared x-axes.
One set (stw) includes one value every 60 seconds, empties are nan. The other includes a value every second (Trim corrected).

The problem i encounter is, that the values of lower resolution don’t get displayed at all.
When i try to display two sets of values of equal resolution, it works just fine.

I used the following code:


    fig, ax = plt.subplots(figsize=(15,5))
    
    ax.plot(df1['Time corrected'],df1['stw'], color = 'green')
    ax.tick_params(axis='y', labelcolor='green')
    
    ax1=ax.twinx()
    
    ax1.plot(df1['Time corrected'], df1['Trim corrected'], color= 'purple')
    ax1.tick_params(axis='y', labelcolor='purple')

which yields this:Trim over time

Needles to say, i’m an absolute amateur and just got started with python and programming in general.

Thanks for your help.

Edit:

  • added libraries in use

I tested plotting only data which is redorded at the same intervals (sog and stw) see the result sog and stw and for rerference:

import pandas as pd
import matplotlib.pyplot as plt
    
fig, ax = plt.subplots(figsize=(15,5))
    
ax.plot(df1['Time corrected'],df1['stw'], color = 'green')
ax.tick_params(axis='y', labelcolor='green')
    
ax1=ax.twinx()
    
ax1.plot(df1['Time corrected'], df1['sog'], color= 'purple')
ax1.tick_params(axis='y', labelcolor='purple')

When using the same timestamp as in the two examples and plotting with the df.plot method, i have no trouble displaying either of the values in general. See Example plot

from

import pandas as pd
import matplotlib.pyplot as plt

df1.plot(figsize= (15,5),
          kind= 'line',
          color= 'green',     
          x= 'tsp',
          y= 'stw', 
          sharex= False,
          title= 'Speed over Time',
          ylabel= 'Speed Through Water [kn]',
          xlabel= 'Time [UTC]',
          grid = True)
plt.rcParams['figure.dpi'] = 200
plt.show()

Edit 2:
Thanks to Björn, i did the following ‘fix’ for now.

df1 = df1.rename({'Trim corrected':'Pitch Angle [°]'}, axis = 'columns')
df1 = df1.rename({'stw':'Speed through Water [kn]'}, axis = 'columns')
df1 = df1.rename({'Time corrected':'Time [UTC]'}, axis = 'columns')

import seaborn as sns

fig, ax = plt.subplots(figsize=(15,5))
ax1= sns.lineplot(x=df1['Time [UTC]'],y=df1.loc[:,'Pitch Angle [°]'], color='purple', label='Pitch Angle [°]', ax = ax)
ax1.set_ylim(-1.5,2.2)
ax2 = ax1.twinx()

sns.lineplot(x=df1['Time [UTC]'],y=df1['Speed through Water [kn]'], color='green', ax = ax2,linewidth=3, label= 'Speed Throough Water [kn]') 
plt.rcParams['figure.dpi'] = 200

ax.legend()

which yields this

and does the trick for me.

Asked By: johannesv

||

Answers:

had your question in the first questions review queue and just as a short feedback apriori, while I think you did a good job in providing details on your problem, it is extremely beneficial to provide a MRE including e.g. mockup data (e.g., see below)

import pandas as pd
import numpy as np
import seaborn as sns
# Create simulation data
N = 500 # Number of samples in seconds
index = pd.date_range("25-02-2022 13:30", freq="S", periods=N).tolist()
df1 = pd.DataFrame(index=index)
df1['stw'] = [float(np.random.uniform(5,25,1)) if x % 60==0 else np.nan for x in range(0,N) ]
df1['Trim corrected'] = np.random.uniform(-1.4,2.2,N)

I am not quite sure that I got yur question correct, but as far as I understood it you want to plot both lineplots in one "subplot" (with shared-x-axis)? I just out of routine defaulted on using seaborn package (docs) for plotting but it should the same approach with matplotlib

import seaborn as sns

fig, ax1 = plt.subplots(figsize=(15,5))

sns.lineplot(x=df1.index,y=df1.loc[:,"Trim corrected"], ax = ax1)    
ax2=ax1.twinx()
sns.lineplot(x=df1.index,y=df1.stw, ax = ax2,linewidth=3,color="orange")    
plt.rcParams['figure.dpi'] = 200

enter image description here

Answered By: Björn
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.