2013-05-10 17 views
8

Spędziłem kilka ostatnich dni próbując znaleźć sposób na usunięcie niewielkich marginesów z osi w działce 3D. Próbowałem ax.margins(0) i ax.autoscale_view('tight') i innych podejść, ale te małe marginesy nadal istnieją. W szczególności nie podoba mi się, że histogramy słupkowe są podwyższone, tj. Ich dno nie znajduje się na poziomie zerowym - patrz przykładowy obraz.Usuwanie marginesów osi na wykresie 3D

unwanted margins on all axes

W gnuplot, użyłbym "set xyplane na 0". W matplotlib, ponieważ istnieją marginesy na każdej osi po obu stronach, byłoby świetnie móc kontrolować każdą z nich.

Edit: poniżej rozwiązanie HYRY za dobrze, ale oś 'x' dostaje linię siatki narysowane nad nim przy Y = 0:

strange axis

+0

To naprawdę pomaga, jeśli można dodać kod używasz do tworzenia fabuły, więc mamy punkt wyjścia. Łatwiej będzie skopiować i wkleić kod, a następnie znaleźć rozwiązanie tego konkretnego problemu. – hooy

+0

Wiele przykładowego kodu [tutaj] (http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html) (przykład "Bar działek" jest podobny do mojego przypadku powyżej). – dolphin

Odpowiedz

6

nie ma właściwość lub metoda, która może zmodyfikuj te marginesy. Musisz załatać kod źródłowy. Oto przykład:

from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import numpy as np 
###patch start### 
from mpl_toolkits.mplot3d.axis3d import Axis 
if not hasattr(Axis, "_get_coord_info_old"): 
    def _get_coord_info_new(self, renderer): 
     mins, maxs, centers, deltas, tc, highs = self._get_coord_info_old(renderer) 
     mins += deltas/4 
     maxs -= deltas/4 
     return mins, maxs, centers, deltas, tc, highs 
    Axis._get_coord_info_old = Axis._get_coord_info 
    Axis._get_coord_info = _get_coord_info_new 
###patch end### 

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]): 
    xs = np.arange(20) 
    ys = np.random.rand(20) 

    # You can provide either a single color or an array. To demonstrate this, 
    # the first bar of each set will be colored cyan. 
    cs = [c] * len(xs) 
    cs[0] = 'c' 
    ax.bar(xs, ys, zs=z, zdir='y', color=cs, alpha=0.8) 

ax.set_xlabel('X') 
ax.set_ylabel('Y') 
ax.set_zlabel('Z') 

plt.show() 

Wynikiem jest:

enter image description here

Edit

Aby zmienić kolor linii siatki:

for axis in (ax.xaxis, ax.yaxis, ax.zaxis): 
    axis._axinfo['grid']['color'] = 0.7, 1.0, 0.7, 1.0 

Edi t2

Zestaw X & Y Lim:

ax.set_ylim3d(-1, 31) 
ax.set_xlim3d(-1, 21) 
+0

Dziękuję, zadziałało ... (1) jeśli zmienię "na c, z w zip (['r', 'g', 'b', 'y'], [30, 20, 10, 2]) ', dlaczego oś" X "ma gruby przerywany styl linii? (2) Jak zmienić kolory linii siatki? 'ax.grid (color = 'blue')' nie działa. – dolphin

+0

@dolphin, czy możesz opublikować wynik (1)? Dla (2), kolor nie może być modyfikowany przez niektóre API, dodałem kod, który zmienił ukryty dyktando _axinfo. – HYRY

+0

Dzięki za (2)! Szkoda, że ​​złożoność i elastyczność matplotlib powoduje tak wiele "hacków", które muszą być indywidualnie wyszukiwane, a intuicyjne rozwiązania czasami działają, czasem nie.Jeśli chodzi o (1), nie mogłem opublikować obrazu w komentarzu, więc wkleiłem fragment kodu z nadzieją, że uda się go odtworzyć :-) Teraz dodałem kolejny obraz jako Edytuj w pierwotnym pytaniu. – dolphin

0

musiałem podkręcić przyjętego rozwiązania nieznacznie, bo w moim przypadku osi X i Y (ale nie z) miała dodatkowy margines, który, przez wydrukowanie mins, maxs, deltas, okazało się być deltas * 6.0/11. Oto zaktualizowana łatka, która sprawdziła się w moim przypadku.

###patch start### 
from mpl_toolkits.mplot3d.axis3d import Axis 
def _get_coord_info_new(self, renderer): 
    mins, maxs, cs, deltas, tc, highs = self._get_coord_info_old(renderer) 
    correction = deltas * [1.0/4 + 6.0/11, 
          1.0/4 + 6.0/11, 
          1.0/4] 
    mins += correction 
    maxs -= correction 
    return mins, maxs, cs, deltas, tc, highs 
if not hasattr(Axis, "_get_coord_info_old"): 
    Axis._get_coord_info_old = Axis._get_coord_info 
Axis._get_coord_info = _get_coord_info_new 
###patch end### 

(Ja również zmienił logikę łatanie się trochę tak, że edytując funkcję i przeładowywania jej moduł działa zgodnie z oczekiwaniami w Jupyter.)

Powiązane problemy