Remove only overlapping ticks in subplots grid

2024/10/11 18:18:23

I have created a subplots grid without any spaces between the subplots, with shared x,y-axes. I only show the ticks and labels for the outer subplots. The problem is that the tick numbers overlap at the borders of the subplots. With MaxNLocator, I can remove the upper or lower ticks, but only for all plots at once.

Question: How can I keep the highest tick only for certain plots (in this case x=2.0 only in the bottom right subplot, and y=3 only in the top left subplot)? Why does my conditional setting of ticks for certain subplots fail?

enter image description here

Code:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocatornumPlotsY = 3
numPlotsX = 3
f, ax_grid = plt.subplots(numPlotsY,numPlotsX,sharex=True,sharey=True)A = np.arange(numPlotsY)+1.0
phi = np.arange(numPlotsX)
x = np.linspace(0,2.0,100)
fontsize = 18for y_i in range(0,numPlotsY):for x_i in range(0,numPlotsX):y = A[y_i]*np.sin(x*np.pi + phi[x_i])ax = ax_grid[y_i,x_i]ax.plot(x,y,lw=2.0)if x_i == 0:ax.set_ylabel(r'$y$', fontsize=fontsize)if y_i == numPlotsY-1:############################ Why doesn't this work?! ############################if x_i != numPlotsX-1:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))else:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune=None))ax.set_xlabel(r'$x/\pi$', fontsize=fontsize)if y_i == 0:ax.set_title(r'$\phi=%s$' % phi[x_i], fontsize=fontsize)if x_i == numPlotsX-1:ax.annotate(r'$A=%d$' % A[x_i], xy=(1.1,0.5), rotation=90,ha='center',va='center',xycoords='axes fraction', fontsize=fontsize)f.subplots_adjust(wspace=0,hspace=0)
plt.suptitle(r'$A\cdot\sin\left(2\pi x + \phi\right)$',fontsize=18)
plt.show()
Answer

As @AndrasDeak pointed out, I cannot modify individual subplot ticks as long as I have set sharex=True,sharey=True. The solution is to set them to false

f, ax_grid = plt.subplots(numPlotsY,numPlotsX,sharex=False,sharey=False)

and changing the conditional statements from my original post to:

# If left-most column:  Remove all overlapping y-ticks
# Else:                 Remove all ticks
if x_i == 0:ax.set_ylabel(r'$y$', fontsize=fontsize)# If top left subplot:      Remove bottom y-tick# If bottom left subplot:   Remove top y-tick# Else:                     Remove top and bottom y-ticksif y_i == 0:nbins = len(ax.get_yticklabels())ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))elif y_i == numPlotsY-1:nbins = len(ax.get_yticklabels())ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))else:nbins = len(ax.get_yticklabels())ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))
else:ax.yaxis.set_ticks([])# If bottom row:    Remove all overlapping x-ticks
# Else:             Remove all ticks
if y_i == numPlotsY-1:# If bottom left subplot:   Remove right x-tick# If bottom right subplot:  Remove top left x-tick# Else:                     Remove left and right x-ticksif x_i == 0:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))elif x_i == numPlotsX-1:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))else:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))
else:ax.xaxis.set_ticks([])

Not the most elegant result, but it demonstrates how to manipulate only the overlapping ticks: enter image description here

Full code for anyone interested:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocatornumPlotsY = 3
numPlotsX = 3
f, ax_grid = plt.subplots(numPlotsY,numPlotsX,sharex=False,sharey=False)A = np.arange(numPlotsY)+1.0
phi = np.arange(numPlotsX)
x = np.linspace(0,2.0,100)
fontsize = 18for y_i in range(0,numPlotsY):for x_i in range(0,numPlotsX):y = A[y_i]*np.sin(x*np.pi + phi[x_i])ax = ax_grid[y_i,x_i]ax.plot(x,y,lw=2.0)# If left-most column:  Remove all overlapping y-ticks# Else:                 Remove all ticksif x_i == 0:ax.set_ylabel(r'$y$', fontsize=fontsize)# If top left subplot:      Remove bottom y-tick# If bottom left subplot:   Remove top y-tick# Else:                     Remove top and bottom y-ticksif y_i == 0:nbins = len(ax.get_yticklabels())ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))elif y_i == numPlotsY-1:nbins = len(ax.get_yticklabels())ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))else:nbins = len(ax.get_yticklabels())ax.yaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))else:ax.yaxis.set_ticks([])# If bottom row:    Remove all overlapping x-ticks# Else:             Remove all ticksif y_i == numPlotsY-1:# If bottom left subplot:   Remove right x-tick# If bottom right subplot:  Remove top left x-tick# Else:                     Remove left and right x-ticksif x_i == 0:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='upper'))elif x_i == numPlotsX-1:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='lower'))else:nbins = len(ax.get_xticklabels())ax.xaxis.set_major_locator(MaxNLocator(nbins=nbins,prune='both'))else:ax.xaxis.set_ticks([])if y_i == 0:ax.set_title(r'$\phi=%s$' % phi[x_i], fontsize=fontsize)if x_i == numPlotsX-1:ax.annotate(r'$A=%d$' % A[x_i], xy=(1.1,0.5), rotation=90,ha='center',va='center',xycoords='axes fraction', fontsize=fontsize)f.subplots_adjust(wspace=0,hspace=0)
plt.suptitle(r'$A\cdot\sin\left(2\pi x + \phi\right)$',fontsize=18)
plt.show()
https://en.xdnf.cn/q/118295.html

Related Q&A

how to start a thread when django runserver?

I want to start a thread when django project runserver successfully. where can I put the create-thread-and-start code? Is there any hook for the django runserver?

pandas groupby plot values

I have a pandas dataframe that looks like this:**real I SI weights**0 1 3 0.3 0 2 4 0.20 1 3 0.50 1 5 0.51 2 5 0.3…

Any python module for customized BNF parser?

friends.I have a make-like style file needed to be parsed. The grammar is something like:samtools=/path/to/samtools picard=/path/to/picardtask1: des: descriptionpath: /path/to/task1para: [$global.samto…

How to draw an histogram with multiple categories in python

I am a freshman in python, and I have a problem of how to draw a histogram in python.First of all, I have ten intervals that are divided evenly according to the length of flowers petal, from min to max…

Turtle in Tkinter creating multiple windows

I am attempting to create a quick turtle display using Tkinter, but some odd things are happening.First two turtle windows are being created, (one blank, one with the turtles), secondly, any attempt of…

Array tkinter Entry to Label

Hey Guys I am beginner and working on Project Linear and Binary search GUI application using Tkinter, I want to add multiple Entry boxes values to label and in an array here, I tried but its not workin…

Grid search and cross validation SVM

i am implementing svm using best parameter of grid search on 10fold cross validation and i need to understand prediction results why are different i got two accuracy results testing on training set not…

Accessing dynamically created tkinter widgets

I am trying to make a GUI where the quantity of tkinter entries is decided by the user.My Code:from tkinter import*root = Tk()def createEntries(quantity):for num in range(quantity):usrInput = Entry(roo…

Graphene-Django Filenaming Conventions

Im rebuilding a former Django REST API project as a GraphQL one. I now have queries & mutations working properly.Most of my learning came from looking at existing Graphene-Django & Graphene-Py…

Summing up CSV power plant data by technology and plant name

Ive got a question regarding the Form 860 data about US power plants.It is organized block-wise and not plant-wise. To become useful, the capacity numbers must be summed up.How may I get the total capa…