4

Consider the figure below.

enter image description here

This image has been set up with the following code.

  plt.rc('text', usetex=True)
  plt.rc('font', family='serif')
  fig, ax = plt.subplots()

  ax.set_xlabel("Run Number", fontsize=25)

  plt.grid(True, linestyle='--')
  plt.tick_params(labelsize=20)
  ax.set_xticklabels(map(str,range(number_of_runs)))
  ax.minorticks_on()

  ax.set_ylim([0.75,1.75])

I have not included the code that actually generates the data for plotting for the sake of clarity.

Unlike the diagram above, I would like to draw grid-lines perpendicular to the X-axis through each orange (and hence blue) dot. How do I do this? The x-coordinates of the successive orange and blue dots form the same arithmetic progression in my code.

Also I notice that the tick numbers numbered 1,2,... are wrong for my application. Instead, I would like each successive grid-line, which I ask for as perpendicular to the X-axis in the previous step, to be numbered sequentially from 1 along the X-axis. How do I configure the Xtick marks for this?

smilingbuddha
  • 14,334
  • 33
  • 112
  • 189
  • as per your second question: you want that for every dot there is a corresponding "number of runs"? Don't you get this automatically by using "number of runs" as x-coordinate of the plot? Maybe showing a bit of the code generating the plot might help. – Robyc Jan 24 '19 at 09:03

2 Answers2

6

The grid lines cross the xticks (or yticks). You need to define xticks properly so that the grid lines cross your data points (the dots)

example below:

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
number_of_runs = range(1,10)    # use your actual number_of_runs
ax.set_xticks(number_of_runs, minor=False)
ax.xaxis.grid(True, which='major')

In case you want to have only vertical lines, add this:

ax.yaxis.grid(False, which='major')

Similar question here.

NerdOnTour
  • 634
  • 4
  • 15
Robyc
  • 379
  • 1
  • 13
4

You should specify the exact places where you want the grids using a call to ax.set_xticks and then specify the exact numbers you want on the axis using a call to ax.set_xticklabels.

I am plotting some two random arrays in the example below:

plt.rc('text', usetex=True)
plt.rc('font', family='serif')

y1 = np.random.random(10)
y2 = np.random.random(10)

fig, ax = plt.subplots(ncols=2, figsize=(8, 3))

# equivalent to your figure
ax[0].plot(y1, 'o-') 
ax[0].plot(y2, 'o-')
ax[0].grid(True, linestyle='--')
ax[0].set_title('Before')

# hopefully what you want
ax[1].plot(y1, 'o-')
ax[1].plot(y2, 'o-')
ax[1].set_title('After')
ax[1].set_xticks(range(0, len(y1)))
ax[1].set_xticklabels(range(1, len(y1)+1))
ax[1].grid(True, linestyle='--')

plt.show()

This is the output: enter image description here

A note: Looking at your plot, it seems that the actual x-axis is not integers, but you want integers starting from 1, Probably the best way to do this is to just pass in the y axis data array as an argument for the plot command (plt.plot(y) instead of plt.plot(x, y), like what I have done above. You should decide if this is appropriate for your case.

krm
  • 847
  • 8
  • 13