2016-11-18 4 views
0

Ich habe ein Bild, bei dem jeder Spalte ein Attribut zugeordnet ist. Ich möchte das Bild plotten und jede Spalte mit ihrem Attributwert beschriften. Hier ist ein einfacher Code zu zeigen, was ich meine:Matplotlib Etiketten sind überlappend

import matplotlib.pyplot as plt 
import numpy as np 
from scipy.ndimage.filters import gaussian_filter 

np.random.seed(200) 

cols = 600 
attr = list('abcdefghijklmnopqrstuvwxyz') * cols 
attr = labels[:cols] 
img = gaussian_filter(np.random.rand(400, cols), 100) 
plt.imshow(img, cmap='inferno') 
plt.xticks(np.arange(cols), attr) 
plt.show() 

Das resultierende Bild unten zeigt, wie chaotisch die X-Etikett erhalten. Was ich möchte, ist, einige Etiketten zu zeigen, die aktualisiert werden, wenn Sie mit der Handlung interagieren, wie zoomen und schwenken.

Der Grund, warum ich denke, dass dies möglich ist, ist, weil das Standardverhalten von Maplotlib korrekt ist (wenn die Xticks nicht gesetzt werden). Es zeigt die Spaltennummer in Intervallen an, so dass Beschriftungen nicht überlappen, und werden beim Zoomen aktualisiert & Schwenken.

Meine Frage ist also: Ist es möglich, die Standard-Matplotlib-Label-Verhalten mit benutzerdefinierten Etiketten zu erhalten?

Overlapping Etiketten

enter image description here

Standardverhalten

enter image description here

Antwort

2

Was Sie wollen, ist tick formatting genannt. In diesem Fall können Sie eine Instanz von FuncFormatter erstellen und sie den Haupt-Ticks zuweisen.

Zuerst müssen Sie FuncFormatter auf Ihre Importe hinzuzufügen:

import matplotlib.pyplot as plt 
from matplotlib.ticker import FuncFormatter 
import numpy as np 
from scipy.ndimage.filters import gaussian_filter 

Sie brauchen eine Funktion, die den Tick-Wert und seine Position und gibt die Zecke Etikett nimmt. Sie werden die Position hier nicht benötigen, aber sie wird trotzdem an die Funktion übergeben. Stellen Sie sicher, dass die Funktion unerwartete Tick-Werte verarbeiten kann (Ich habe Matplotlib 2.0.0b4 verwendet und ein Häkchen bei 600 gesetzt).

cols = 600 
letters = list('abcdefghijklmnopqrstuvwxyz') 
attr = (letters * (1 + cols // len(letters)))[:cols] 

def format_tick(labels): 
    def get_label(x, pos): 
     try: 
      return labels[int(round(x))] 
     except IndexError: 
      return '' 
    return get_label 

erstellen FuncFormatter Instanz Ihre Format-Funktion:

formatter = FuncFormatter(format_tick(attr)) 

Set formatter als Hauptformatierer für Ihr Grundstück:

rs = np.random.RandomState(seed=200) 
img = gaussian_filter(rs.rand(400, cols), 100) 
plt.imshow(img, cmap='inferno') 
plt.gca().xaxis.set_major_formatter(formatter) 

custom tick labels

Natürlich ist diese Kennzeichnung tut mach keinen Sinn mit deinen s reichlich Daten. Ich bin mir sicher, dass es einen besseren Weg für Ihren tatsächlichen Anwendungsfall gibt, was auch immer es ist.

Verwandte Themen