Matplotlib won't show minor ticks when using subplots - python

I have several subplots and want to adjust the axis ticks settings by ax.tick_params. Everything works fine, however, the minor ticks are not shown. Here is a code example
import matplotlib.pyplot as plt
x = np.linspace(0,1,100)
y = x*x
f, (ax1,ax2) = plt.subplots(2, 1)
ax1.tick_params(axis="both", direction="in", which="both", right=False, top=True)
ax2.tick_params(axis="both", direction="in", which="both", right=True, top=False)
ax1.plot(x,y)
ax2.plot(x,-y)
plt.show()
I assumed that which=both would give me the minor ticks. However I need to add an additional
plt.minorticks_on()
which makes them visible but only in ax2.
How do I fix this?

With pyplot the danger is that you loose track of which one the current axes is that a command like plt.minorticks_on() operates on. Hence it would be beneficial to use the respective methods of the axes you're working with:
ax1.minorticks_on()
ax2.minorticks_on()

plt would work on the current axis which is ax2 in your case. One way is to first enable them using the way you did and then specify the number of minor ticks using AutoMinorLocator
from matplotlib.ticker import AutoMinorLocator
ax1.tick_params(axis="both", direction="in", which="both", right=False, top=True)
ax2.tick_params(axis="both", direction="in", which="both", right=True, top=False)
ax1.plot(x,y)
ax2.plot(x,-y)
for ax in [ax1, ax2]:
ax.xaxis.set_minor_locator(AutoMinorLocator(4))
ax.yaxis.set_minor_locator(AutoMinorLocator(4))

Related

Pyplot: change size of tick lines on axis

Consider this reproducable example:
import numpy as np
import matplotlib.pyplot as plt
labels = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21']
fig, axes = plt.subplots(nrows=3, ncols=3,figsize=(6, 3.5),dpi=300)
plt.subplots_adjust(wspace=0.025, hspace=0.2)
for ax in [a for b in axes for a in b]:
ax.imshow(np.random.randint(2, size=(22,42)))
ax.set_xticks([0,6,12,18,24,30,36,41])
ax.tick_params(axis='x', which='major', labelsize=3)
ax.set_yticks([])
ax.set_aspect('equal')
for ax in [item for sublist in axes for item in sublist][0::3]:
ax.set_yticks(range(len(labels)))
ax.set_yticklabels(labels,fontsize=3)
fig.savefig("example.png",bbox_inches='tight')
My issue is that even though I changed the tick font size, the lines of each tick remain the same. This looks ugly and wastes a lot of space, especially on the X axes. Any ideas how to get those lines smaller, thus that the xlabels are closer to the axis?
PS tight_layout() does not help.
Make
ax.tick_params(axis='x', which='major', labelsize=3, length=2)
and, right after,
ax.tick_params(axis='y', which='major', labelsize=3, length=2)
This will make the ticks smaller, but won't get the labels any closer to the chart.
PS: length=1 will make the ticks even smaller, obviously.
You could play with the width parameter:
ax.tick_params(axis='x', which='major', labelsize=3, width=0.1)
Instead of (line 4):
fig, axes = plt.subplots(nrows=3, ncols=3,figsize=(6, 3.5),dpi=300)
You can manipulate figsize. Example:
fig, axes = plt.subplots(nrows=3, ncols=3,figsize=(3, 2),dpi=300).
Lets's compare both outputs:
The numbers on axes are bigger than old one.

Put shared axis labels to upper plot

from matplotlib import pyplot as plt
fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True)
fig.show()
Returns this figure:
But I want the x-axis labels below the first plot, not the second, like shown below. How can I achieve this?
There is an example in the official reference, so I answered it by referring to it: In the tick parameter, set the bottom label to false.
import matplotlib.pyplot as plt
ax0 = plt.subplot(211)
ax1 = plt.subplot(212, sharex=ax0, sharey=ax0)
#plt.plot([],[])
plt.tick_params('x', labelbottom=False)
#print(ax1.get_xticks())
plt.show()
The answer from #r-beginners brought me to a solution that also works when using the plt.subplots shortcut instead of instantiating each axis separately.
from matplotlib import pyplot as plt
fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True)
plt.tick_params('x', labelbottom=False, labeltop=True)
fig.show()
he essential part is plt.tick_params which take keyword arguments labeltop or labelbottom (as well as labelleft or labelright for shared axis on several columns) to select / deselect each axis individually.

set_markersize not working for right side axis

I'm messing around with some plot styles and ran into a curiosity. I have a plot with twinx() to produce ticks on the right-hand side as well as the left. I want to stagger some ticks, some going farther out that others.
I can add padding to any tick on any axes and push out the text via ax.yaxis.get_major_ticks()[1].set_pad(), but when I try to lengthen the tick via ax.yaxis.get_major_ticks()[1].tick1line.set_markersize(), it works for all axes EXCEPT the right side. Any insight?
Please see the code below. I've tried switching up the axis (ax1, ax2) and index.
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
t = np.linspace(0,5)
x = np.exp(-t)*np.sin(2*t)
fig, ax1 = plt.subplots()
ax1.plot(t, x, alpha=0.0)
ax2 = ax1.twinx()
ax2.plot(t, x, alpha=1.0)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0.1, 0.2])
ax2.set_yticks([0.3, 0.4, 0.5])
ax2.set_xticks([1,2,3])
ax1.grid(True, color='lightgray')
ax2.grid(True, color='lightgray')
for a in [ax1, ax2]:
a.spines["top"].set_visible(False)
a.spines["right"].set_visible(False)
a.spines["left"].set_visible(False)
a.spines["bottom"].set_visible(False)
ax1.set_axisbelow(True)
ax2.set_axisbelow(True)
ax1.xaxis.get_major_ticks()[1].set_pad(15) #
ax1.xaxis.get_major_ticks()[1].tick1line.set_markersize(15)
ax1.yaxis.get_major_ticks()[1].set_pad(15) #
ax1.yaxis.get_major_ticks()[1].tick1line.set_markersize(15)
ax2.yaxis.get_major_ticks()[1].set_pad(15) #
ax2.yaxis.get_major_ticks()[1].tick1line.set_markersize(15)
plt.savefig('fig.pdf')
plt.show()
You need to use tick2line instead of tick1line, since that's the one referring to the top/right axis, according to the documentation.
Change ax2.yaxis.get_major_ticks()[1].tick1line.set_markersize(15) for:
ax2.yaxis.get_major_ticks()[1].tick2line.set_markersize(15)
Result:

ticks and labels of right y-axis of ax.twinx().twiny() not removable

I need to combine a plot of a lot of data, that takes several seconds and combine it with a plot of very little data that is plotted in the same frame of reference as the former plot. The latter is plotted interactively. In the following MWE the interactive part is simulated by a loop.
My problem is that when I clone the original axes with twinx().twiny() I cannot get rid of the ticks for both of the axes of the twined axes object.
import numpy as np
import matplotlib.pyplot as plt
from random import choice
from time import sleep
%matplotlib notebook
data = np.random.rand(100,2)*10
fig, ax1 = plt.subplots(1, 1)
ax1.scatter(data[:,0], data[:,1])
ax2 = ax1.twinx().twiny()
ax2.set_xlim(ax1.get_xlim())
ax2.set_ylim(ax1.get_ylim())
ax2.tick_params(top=False, labeltop=False, left=False, labelleft=False, right=False, labelright=False, bottom=False, labelbottom=False)
for i in range(10):
try:
sc.remove()
except:
pass
p = choice(data)
sc = ax2.scatter(p[0], p[1], s=10, color='red')
fig.canvas.draw()
sleep(.5)
plt.show()
So ax2.tick_params(top=False, labeltop=False, left=False, labelleft=False, right=False, labelright=False, bottom=False, labelbottom=False) should get rid of any ticks and labels, right? But is doesn't. The plot looks like this:
The right y-axis should not be there, should it? Is this a bug or am I missing something?
Your solution worked on my code (below) and I just called the params before the actual plot.
ax2 = axes[ax].twiny()
ax2.tick_params(top=False, labeltop=False, left=False, labelleft=False, right=False, labelright=False, bottom=False, labelbottom=False)
ax2.plot(x, vals[ax], color = 'black')
You can probably make it work if you figure out the placement of the line.

ax.grid overwrites ticks labels when spine is in centre

When using ax.grid() and moving the spines to the middle of the plot, the grid lines go over the axes labels. Any way to stop this and move the axes labels to "front"?
EDIT: It is the ticks labels (the numbers) I'm interested in fixing, not the axis label, which can be easily moved.
EDIT: made the MWE and image match exactly
EDIT: matplotlib version 2.0.0
#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = plt.gca()
ax.minorticks_on()
ax.grid(b=True, which='major', color='k', linestyle='-',alpha=1,linewidth=1)
ax.grid(b=True, which='minor', color='k', linestyle='-',alpha=1,linewidth=1)
x = np.linspace(-5,5,100)
y = np.linspace(-5,5,100)
plt.plot(x,y)
plt.yticks([-5,-4,-3,-2,-1,0,1,2,3,4,5])
ax.spines['left'].set_position(('data', 0))
plt.show()

Categories

Resources