2016-09-28 4 views
0

Python 2.7, matplotlib 1.5.1, Win 7 mal 64Matplotlib 3D streuen automatische Skalierung Ausgabe

Ich versuche, die kürzesten Abstände zwischen einem Knoten & seiner geometrischen nächsten Nachbarn (dh nicht seinen nächsten Nachbarn verbunden) in einer plotten Grafik mit Dijkstra-Algorithmus.

Der Algorithmus funktioniert gut, aber wenn es um das Plotten geht, flippt Matplotlibs Skalierung aus, wenn ich bestimmte Knoten zeichne. Snippet

Code:

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 

# Find the paths between a given node & its nearest neighbours 

def plotPath(pathStart, pathEnd, pointCol='b'): 

    shortPath = graph.dijkstra(pathStart, pathEnd) # this calculates the shortest path 

    pathNodesIdx = [i-1 for i in shortPath] # Algorithm returns 1 indexed whilst Python uses 0 indexed 
    pathCoords = L3.nodes[pathNodesIdx, 1:4] # retrieves the coordinate for the nodes on the path 

    ax.scatter(pathCoords[1:-1,0], pathCoords[1:-1,1], pathCoords[1:-1,2], s=240, c=pointCol, marker='o') 
    startNode = pathCoords[0] 
    endNode = pathCoords[-1] 
    ax.scatter(startNode[0], startNode[1], startNode[2], s=240, c='g', marker='o') 
    ax.scatter(endNode[0], endNode[1], endNode[2], s=240, c='r', marker='o') 
    for node in pathCoords[1:]: 
     ax.plot([startNode[0], node[0]], [startNode[1], node[1]], [startNode[2], node[2]], color=pointCol, linewidth=2.0) 
     startNode = node 

    return pathCoords 


pointCol = 'b' 
fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 

pathStart = 1 # given node 
graph=Graph(L3.trabGraph) # L3.trabGraph is list conataining the edge/node/cost information for the graph 

# Return indices for nearest neighbours 
nearest = [i+1 for i in L3.nodeNeighbours(pathStart, numNeighs=6, method='brute')[1:]] 

Zum Beispiel habe ich plotten nur den Weg zum zweiten nächsten Nachbarn mit plotPath(1, nearest[2]) ich:

enter image description here

Aber wenn ich die anderen nächsten Nachbarn hinzufügen verwenden,

p0 = plotPath(1, nearest[0]) 
p1 = plotPath(1, nearest[1]) 
p2 = plotPath(1, nearest[2]) 
p3 = plotPath(1, nearest[3]) 
p4 = plotPath(1, nearest[4]) 

Ich bekomme:

enter image description here

Als Referenz werden die Koordinaten der Knoten für jeden Fall:

p0 = array([[ 1.094, 1.76 , 1.125], 
     [ 1.188, 1.75 , 1.104]]) 

p1 = array([[ 1.094, 1.76 , 1.125], 
     [ 1.104, 1.875, 1.094]]) 

p2 = array([[ 1.094, 1.76 , 1.125], 
     [ 1.188, 1.75 , 1.104], 
     [ 1.188, 1.688, 1.094]]) 

p3 = array([[ 1.094, 1.76 , 1.125], 
     [ 1.198, 1.76 , 1.198]]) 

p4 = array([[ 1.094, 1.76 , 1.125], 
     [ 1.198, 1.76 , 1.198], 
     [ 1.188, 1.708, 1.198]]) 

Für das Leben von mir, ich sehe nicht, warum matplotlib dies tut? Jeder weiß es?

Ich habe die Ausführungen des Algorithmus Dijkstra ausgelassen (von Rosetta Code FYI) & die Erstellung des Graphen aus Gründen der Kürze & die Tatsache, dass ich nicht frei bin die Grafik, Informationen zu teilen.

+0

Können Sie uns sagen, was Matplotlib genau macht, was Sie hier nicht mögen/erwarten und wie Sie das Ergebnis aussehen lassen würden? Ohne zu wissen, was Sie erreichen wollen, kann Ihnen niemand helfen. Vielleicht hilft [dies] (http://stackoverflow.com/help/how-to-ask). – ImportanceOfBeingErnest

+0

Die 2 Bilder in der Post enthalten die gleichen Daten. Im ersten Bild sehen Sie, dass das Diagramm automatisch skaliert wurde, um die Größe der Leinwand an die Daten anzupassen. Im zweiten Bild werden dem Diagramm zusätzliche 7 Punkte hinzugefügt, aber die automatische Skalierung hat die Größe der Leinwand so stark vergrößert, dass die Punkte jetzt alle in die Ecke gebündelt sind. Wie aus den Punktlisten am Ende des Posts ersichtlich ist, belegen alle Punkte nur einen sehr kleinen Teilbereich des neu automatisch skalierten Canvas. – DrBwts

+0

Ja, stimmt. Aber was genau ist das Problem? – ImportanceOfBeingErnest

Antwort

1

Wenn die Frage hier wirklich ist "Wie setze ich die Grenzen eines 3D-Plots in Matplotlib?" dann wäre die Antwort:

So wie Sie in der 2. Fall tun:

ax.set_xlim([xmin, xmax]) 
ax.set_ylim([ymin, ymax]) 
ax.set_zlim([zmin, zmax]) 

für die jeweiligen Fälle die Werte min und max Finding könnte natürlich automatisiert werden.