2011-07-04 4 views
11

Próbuję utworzyć wykres, ale chcę, aby ticklabele wyświetlały się tak, jak pokazano, gdzie skala logarytmiczna jest pokazana powyżej. Chcę tylko pomniejszyć ticklabel dla 50, 500 i 2000, aby pokazać. Czy mimo to należy podać mniejsze etykiety zaznaczenia? Próbowałem to trochę zrozumieć, ale nie znalazłem dobrego rozwiązania. Wszystko, co mogę wymyślić, to uzyskać minorticklabels() i ustawić rozmiar czcionki na 0. Jest to pokazane poniżej pierwszego fragmentu kodu. Miałem nadzieję, że istnieje bardziej czyste rozwiązanie.Matplotlib, więc na osi logowania są tylko nieznaczne znaczniki znaczników w określonych punktach. Zmieniaj także rozmiar etykiet zaznaczania w kolorowym pasku

Drugą rzeczą jest zmiana rozmiaru ticklabeli na kolorowym pasku, którego nie znalazłem. Jeśli ktokolwiek wie, jak to zrobić, proszę dać mi znać, ponieważ nie widzę metody na pasku kolorów, która z łatwością to zrobi.

Pierwszy kod:

fig = figure(figto) 
ax = fig.add_subplot(111) 
actShape = activationTrace.shape 
semitones = arange(actShape[1]) 
freqArray = arange(actShape[0]) 
X,Y = meshgrid(self.testFreqArray,self.testFreqArray) 
Z = sum(activationTrace[:,:,beg:end],axis=2) 
surf = ax.contourf(X,Y,Z, 8, cmap=cm.jet) 
ax.set_position([0.12,0.15,.8,.8]) 
ax.set_ylabel('Log Frequency (Hz)') 
ax.set_xlabel('Log Frequency (Hz)') 
ax.set_xscale('log') 
ax.set_yscale('log') 
ax.xaxis.set_minor_formatter(FormatStrFormatter('%d')) 
ax.yaxis.set_ticks_position('left') 
ax.xaxis.set_ticks_position('bottom') 
ax.tick_params(axis='both',reset=False,which='both',length=8,width=2) 
self.plotSetAxisLabels(ax,22) 
self.plotSetAxisTickLabels(ax,18) 
cbar = fig.colorbar(surf, shrink=0.5, aspect=20, fraction=.12,pad=.02) 
cbar.set_label('Activation',size=18) 
return ax, cbar 

enter image description here

drugi kod:

fig = figure(figto) 
ax = fig.add_subplot(111) 
actShape = activationTrace.shape 
semitones = arange(actShape[1]) 
freqArray = arange(actShape[0]) 
X,Y = meshgrid(self.testFreqArray,self.testFreqArray) 
Z = sum(activationTrace[:,:,beg:end],axis=2) 
surf = ax.contourf(X,Y,Z, 8, cmap=cm.jet) 
ax.set_position([0.12,0.15,.8,.8]) 
ax.set_ylabel('Log Frequency (Hz)') 
ax.set_xlabel('Log Frequency (Hz)') 
ax.set_xscale('log') 
ax.set_yscale('log') 
ax.xaxis.set_minor_formatter(FormatStrFormatter('%d')) 
ax.yaxis.set_minor_formatter(FormatStrFormatter('%d')) 
ax.yaxis.set_ticks_position('left') 
ax.xaxis.set_ticks_position('bottom') 
ax.tick_params(axis='both',reset=False,which='both',length=8,width=2) 
self.plotSetAxisLabels(ax,22) 
self.plotSetAxisTickLabels(ax,18) 
cbar = fig.colorbar(surf, shrink=0.5, aspect=20, fraction=.12,pad=.02) 
cbar.set_label('Activation',size=18) 
count = 0 
for i in ax.xaxis.get_minorticklabels(): 
    if (count%4 == 0): 
     i.set_fontsize(12) 
    else: 
     i.set_fontsize(0) 
    count+=1 
for i in ax.yaxis.get_minorticklabels(): 
    if (count%4 == 0): 
     i.set_fontsize(12) 
    else: 
     i.set_fontsize(0) 
    count+=1 
return ax, cbar 

enter image description here

Dla colorbar: Kolejny szybki pytanie, jeśli nie przeszkadza, ponieważ próbuje wymyślić to b nie jestem całkowicie pewien. Chcę używać notacji naukowej, którą mogę uzyskać za pomocą ScalarFormatter. Jak ustawić liczbę miejsc dziesiętnych i mnożnik? Chciałbym, żeby było to jak 8x10^8 lub .8x10^9, aby zaoszczędzić miejsce, zamiast wstawiać wszystkie zera. Sądzę, że jest wiele sposobów na wykonanie tego wewnątrz obiektu osi, ale to, co uważasz za najlepszy sposób. Nie mogę wymyślić, jak zmienić zapis przy zmianie na ScalarFormatter.

Dla wykresu: Ponadto, moje dane mają punkty zaczynające się od 46, a następnie na kolejne mnożniki tego pomnożone przez 2^(1/12), więc 46,49,50,55,58,61 ... 3132 . Wszystkie są zaokrąglone, ale leżą blisko 2^(1/12). Postanowiłem, że lepiej umieścić większe serie w pobliżu tych liczb. Jest to najlepszy sposób użycia stałego formatera i używania znacznika co 15 w freqArray. Następnie użyj mniejszego paska na każdej innej częstotliwości. Czy mogę to zrobić i nadal utrzymuję oś log?

Odpowiedz

80

1) Użyj FixedLocator, aby statycznie zdefiniować wyraźne lokalizacje zaznaczeń.

2) Colorbar cbar będzie miał atrybut ax, który zapewni dostęp do zwykłych metod osi, w tym formatowania znaczników.

import numpy as np 
import matplotlib.pyplot as plt 

fig = plt.figure() 
ax = fig.add_subplot(111) 
x = np.arange(10,3000,100) 
y = np.arange(10,3000,100) 
X,Y = np.meshgrid(x,y) 
Z = np.random.random(X.shape)*8000000 
surf = ax.contourf(X,Y,Z, 8, cmap=plt.cm.jet) 
ax.set_ylabel('Log Frequency (Hz)') 
ax.set_xlabel('Log Frequency (Hz)') 
ax.set_xscale('log') 
ax.set_yscale('log') 
ax.xaxis.set_minor_formatter(plt.FormatStrFormatter('%d')) 
# defining custom minor tick locations: 
ax.xaxis.set_minor_locator(plt.FixedLocator([50,500,2000])) 
ax.yaxis.set_ticks_position('left') 
ax.xaxis.set_ticks_position('bottom') 
ax.tick_params(axis='both',reset=False,which='both',length=8,width=2) 
cbar = fig.colorbar(surf, shrink=0.5, aspect=20, fraction=.12,pad=.02) 
cbar.set_label('Activation',size=18) 
# access to cbar tick labels: 
cbar.ax.tick_params(labelsize=5) 
plt.show() 

enter image description here

Edit

Jeśli chcesz, margle kleszcza, ale chcesz selektywnie pokazują etykiety, nie widzę nic złego w swoim iteracji, z wyjątkiem może używać set_visible zamiast co powoduje, że rozmiar czcionki wynosi zero.

Możecie cieszyć się lepszą kontrolę przy użyciu FuncFormatter gdzie można użyć wartości lub stanowisko kleszcza, aby zdecydować, czy zostanie ono pokazane:

def show_only_some(x, pos): 
    s = str(int(x)) 
    if s[0] in ('2','5'): 
     return s 
    return '' 

ax.xaxis.set_minor_formatter(plt.FuncFormatter(show_only_some)) 
+0

To dobry kolega rzeczy. Nie myślałem, aby użyć tu set_visible, ale to jest lepsze niż ustawienie czcionki na rozmiar 0, ponieważ nadal jest to co najmniej jeden piksel. Chcę zaznaczyć tam znaki, aby FixedLocator nie działał w tym przypadku, ale podoba mi się wygląd FuncFormatter. Będę trzymać się tego, co mam na teraz, ale mogę dać to następnym razem. Dla FuncFormatter zawsze bierze dwa parametry w tej kolejności (value, tickposition). –

+0

Już odpowiedziałem na moje własne pytanie dotyczące FuncFormatter, więc nie martw się o to. Dzięki stosy. W rzeczywistości właśnie zaimplementowano FuncFormatter, ponieważ prawie łatwiejsze i podobne do ekstremalnej elastyczności, jeśli będę musiał zmienić ją w przyszłości, będzie to naprawdę łatwe. –

+0

Nie ma za co. Cieszę się, że mogę pomóc – Paul

0

Na podstawie odpowiedzi z @Paul I stworzył następującą funkcję:

def get_formatter_function(allowed_values, datatype='float'): 
    """returns a function, which only allows allowed_values as axis tick labels""" 
    def hide_others(value, pos): 
     if value in allowed_values: 
      if datatype == 'float': 
       return value 
      elif datatype == 'int': 
       return int(value) 
     return '' 
    return hide_others 

Co jest nieco bardziej elastyczne.

Powiązane problemy