Mon script python utilise matplotlib pour tracer une "carte thermique" 2D d'un jeu de données x, y, z. Mes valeurs x et y représentent des résidus d'acides aminés dans une protéine et ne peuvent donc être Lorsque je fais un zoom sur l'intrigue, cela ressemble à ceci:
Comme je l'ai dit, les valeurs flottantes sur les axes x-y n'ont pas de sens avec mes données et je veux donc qu'elles ressemblent à ceci:
Des idées pour y parvenir? C'est le code qui génère le tracé:
def plotDistanceMap(self):
# Read on x,y,z
x = self.currentGraph['xData']
y = self.currentGraph['yData']
X, Y = numpy.meshgrid(x, y)
Z = self.currentGraph['zData']
# Define colormap
cmap = colors.ListedColormap(['blue', 'green', 'orange', 'red'])
cmap.set_under('white')
cmap.set_over('white')
bounds = [1,15,50,80,100]
norm = colors.BoundaryNorm(bounds, cmap.N)
# Draw surface plot
img = self.axes.pcolor(X, Y, Z, cmap=cmap, norm=norm)
self.axes.set_xlim(x.min(), x.max())
self.axes.set_ylim(y.min(), y.max())
self.axes.set_xlabel(self.currentGraph['xTitle'])
self.axes.set_ylabel(self.currentGraph['yTitle'])
# Cosmetics
#matplotlib.rcParams.update({'font.size': 12})
xminorLocator = MultipleLocator(10)
yminorLocator = MultipleLocator(10)
self.axes.xaxis.set_minor_locator(xminorLocator)
self.axes.yaxis.set_minor_locator(yminorLocator)
self.axes.tick_params(direction='out', length=6, width=1)
self.axes.tick_params(which='minor', direction='out', length=3, width=1)
self.axes.xaxis.labelpad = 15
self.axes.yaxis.labelpad = 15
# Draw colorbar
colorbar = self.figure.colorbar(img, boundaries = [0,1,15,50,80,100],
spacing = 'proportional',
ticks = [15,50,80,100],
extend = 'both')
colorbar.ax.set_xlabel('Angstrom')
colorbar.ax.xaxis.set_label_position('top')
colorbar.ax.xaxis.labelpad = 20
self.figure.tight_layout()
self.canvas.draw()
Cela devrait être plus simple:
(à partir de https://scivision.co/matplotlib-force-integer-labeling-of-axis/ )
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
#...
ax = plt.figure().gca()
#...
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
Basé sur une réponse pour modification des étiquettes de tick J'ai trouvé une solution, je ne sais pas si cela fonctionnera dans votre cas car votre extrait de code ne peut pas être exécuté en lui-même.
L'idée est de forcer les étiquettes de tick à un espacement de 0,5, puis de remplacer chaque tick de 0,5 par son homologue entier et les autres par une chaîne vide.
import numpy
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1,2)
x1, x2 = 1, 5
y1, y2 = 3, 7
# first axis: ticks spaced at 0.5
ax1.plot([x1, x2], [y1, y2])
ax1.set_xticks(numpy.arange(x1-1, x2+1, 0.5))
ax1.set_yticks(numpy.arange(y1-1, y2+1, 0.5))
# second axis: tick labels will be replaced
ax2.plot([x1, x2], [y1, y2])
ax2.set_xticks(numpy.arange(x1-1, x2+1, 0.5))
ax2.set_yticks(numpy.arange(y1-1, y2+1, 0.5))
# We need to draw the canvas, otherwise the labels won't be positioned and
# won't have values yet.
fig.canvas.draw()
# new x ticks '1'->'', '1.5'->'1', '2'->'', '2.5'->'2' etc.
labels = [item.get_text() for item in ax2.get_xticklabels()]
new_labels = [ "%d" % int(float(l)) if '.5' in l else '' for l in labels]
ax2.set_xticklabels(new_labels)
# new y ticks
labels = [item.get_text() for item in ax2.get_yticklabels()]
new_labels = [ "%d" % int(float(l)) if '.5' in l else '' for l in labels]
ax2.set_yticklabels(new_labels)
fig.canvas.draw()
plt.show()
Si vous voulez beaucoup dézoomer, cela nécessitera des précautions supplémentaires, car celui-ci produit alors un ensemble très dense d'étiquettes de tiques.