0

I am having trouble plotting a lineplot and barplot (with the same inexes) on the same seaborn plot using data from the ‘results’ dataframe which I will show below (with ‘a’ data, ‘b’ data, and ‘percentiles’) in Python.

When I plot them separately, I am able to plot the lineplot fine (using ‘a’ data), however, the x-axis values of the barplot I am trying to plot (using 'b' data) does not show up. Strangely, I can plot a lineplot without any problem using the same data I am trying to plot the barplot with (‘b’ data)

When I try to plot them on the same plot, the x-axis starts from a date that is not even present in the ‘results’ dataframe.

I have even tried exporting the results dataframe as a csv and re-importing it to see if that works, but I run into the same problems.

What I would like to achieve:

  • Plotting the ‘a’ data as a lineplot, and the ‘b’ data as a bar plot on the same seaborn plot with different y-axes
  • I would like to have the same number of y-axis tickers and for the 0’s of both the y-axes to be aligned
  • Finally, I would like the colour of the barplot to be dependent on whether the percentile column indicated ‘low’, ‘mid’, ‘high’ (a different colour for each of these)
# Here is the 'a' and 'b' data that I start with

a = pd.read_csv(r'a.csv',sep=",", parse_dates=['date'], dayfirst=True, index_col=0)

b = pd.read_csv(r'b.csv',sep=",", parse_dates=['date'], dayfirst=True, index_col=0)

'a' DataFrame

'b' DataFrame

# After manipulating the data, here is the 'results' DataFrame I end up with

'results' DataFrame

# Plotting them separately

# Plotting lineplot using 'a' column from 'results' DataFrame

sns.lineplot(data=result.iloc[:, 0], color="g")

lineplot

# Plotting barplot using 'b' column from 'results' DataFrame

b_plot = sns.barplot(data=result, x=result.index, y=result.iloc[:, 2], color="b")

b_plot.xaxis.set_major_locator(md.YearLocator(base=4)) 
b_plot.xaxis.set_major_formatter(md.DateFormatter('%Y'))
b_plot.margins(x=0)

barplot

# Attempting to plot the lineplot and barplot on the same plot

matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None)
fig, ax1 = plt.subplots(figsize=(12,6))

a_plot = sns.lineplot(data=result.iloc[:, 0], color="g", ax=ax1)
ax2 = ax1.twinx()
b_plot = sns.barplot(data=result, x=result.index, y=result.iloc[:, 2], color="b", ax=ax2)

b_plot.xaxis.set_major_locator(md.YearLocator(base=4)) 
b_plot.xaxis.set_major_formatter(md.DateFormatter('%Y'))
b_plot.margins(x=0)

lineplot and barplot on same plot

EDIT: I have answered the questions below

galaxy_d
  • 23
  • 1
  • 9
  • Try calling ```f, ax = plt.subplots()``` before calling the seaborn plot commands for each plot – Stefan Feb 17 '22 at 19:12
  • Does this answer your question? [Seaborn lineplot and barplot don't align in the X axis](https://stackoverflow.com/questions/64402358/seaborn-lineplot-and-barplot-dont-align-in-the-x-axis) – Mr. T Feb 18 '22 at 09:28
  • Welcome to SO. Please read [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) and [How to create a minimal, complete, and reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). You should avoid asking several distinct questions. – Mr. T Feb 18 '22 at 09:31
  • @Mr. T I have tried the solutions on the page you have linked. However, my x-axis datetime indexes still do not show up when I plot both on the same plot. There is no issue when I do the lineplot separately. But the datetime indexes on the x-axis do not show up even when I do the seaborn barplot separately – galaxy_d Feb 18 '22 at 15:27

2 Answers2

0

Here's an example of what I suggested in the comments.

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

data = pd.DataFrame({'Day': [1, 2, 3, 4], 'Value': [3, 7, 4, 2], 'Value 2': [1, 7, 4, 5]})

f, ax = plt.subplots()
sns.barplot(data=data, x='Day', y='Value')

Edit: use pointplot here to align the entries.

sns.pointplot(data=data, x='Day', y='Value 2')

enter image description here

Stefan
  • 86
  • 2
  • Learned something new myself here. If you're wondering why the bar and line plots don't line up check out [this](https://stackoverflow.com/questions/64402358/seaborn-lineplot-and-barplot-dont-align-in-the-x-axis) stack entry – Stefan Feb 17 '22 at 19:25
  • thanks for the pointplot suggestion - I can now plot them on the same plot. However, my x axis still shows no values... I can't even plot the barplot by itself with the x axis values showing (as described in my original question) – galaxy_d Feb 18 '22 at 13:44
0

Here are the answers to my questions:

matplotlib.rc_file_defaults()
ax1 = sns.set_style(style=None, rc=None)
fig, ax1 = plt.subplots(figsize=(12,6))
ax2 = ax1.twinx()

# plot the bar plot and make the colours dependent on the values in a seperate column
result_date = result.reset_index()
    
palette = {"low":"lightgreen",
           "mid":"darkseagreen", 
           "high":"green"}

b_plot = sns.barplot(data = result_date, x=result_date.iloc[:, 0], 

y=result_date.iloc[:, 3], ax=ax1, hue='percentile', palette=palette, dodge = False)

# plot the lineplot
a_plot = sns.pointplot(data=result, x=result.index, y=result.iloc[:, 0], color="black", ax=ax2, markers = 'o', scale=0.4)

# set the x tickers to be those of the bar plot
ax1.set_xticks(np.arange(len(result_date)))
ax1.set_xticklabels(result_date.date.apply(lambda x: str(x.year)))
ax1.xaxis.set_major_locator(ticker.AutoLocator())
    
# align axis at 0, and get same number of ticks on both y-axes
max1 = np.nanmax(np.abs(ax1.get_ybound())) 
max2 = np.nanmax(np.abs(ax2.get_ybound()))
nticks = 7 
    
ax1.set_yticks(np.linspace(-max1, max1, nticks))
ax2.set_yticks(np.linspace(-max2, max2, nticks))

galaxy_d
  • 23
  • 1
  • 9