1

I am struggling to understand how the gridlines work with matplotlib specially when working with pandas dataframe. I need to plot DatetimeIndex vs multiple columns of the dataframe. Here is my code

import pandas
import matplotlib.pyplot as plt
plt.style.use("seaborn-whitegrid")
plt.rcParams.update({'figure.figsize': [15, 8],
                     'font.family': 'sans-serif',
                     'font.sans-serif': 'Verdana',
                     'font.size': 13,
                     'legend.frameon': True,
                     'legend.framealpha': 0.9,
                     'legend.facecolor': "white",
                     'legend.edgecolor': "black"})

d = pandas.DataFrame({"A": [x for x in range(12)], "B": [6 for x in range(12)]})
d.index = pandas.date_range("2021-01-01", "2021-01-01 11:00:00", freq="H")
ax = d.plot()
xtick_minor = pandas.date_range(start=d.index.min(), end=d.index.max(), freq='H')
ax.set_xticks(xtick_minor, minor=True)
ax.grid('on', which='both', axis='x', linestyle="--")

enter image description here

I also want a solid major grid line every 6 hours. How do I get that?

d.b
  • 32,245
  • 6
  • 36
  • 77
  • Does this answer your question? [How to add a grid line at a specific location in matplotlib plot?](https://stackoverflow.com/questions/14608483/how-to-add-a-grid-line-at-a-specific-location-in-matplotlib-plot) – sehan2 Oct 21 '21 at 18:31
  • @sehan2, I can get either the minor to work or the major but not both. Not sure what I am missing. – d.b Oct 21 '21 at 18:34
  • I see your problem. Have you looked at this? https://stackoverflow.com/questions/19940518/cannot-get-minor-grid-lines-to-appear-in-matplotlib-figure – sehan2 Oct 21 '21 at 18:41
  • @sehan2, could you provide an example of how to make that work when working with pandas dataframe (plotting index vs multiple columns)? – d.b Oct 21 '21 at 18:50

2 Answers2

2

Quang Hoang's answer addresses the question, although there is some odd behavior with the x-label at the 6-hourly points. If you need to correct that, you use the solution below which formats the x-ticks.

import pandas
import matplotlib.pyplot as plt

#Added functions
from matplotlib.ticker import MultipleLocator
import matplotlib.dates as mdates


plt.style.use("seaborn-whitegrid")
plt.rcParams.update({'figure.figsize': [15, 8],
                     'font.family': 'sans-serif',
                     'font.sans-serif': 'Verdana',
                     'font.size': 13,
                     'legend.frameon': True,
                     'legend.framealpha': 0.9,
                     'legend.facecolor': "white",
                     'legend.edgecolor': "black"})

d = pandas.DataFrame({"A": [x for x in range(12)], "B": [6 for x in range(12)]})

d.index = pandas.date_range("2021-01-01", "2021-01-01 11:00:00", freq="H")

ax = d.plot()

#Create the 6 houly time series
major_index = pandas.date_range("2021-01-01", "2021-01-01 11:00:00", freq="6H")
xticklabels = [x.strftime('%H:%M') for x in major_index]

#Set the ticks to be the 6 hourly data
ax.set_xticks(major_index)
ax.set_xticklabels(xticklabels)

#Make the minor ticks every hour
ax.xaxis.set_minor_locator(MultipleLocator(1))

#Add the grid lines based on style
ax.grid('on', which='minor', axis='x', linestyle="--")
ax.grid('on', which='major', axis='x', linestyle="-",linewidth=3)

plt.show()

enter image description here

BenT
  • 3,172
  • 3
  • 18
  • 38
1

It looks straight-forward from your code:

xtick_major = pd.date_range(start=d.index.min(), end=d.index.max(), freq='6H')
ax.set_xticks(xtick_major, minor=False)
ax.grid('on', which='major', axis='x', color='g')


xtick_minor = pd.date_range(start=d.index.min(), end=d.index.max(), freq='H')
ax.set_xticks(xtick_minor, minor=True)
ax.grid('on', which='minor', axis='x', linestyle="dashdot")

output:

enter image description here

Quang Hoang
  • 146,074
  • 10
  • 56
  • 74
  • The 6 hour point on the x-axis is missing for some reason. I have been having the same issue with my solution to this question. – BenT Oct 21 '21 at 19:16