0

a given df where the index is the month two columns 'Ta' and 'G_Bn'.

df

Those columns shall be ploted against the month with seaborn to get a barplot with two y-axis. One for 'Ta' and one for 'G_Bn'. The bars have to be next to each other. My idea:

#Create combo chart
fig, ax1 = plt.subplots(figsize=(20,10))
ax1 = sns.barplot(data=dataMonthly, color ='#2b83ba')
ax1.tick_params(axis='y')
ax1.set_xlabel('Time')
ax1.set_ylabel('Value1')

ax2 = ax1.twinx()
ax2 = sns.barplot(x = dataMonthly.index, y = "Ta", data=dataMonthly, color ="#404040")
ax2.set_ylabel('Value2')
ax2.tick_params(axis='y')
plt.show()

The problem is that the bars do always lay on top of each other because I plot on ax1 and then ax2. How do I solve it? Any ideas?

qwertz
  • 619
  • 1
  • 7
  • 15
  • 1
    I find [How can I plot a secondary y-axis with seaborn's barplot?](https://stackoverflow.com/questions/65973917/how-can-i-plot-a-secondary-y-axis-with-seaborns-barplot) answer to be very helpful. – r-beginners Jan 31 '22 at 13:18

1 Answers1

0

The following approach creates a dummy categorical variable to serve as hue:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

dataMonthly = pd.DataFrame({'G_Bn': np.random.uniform(30, 40, 5).cumsum(),
                            'Ta': np.random.uniform(5, 10, 5).cumsum()})

fig, ax1 = plt.subplots(figsize=(20, 10))
ax2 = ax1.twinx()

palette = ['#2b83ba', "#404040"]
categories = ["G_Bn", "Ta"]
for ax, cat_val in zip([ax1, ax2], categories):
    sns.barplot(x=dataMonthly.index, y=dataMonthly[cat_val],
                hue=pd.Categorical([cat_val] * len(dataMonthly), categories), palette=palette, ax=ax)

ax1.set_xlabel('Time')
ax2.legend_.remove()  # a legend was created for ax1 as well as ax2
plt.tight_layout()
plt.show()

sns.barplot on twinx ax, using dummy hue

PS: Note that if you create the ax before calling a seaborn function, it is strongly recommended to use the ax=... parameter and to not catch the return-value of seaborn's function.

JohanC
  • 71,591
  • 8
  • 33
  • 66