0

I am working with Matplotlib. Below you can see my data and plot.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap


data = {'year': [2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023],
        'open': [70, 20, 24, 150, 80, 90, 60, 90, 20, 20, 20, 24, 150, 80, 90, 60, 90, 20, 30],
        'closed':[30, 14, 20, 10, 20, 40, 10, 10, 10, 10, 30, 14, 20, 10, 20, 40, 10, 10, 10]}

df = pd.DataFrame(data, columns = ['year',
                                   'open',
                                   'closed'])


fig, ax_1 = plt.subplots(figsize = (8, 5))
ax_2 = ax_1.twinx()
cmap = get_cmap('tab10')

ax_1.bar(df['year'], df['open'], label = 'open', color = cmap(0))
ax_2.plot(df['year'], df['closed'], label = 'closed', color = cmap(0.1),linewidth = '4.5')

handles_1, labels_1 = ax_1.get_legend_handles_labels()
handles_2, labels_2 = ax_2.get_legend_handles_labels()

ax_1.set_ylim(0, 160)
ax_2.set_ylim(0, 45)
ax_1.legend(handles = handles_1 + handles_2, labels = labels_1 + labels_2, loc = 'upper left', shadow = True)
ax_1.grid(axis = 'y')
ax_1.set_title('Sales comparison')

plt.show()

This code produce plot as plot below. enter image description here

Now I want to put titles on the places marked with yellow line with same names as data that showed open and closed. Also this chart have problem with decimal places on x-axis which need to be integer.

So can anybody help me how to solve this problem ?

Zephyr
  • 11,891
  • 53
  • 45
  • 80
silent_hunter
  • 2,224
  • 1
  • 12
  • 30
  • Does this answer your question? [Adding a y-axis label to secondary y-axis in matplotlib](https://stackoverflow.com/questions/14762181/adding-a-y-axis-label-to-secondary-y-axis-in-matplotlib) – Jody Klymak Jul 30 '22 at 16:10
  • Please don’t ask two unrelated questions per post! – Jody Klymak Jul 30 '22 at 16:12
  • @JodyKlymak I will ask everything that I want. If you can't provide answers please go to other questions. Thank you! – silent_hunter Jul 30 '22 at 16:17
  • Stackoverflow expects one question per post and posts with multiple questions are subject to being closed. I did provide an answer to your first question. Both your questions are duplicates. – Jody Klymak Jul 30 '22 at 17:03
  • @Jody Klymak Please go to other posts and give your opinions. This question is regularly answered. Your opinion is not needed. Thank you! – silent_hunter Jul 30 '22 at 17:20

1 Answers1

1

You can set y labels with matplotlib.axes.Axes.set_ylabel, one for each axes you used:

ax_1.set_ylabel('open')
ax_2.set_ylabel('closed')

And you can force x ticks to be integers with:

ax_1.xaxis.set_major_locator(MaxNLocator(integer = True))

Complete Code

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
from matplotlib.ticker import MaxNLocator


data = {'year': [2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023],
        'open': [70, 20, 24, 150, 80, 90, 60, 90, 20, 20, 20, 24, 150, 80, 90, 60, 90, 20, 30],
        'closed':[30, 14, 20, 10, 20, 40, 10, 10, 10, 10, 30, 14, 20, 10, 20, 40, 10, 10, 10]}

df = pd.DataFrame(data, columns = ['year',
                                   'open',
                                   'closed'])


fig, ax_1 = plt.subplots(figsize = (8, 5))
ax_2 = ax_1.twinx()
cmap = get_cmap('tab10')

ax_1.bar(df['year'], df['open'], label = 'open', color = cmap(0))
ax_2.plot(df['year'], df['closed'], label = 'closed', color = cmap(0.1),linewidth = '4.5')

handles_1, labels_1 = ax_1.get_legend_handles_labels()
handles_2, labels_2 = ax_2.get_legend_handles_labels()

ax_1.set_ylim(0, 160)
ax_2.set_ylim(0, 45)
ax_1.legend(handles = handles_1 + handles_2, labels = labels_1 + labels_2, loc = 'upper left', shadow = True)
ax_1.grid(axis = 'y')
ax_1.set_title('Sales comparison')

ax_1.set_ylabel('open')
ax_2.set_ylabel('closed')

ax_1.xaxis.set_major_locator(MaxNLocator(integer = True))

plt.show()

Plot

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80