Mijn pythonscript gebruikt matplotlib om een 2D “heatmap” van een x, y, z-dataset te plotten. Mijn x- en y-waarden vertegenwoordigen aminozuurresten in een eiwit en kunnen daarom alleen gehele getallen zijn. Als ik inzoom op de plot, ziet het er als volgt uit:
Zoals ik al zei, hebben float-waarden op de x-y-assen geen zin met mijn gegevens en daarom wil ik dat het er als volgt uitziet:
Enig idee hoe dit te bereiken?
Dit is de code die de plot genereert:
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()
Antwoord 1, autoriteit 100%
Dit zou eenvoudiger moeten zijn:
(van 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))
Antwoord 2, autoriteit 3%
De volgende oplossing door simpelweg de index i
naar string te casten werkte voor mij:
import matplotlib.pyplot as plt
import time
datay = [1,6,8,4] # Just an example
datax = []
# In the following for loop datax in the end will have the same size of datay,
# can be changed by replacing the range with wathever you need
for i in range(len(datay)):
# In the following assignment statement every value in the datax
# list will be set as a string, this solves the floating point issue
datax += [str(1 + i)]
a = plt
# The plot function sets the datax content as the x ticks, the datay values
# are used as the actual values to plot
a.plot(datax, datay)
a.show()
Antwoord 3
Op basis van een antwoord voor het aanpassen van vinkjeskwam ik met een oplossing, weet niet of het gaat werken in uw geval omdat uw codefragment niet op zichzelf kan worden uitgevoerd.
Het idee is om de tick-labels te forceren tot een afstand van .5, en dan elke .5 tick te vervangen door zijn integere tegenhanger, en andere door een lege string.
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()
Als je veel wilt uitzoomen, heb je wat extra aandacht nodig, omdat deze dan een zeer dichte reeks vinklabels produceert.
Antwoord 4
ax.set_xticks([2,3])
ax.set_yticks([2,3])