Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create grids in xkcd plots

I want to create some xkcd plots with a grid in the background. Like this example, but when the plt.xkcd() the grids don't appear in the plot.

from matplotlib import pyplot as plt
import numpy as np

plt.xkcd()
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.xticks([])
plt.yticks([])
ax.set_ylim([-30, 10])
plt.grid()

data = np.ones(100)
data[70:] -= np.arange(30)

plt.annotate(
    'THE DAY I REALIZED\nI COULD COOK BACON\nWHENEVER I WANTED',
    xy=(70, 1), arrowprops=dict(arrowstyle='->'), xytext=(15, -10))

plt.plot(data)

plt.xlabel('time')
plt.ylabel('my overall health')

plt.show()

In the case of plots done with mplot3d the grid is "working", as can be seen in this example. Although, the grid seems to be perfect. How can I create the grids?

like image 978
nicoguaro Avatar asked Sep 06 '25 03:09

nicoguaro


2 Answers

I'm expanding my comment into an answer. As DrV mentioned, the linewidth is set to zero, so we need to explicitly specified in the call to grid(). Other thing to take into account is that the grid will appear over the plot, so the zorder need to be specified. As mentioned in this post, the grid should be set with zorder=0 and the plot should have a value greater to 3 zorder=3.

So, an example without grid is

import numpy as np
import matplotlib.pyplot as plt

plt. xkcd()
x = np.linspace(0, 1)
y = np.sin(4 * np.pi * x) * np.exp(-5 * x)

plt.fill(x, y, 'r')
plt.grid(True)
plt.show()

Giving: xkcd-style plot withtout grid

An example with grid:

import numpy as np
import matplotlib.pyplot as plt

plt. xkcd()
x = np.linspace(0, 1)
y = np.sin(4 * np.pi * x) * np.exp(-5 * x)

plt.fill(x, y, 'r', zorder=3)
plt.grid(True, lw=0.5, zorder=0)
plt.show()

Giving: enter image description here

like image 147
nicoguaro Avatar answered Sep 07 '25 20:09

nicoguaro


The first reason is that you have no gridlines:

In [43]: ax.xaxis.get_gridlines()
Out[43]: <a list of 0 Line2D gridline objects>

This is because you have no xticks:

In [47]: ax.get_xticks()
Out[47]: array([], dtype=float64)

This can be fixed by adding some ticks:

ax.set_xticks([20,50,80])
ax.set_yticks([-20,-10,0])

Now we should have some gridlines:

In [54]: ax.xaxis.get_gridlines()
Out[54]: <a list of 3 Line2D gridline objects>

Unfortunately, nothing can be seen. That, in turn, is because the grid width is zero:

In [56]: ax.xaxis.get_gridlines()[0].get_linewidth()
Out[56]: 0.0

We can fix that by (see below for a more general method):

ax.xaxis.grid(linewidth=1.0)
ax.yaxis.grid(linewidth=1.0)

And now you have:

enter image description here

Of course, in practice you will set the x and y ticks as you wish (and maybe switch off the tick marks themselves). After that you can simply set the grid on by:

ax.grid(True, linewidth=1)

Please not that the ticks were removed on purpose in the beginning of the example code.

like image 45
DrV Avatar answered Sep 07 '25 21:09

DrV