16

I have the following plot, which provides the spectrogram of a pressure signal along with the signal placed on it for comparison. I was able to draw the y-axis grids on the spectrogram, but could not place the x-axis grid on it.

enter image description here

The data used to generate the spectrogram is available here.

Reproducible code

from __future__ import division
from matplotlib import ticker as mtick
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np

data = np.genfromtxt('pressure.dat', skiprows = 1, delimiter = '\t')
pressure = data[:, 1]
theta = data[:, 0]


with PdfPages('Spectorgram of cylinder pressure.pdf') as spectorgram_pressure:
    _spectorgram_pressure_vs_frequency_ = plt.figure(figsize=(5.15, 5.15))
    _spectorgram_pressure_vs_frequency_.clf()
    spectorgram_pressure_vs_frequency = plt.subplot(111)
    cax = plt.specgram(pressure * 100000, NFFT = 256, Fs = 90000, cmap=plt.cm.gist_heat, zorder = 1)
    spectorgram_pressure_vs_frequency.grid(False, which="major")
    spectorgram_pressure_vs_frequency.set_xlabel('Time (s)', labelpad=6)
    spectorgram_pressure_vs_frequency.set_ylabel('Frequency (Hz)', labelpad=6)
    y_min, y_max = spectorgram_pressure_vs_frequency.get_ylim()
    # plt.gca
    cbar = plt.colorbar(orientation='vertical', ax = spectorgram_pressure_vs_frequency, fraction = 0.046, pad = 0.2)
    cbar.set_label('Power spectral density (dB)', rotation=90)
    primary_ticks = len(spectorgram_pressure_vs_frequency.yaxis.get_major_ticks())
    pressure_vs_time = spectorgram_pressure_vs_frequency.twinx()
    pressure_vs_time.plot(((theta + 360) / (6 * 6600)), pressure, linewidth = 0.75, linestyle = '-', color = '#FFFFFF', zorder = 2)
    pressure_vs_time.grid(b = True, which='major', color='#FFFFFF', linestyle=':', linewidth = 0.3)
    spectorgram_pressure_vs_frequency.xaxis.grid(True, which='major', color='#FFFFFF', linestyle=':', linewidth = 0.3)
    pressure_vs_time.set_ylabel('Cylinder pressure (bar)', labelpad=6)
    pressure_vs_time.yaxis.set_major_locator(mtick.LinearLocator(primary_ticks))
    spectorgram_pressure_vs_frequency.set_xlim([0, max(cax[2])])
    spectorgram_pressure.savefig(bbox_inches='tight')
    plt.close()

How to place x-axis grids on top of the spectrogram like the y-axis grids in Python? I am using matplotlib version 1.3.1. Is this a version-specific problem?

Update

I updated matplotlib from version 1.3.1 to 1.4.3, even then I cannot set the x-axis grids on.

Tom Kurushingal
  • 6,086
  • 20
  • 54
  • 86
  • if I run your code, I get gridlines in both the x and y directions. Do you have something set in your `matplotlibrc` that might be affecting things? Maybe try setting them to default values with `matplotlib.rcdefaults()` – tmdavison Jul 24 '15 at 14:44
  • Even in my matplotlibrc gridlines are on. grid.color : FFFFFF grid.linestyle : - grid.linewidth : 0.5 grid.alpha : 1.0 – Tom Kurushingal Jul 24 '15 at 14:51
  • What version of matplotlib? Might be a version issue. – Ajean Jul 24 '15 at 15:01
  • This is very puzzling. It works fine for me in 1.4.3 - in 1.3.1 it causes an `ImportError`, but I guess that's irrelevant now you've updated matplotlib. My only guess is that you must have something elsewhere overriding. It seems you do have *some* different settings, because your font for the labelling is different to that produced on my pdf with default settings – J Richard Snape Jul 31 '15 at 10:44
  • 1
    I also get a black box around my colorbar unlike your image. These slight differences are making me wonder what engine is rendering your pdf. Can you give us a few more setup details - e.g. are you using `usetex` option - if so what OS are you on and what program is rendering the TeX? Do you see the vertical lines if you render to screen (e.g. `plt.show()`)? I can get similar problems to yours on screen with `plt.show()` if I take the line width down. Have you tried increasing the linewidth in your calls to `grid()` and `xaxis.grid()`? Try 1.5 ish. – J Richard Snape Jul 31 '15 at 11:04
  • I have set usetex to True, my OS is Ubuntu 14.04. No, I don't see any vertical lines if I render to screen or when I set linewidth to 1.5. – Tom Kurushingal Jul 31 '15 at 11:27
  • OK. Two new differences that might give mesomething to work on :) I can only easily test on Windows here and I see the lines on screen rendering and the pdf rendering will be different with `usetex`. I'll try to get onto an Ubuntu box and try it out... – J Richard Snape Jul 31 '15 at 11:49
  • Works fine for me too. Ubuntu 12.04, matplotlib 1.4.3. Also with `usetex` switched on. Your figure is still relatively complex. Could you try to make a minimal example? That will make it easier (also for yourself) to identify the problem. – hitzg Aug 02 '15 at 07:49
  • @hitzg Do you get the x-axis grid to appear? – Tom Kurushingal Aug 02 '15 at 07:56
  • Yes, the x-axis grid appears. I didn't change anything in your code. – hitzg Aug 02 '15 at 08:07
  • Have you tried changing the `zorder`? Pass some high number e.g. `zorder=1000` to make sure that its not rendered behind the image. – hitzg Aug 02 '15 at 08:07
  • No, it doesn't help. – Tom Kurushingal Aug 02 '15 at 08:20
  • 1
    OK - I fresh installed Ubuntu 14.04 64 bit to a Virtual box, new install of packages `python-matplotlib` and if "all just worked". I see the vertical x axis grid lines on screen and in the pdf. Just in case, I tried setting `text.usetex=True` and rendering (had to install `livetex-latex-base`, `livetex-fonts-recommended` and `livetex-fonts-extra` and `livetex-latex-extra`). This also worked both on screen and rendering to pdf. I cannot reproduce your error. Is there anything else unusual about your system? Is this snippet of code part of something larger that you're doing with mpl? – J Richard Snape Aug 03 '15 at 11:37
  • Wondering if any of my suggestions helped, or if you have any further info about your setup / context of this code? – J Richard Snape Aug 05 '15 at 20:00

3 Answers3

5

As others have noted - it is very difficult to replicate your issue with the code you have provided.

In particular - I have tried on Windows 8.1, Ubuntu 14.04 (on Virtualbox VM), matplotlib versions 1.3.1 and 1.4.3, with and without text.usetex set and with Python 2.7.6 and Python 3. None of them reproduce your problem with the code you provide.

However

I can reproduce what you see if I replace the line

spectorgram_pressure_vs_frequency.xaxis.grid(True, which='major', color='#FFFFFF', linestyle=':', linewidth = 0.3)

with

pressure_vs_time.xaxis.grid(True, which='major', color='#FFFFFF', linestyle=':', linewidth = 0.3)

i.e. I try to set the xaxis.grid on the twinned axis rather than the original axis. I have to conclude that somehow in your real code you are setting the xaxis.grid on your twinned axis rather than your main axis.


This means I can answer your direct questions as follows:

How to place x-axis grids on top of the spectrogram like the y-axis grids in Python?

Your code does this - you call xaxis.grid() on the original (not twinned) axis.

I am using matplotlib version 1.3.1. Is this a version-specific problem?

No, the behaviour is the same in 1.3.1 and 1.4.3

Community
  • 1
  • 1
J Richard Snape
  • 20,116
  • 5
  • 51
  • 79
0

Though in my case (python3.4, matplotlib 1.4.2, Ubuntu 14) I see the x-gridlines, I guess you can try following:

[pressure_vs_time.xaxis.get_gridlines()[x].zorder for x in range(len(pressure_vs_time.xaxis.get_gridlines())) ]

this will give you the layer of your gridlines (upper have higher values, can also be negative). In my case it returns 2 for all lines. Than you can set:

[pressure_vs_time.xaxis.get_gridlines()[x].zorder = 1000 for x in range(len(pressure_vs_time.xaxis.get_gridlines())) ]
Dima Lituiev
  • 12,544
  • 10
  • 41
  • 58
0

I have copied the code provided in your question and it works fine for me. I see both the x- and y-gridlines. Your code automatically saves a pdf version of the image. I converted this output to png. It looks like this

enter image description here

I am using Ubuntu 14.4 LTS, python 2.7.6, numpy 1.8.2 and matplotlib 1.3.1.

The Dude
  • 3,795
  • 5
  • 29
  • 47