2013-10-30 4 views
10

Ich habe eine harte Zeit Plotten Gitterlinien unter meinen Graphen, ohne mit der Haupt x- und y-Achse ZOrder Messing:Matplotlib: Gitterlinien hinter dem Diagramm halten, aber die y- und x-Achse über

import matplotlib.pyplot as plt 
import numpy as np 


N = 5 
menMeans = (20, 35, 30, 35, 27) 
menStd = (2, 3, 4, 1, 2) 

ind = np.arange(N) # the x locations for the groups 
width = 0.35  # the width of the bars 

fig, ax = plt.subplots() 
rects1 = ax.bar(ind, menMeans, width, color='r', yerr=menStd, alpha=0.9, linewidth = 0,zorder=3) 

womenMeans = (25, 32, 34, 20, 25) 
womenStd = (3, 5, 2, 3, 3) 
rects2 = ax.bar(ind+width, womenMeans, width, color='y', yerr=womenStd, alpha=0.9, linewidth = 0,zorder=3) 

# add some 
ax.set_ylabel('Scores') 
ax.set_title('Scores by group and gender') 
ax.set_xticks(ind+width) 
ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5')) 

ax.legend((rects1[0], rects2[0]), ('Men', 'Women')) 

fig.gca().yaxis.grid(True, which='major', linestyle='-', color='#D9D9D9',zorder=2, alpha = .9) 
[line.set_zorder(4) for line in ax.lines] 

def autolabel(rects): 
    # attach some text labels 
    for rect in rects: 
     height = rect.get_height() 
     ax.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%d'%int(height), 
       ha='center', va='bottom') 

autolabel(rects1) 
autolabel(rects2) 

plt.show() 

Das Beispiel ist von matplotlib selbst genommen, und ich habe ein wenig gezwängt, um zu zeigen, wie man das Problem erscheinen lässt. Ich kann Bilder nicht posten, aber wenn Sie den Code ausführen, werden Sie sehen, dass die Balken über den horizontalen Gitterlinien sowie über der x- und y-Achse geplottet werden. Ich möchte nicht, dass die X- und Y-Achse durch die Grafik verdeckt wird, besonders wenn die Zecken auch blockiert werden.

+0

warum verwenden Sie 'fig.gca()' statt "Axt"? –

+0

Aus Neugier: Weißt du, was die Linien in 'ax.lines' erzeugt? –

+0

Sie richtig ist, war ich nur versucht, verloren, um herauszufinden, wie es zu tun, anstatt zu verstehen versuchen, wie alles funktioniert ... –

Antwort

2

ich versucht habe matplotlib 1.2.1, 1.3.1rc2 und Master (Commit 06d014469fc5c79504a1b40e7d45bc33acc00773)

Um die Achse Stacheln an der Spitze der den Bars bekommen können Sie Folgendes tun:

for k, spine in ax.spines.items(): #ax.spines is a dictionary 
    spine.set_zorder(10) 

EDIT

Es scheint, dass ich nicht die Zecke Linien machen kann auf der Oberseite der Bars zu gehen. Ich habe versucht

1. ax.tick_params(direction='in', length=10, color='k', zorder=10) 
    #This increases the size of the lines to 10 points, 
    #but the lines stays hidden behind the bars 
2. for l in ax.yaxis.get_ticklines(): 
     l.set_zorder(10) 

und einige andere Weise ohne Ergebnisse. Es scheint, dass, wenn die Stäbe zeichnen sie oben gesetzt werden und die ZOrder ignoriert

Eine Abhilfe könnte die Zecke Linien nach außen

ax.tick_params(direction='out', length=4, color='k', zorder=10) 

oder beide in und nach außen zu ziehen sein, mit direction='inout'

EDIT2

Ich habe einen Test nach @ tcaswell Kommentare gemacht.

Wenn zorder im ax.bar Funktion eingestellt ist < = 2, wobei die Achse zu sein, und ticklines Gitterlinien über den Balken gezeichnet werden. Wenn der Wert> 2,01 ist (der Standardwert für die Achse), werden die Balken über der Achse, den Ticklines und dem Raster gezeichnet. Dann ist es möglich, größere Werte für die Stacheln zu setzen (wie oben), aber jeder Versuch, die zorder der Ticklines zu ändern, wird einfach ignoriert (obwohl die Werte auf den entsprechenden Künstlern aktualisiert werden).

Ich habe die zorder=1 für das Raster für die bar und zorder=0 zu verwenden versucht, und das Gitter auf der Stäbe gezogen wird. Also Zorder wird ignoriert.

rekapitulieren

Es scheint mir, dass ticklines und Netz zorder sind auf die Standardwerte nur ignoriert und gehalten. Für mich ist das ein Fehler, der irgendwie mit bar oder einigen zusammenhängt.

BTW, ich erinnere mich erfolgreich die ZOrder in ticklines ändern, wenn imshow

+0

, die wie ein Fehler klingt, können Sie überprüfen, ob es auch auf Master passieren? – tacaswell

+0

Ich gebe einen Versuch und lassen Sie –

+0

wissen @tcaswell ich auf 1.3.1rc2 und Master versucht haben (nur geholt) und funktioniert nicht. Es ist dann ein Fehler. Wer archiviert es? [Kann ich versuchen, einen Blick auf den Quellcode zu geben, später heute, wenn ich jeden Hinweis über das Problem finden] –

1

mit hatte ich das gleiche Problem von oberhalb der Achsen als @ luke_16 Plotten.In meinem Fall entstand es, wenn man die Option ax.set_axisbelow(True) verwendet, um den Mahlgrad hinter den Plots einzustellen.

für diesen Fehler Meiner Abhilfe ist, nicht das Onboard-Raster zu verwenden, aber es zu simulieren:

def grid_selfmade(ax,minor=False): 
    y_axis=ax.yaxis.get_view_interval() 
    for xx in ax.xaxis.get_ticklocs(): 
     ax.plot([xx,xx],y_axis,linestyle=':',linewidth=0.5,zorder=0) 
    if minor==True: 
     for xx in ax.xaxis.get_ticklocs(minor=True): 
      ax.plot([xx,xx],y_axis,linestyle=':',linewidth=0.5,zorder=0) 
    x_axis=ax.xaxis.get_view_interval() 
    for yy in ax.yaxis.get_ticklocs(): 
     ax.plot(x_axis,[yy,yy],linestyle=':',linewidth=0.5,zorder=0,) 
    if minor==True: 
     for yy in ax.yaxis.get_ticklocs(minor=True): 
      ax.plot(x_axis,[yy,yy],linestyle=':',linewidth=0.5,zorder=0) 

Diese Funktion muss nur die aktuelle Achse-Instanz und zieht dann über ein Onboard-artigen Gitter hinter alles andere bei den wichtigsten Ticks (optional auch für kleinere Ticks).

für die Achse und Achse Zecken auf der Graphen ist es notwendig, ax.set_axisbelow(False)-False und nicht zu verlassen zorder> 2 in Parzellen zu verwenden. Ich habe die Zordnung von Plots ohne zorder -option verwaltet, indem ich die Reihenfolge der Plot-Befehle im Code änderte.

5

Ich hatte das gleiche Problem der Achsen unterhalb der Diagrammlinie gezogen wird, wenn ich Gitterlinien im Hintergrund habe:

ax.yaxis.grid() # grid lines 
ax.set_axisbelow(True) # grid lines are behind the rest 

Die Lösung, die für mich gearbeitet, um das zorder Argument der plot() Funktion gesetzt war ein Wert zwischen 1 und 2. Es ist nicht sofort klar, aber der Zorder-Wert kann eine beliebige Zahl sein. Aus der Dokumentation für die matplotlib.artist.Artist Klasse:

set_zorder (Level)

die ZOrder für den Künstler ein. Künstler mit niedrigeren Zorder-Werten werden zuerst gezeichnet.

NEHMEN: eine beliebige Anzahl

Deshalb:

for i in range(5): 
    ax.plot(range(10), np.random.randint(10, size=10), zorder=i/100.0 + 1) 

Ich habe nicht für Werte außerhalb dieses Bereichs überprüft, vielleicht würden sie auch funktionieren.

0

Eine einfachere und bessere Lösung ist es, die Linien vom Netz Befehl zu kopieren und das Raster deaktivieren und wieder die Linien wieder hinzufügen, aber mit dem richtigen ZOrder:

ax.grid(True) 
lines = ax1.xaxis.get_gridlines().copy() + ax1.yaxis.get_gridlines().copy() 
ax.grid(False) 
for l in lines: 
    ax1.add_line(l) 
    l.set_zorder(0) 
Verwandte Themen