2015-06-18 11 views
14

Mein Python-Skript verwendet matplotlib, um eine 2D-Heatmap eines x, y, z-Datasets zu zeichnen. Meine x- und y-Werte stellen Aminosäurereste in einem Protein dar und können daher nur ganze Zahlen sein. Als ich in die Handlung vergrößern, sieht es wie folgt aus:Matplotlib: Wie erzwinge Ganzzahl Tick Etiketten?

2D heat map with float tick marks

Wie gesagt, Float-Werte auf den xy-Achsen machen keinen Sinn, mit meinen Daten, und ich möchte es daher wie folgt aussehen: enter image description here

Irgendwelche Ideen wie man das erreicht? Dies ist der Code, der die Handlung erzeugt: für modifying tick labels

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() 

Antwort

28

Dies sollte einfacher sein:

(von 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)) 
+1

Es setzt das Tick-Label nicht auf den Mittelpunkt der gegebenen Region (wie im Beispielbild der Frage), und jedes zweite (unmarkierte) Tick fehlt. Gibt es einen einfachen Trick, um diese zu erreichen? Die '2' sollte in der Position von 2,5 sein, nicht bei 2,0. – Andris

+0

@Andris wow darüber habe ich keine Ahnung. Aber es scheint sowieso seltsam, die Plot-Bibliothek für diese Aufgabe zu optimieren, Sie sollten wahrscheinlich Ihre Daten ändern. Das Beispielbild, auf das Sie sich beziehen, scheint mit Farbe oder etwas Ähnlichem bearbeitet worden zu sein, was nicht bedeutet, dass eine solche Ausgabe mit Matplotlib möglich ist. –

+1

Das gibt sehr seltsame Ergebnisse für mich. Es verwandelt Ticks [0, 2, 4, 8, 10] in [0.0, 1.5, 3.0, 4.5, 7.5, 9.0, 10.5]. Angesichts dessen, was die [Docs] (http://matplotlib.org/api/ticker_api.html#matplotlib.ticker.MaxNLocator) sagen, sollte dies nicht passieren. – Annan

1

Basierend auf eine Antwort, die ich mit einer Lösung kam, weiß nicht, ob es in Ihrem Fall funktioniert wie Ihre Code-Snippet nicht ausgeführt werden kann in sich selbst.

Die Idee ist, die Tickbeschriftungen zu einem Abstand von 0,5 zu zwingen, dann ersetzen alle 0,5 Tick mit seinem Integer-Gegenstück und andere mit einer leeren Zeichenfolge.

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() 

Wenn Sie eine Menge zu verkleinern, die einige zusätzliche Pflege benötigen, da dies eine dann eine sehr dichte Menge von tick-Etiketten produziert.

+0

Vielen Dank für Ihre Antwort! Ich werde es versuchen. – gha

Verwandte Themen