C'è un modo per ottenere matplotlib per tracciare un cerchio perfetto? Sembrano più ovali.Perché Matplotlib traccia i miei cerchi come ovali?
risposta
Solo per espandere la risposta corretta di DSM. Per impostazione predefinita, i grafici hanno più pixel lungo un asse rispetto all'altro. Quando aggiungi un cerchio, viene tradizionalmente aggiunto in unità di dati. Se i tuoi assi hanno un intervallo simmetrico, significa che un passo lungo l'asse x comporterà un diverso numero di pixel rispetto a un passo lungo l'asse y. Quindi un cerchio simmetrico in unità di dati è asimmetrico nelle tue unità Pixel (ciò che vedi effettivamente).
Come indicato correttamente dal DSM, è possibile forzare gli assi xey ad avere un numero uguale di pixel per unità di dati. Questo viene fatto usando i metodi plt.axis("equal")
o ax.axis("equal")
(dove ax
è un'istanza di Axes
).
È inoltre possibile disegnare un Ellipse
in modo che venga ridimensionato in modo appropriato per assomigliare ad un cerchio sulla trama. Ecco un esempio di un caso del genere:
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Circle
fig = plt.figure()
ax1 = fig.add_subplot(211)
# calculate asymmetry of x and y axes:
x0, y0 = ax1.transAxes.transform((0, 0)) # lower left in pixels
x1, y1 = ax1.transAxes.transform((1, 1)) # upper right in pixes
dx = x1 - x0
dy = y1 - y0
maxd = max(dx, dy)
width = .15 * maxd/dx
height = .15 * maxd/dy
# a circle you expect to be a circle, but it is not
ax1.add_artist(Circle((.5, .5), .15))
# an ellipse you expect to be an ellipse, but it's a circle
ax1.add_artist(Ellipse((.75, .75), width, height))
ax2 = fig.add_subplot(212)
ax2.axis('equal')
# a circle you expect to be a circle, and it is
ax2.add_artist(Circle((.5, .5), .15))
# an ellipse you expect to be an ellipse, and it is
ax2.add_artist(Ellipse((.75, .75), width, height))
fig.savefig('perfectCircle1.png')
conseguente in questa figura:
In alternativa, è possibile regolare la tua figura in modo che il Axes
sono quadrati:
# calculate dimensions of axes 1 in figure units
x0, y0, dx, dy = ax1.get_position().bounds
maxd = max(dx, dy)
width = 6 * maxd/dx
height = 6 * maxd/dy
fig.set_size_inches((width, height))
fig.savefig('perfectCircle2.png')
risultante in:
Nota come il secondo asse, che ha l'opzione axis("equal")
, ora ha lo stesso intervallo per gli assi xe y. La figura è stata ridimensionata in modo che le unità di data di ciascuna siano rappresentate dallo stesso numero di pixel.
È anche possibile regolare gli assi in modo che siano quadrati, anche se la cifra non lo è. Oppure puoi cambiare la trasformazione predefinita per il cerchio in None
, il che significa che le unità utilizzate sono pixel. Al momento sto avendo difficoltà a fare questo (il cerchio è un cerchio, ma non dove voglio che sia).
Questo è molto più dettagliato del mio (era) che dovrebbe diventare la risposta canonica. – DSM
Risposta eccellente - un TL generalmente utile; DR è sicuro di fare matplotlib.pyplot.axis ("uguale") subito :-) –
Ho riscontrato lo stesso problema oggi e penso che potrei avere una soluzione più flessibile. Rimangono due problemi principali con la risposta precedente (se non si utilizza la funzione di uguale aspetto). Innanzitutto se ridimensioni l'intero grafico, la proporzione non sarà la stessa poiché il numero di pixel cambierà. Secondo punto, questo trucco non funziona se non si ha lo stesso limite per gli xaxis e gli yaxis.
Questa soluzione utilizza mpl con un oggetto personalizzato. Infatti, ogni volta che si modifica uno degli assi lim o le dimensioni del grafico, mpl chiamerà una funzione interna che prenderà il valore di larghezza e altezza dell'ellisse moltiplicato per il valore della funzione di trasformazione. Dal momento che il valore della larghezza e l'altezza viene memorizzato nell'oggetto ellisse, un modo è quello di creare un oggetto personalizzato con un valore aggiornato ogni volta che la funzione viene chiamata, in base alle proprietà ascia attuali:
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
class GraphDist() :
def __init__(self, size, ax, x=True) :
self.size = size
self.ax = ax
self.x = x
@property
def dist_real(self) :
x0, y0 = self.ax.transAxes.transform((0, 0)) # lower left in pixels
x1, y1 = self.ax.transAxes.transform((1, 1)) # upper right in pixes
value = x1 - x0 if self.x else y1 - y0
return value
@property
def dist_abs(self) :
bounds = self.ax.get_xlim() if self.x else self.ax.get_ylim()
return bounds[0] - bounds[1]
@property
def value(self) :
return (self.size/self.dist_real) * self.dist_abs
def __mul__(self, obj) :
return self.value * obj
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim((0,10))
ax.set_ylim((0,5))
width = GraphDist(10, ax, True)
height = GraphDist(10, ax, False)
ax.add_artist(Ellipse((1, 3), width, height))
plt.show()
- 1. Perché raytracer rende le sfere come ovali?
- 2. Traccia grafici sullo schermo utilizzando l'API matplotlib
- 3. matplotlib: aggiornamento posizione delle patch (o: set_xy per cerchi)
- 4. Come disegnare le linee tra i cerchi?
- 5. NUNIT sta ignorando i miei test? Perché?
- 6. Perché dovrei firmare i miei file JAR?
- 7. Perché VS2010 rimuove i miei riferimenti?
- 8. Perché dovrei testare i miei HTMLHelpers?
- 9. Perché Mojolicious annida i miei percorsi?
- 10. Perché Thread.Sleep (0) risolve i miei problemi e come evitarlo?
- 11. Perché i miei hash sono stampati come stringhe?
- 12. Perché i miei tipi non sono contrassegnati come uguali?
- 13. perché i miei file php vengono visualizzati come testo normale?
- 14. Come faccio a rendere il pulsante "Mi piace" di Facebook non traccia i miei utenti?
- 15. Collisione di cerchi su tela, come capire dove dovrebbero spostarsi i cerchi una volta scontrati?
- 16. Come estrarre i dati dal grafico matplotlib
- 17. Matplotlib: pcolor() non traccia l'ultima riga e colonna?
- 18. Perché i miei database CouchDB crescono così in fretta?
- 19. Traccia gli assi logaritmici con matplotlib in python
- 20. Perché la traccia dello stack mostra il percorso dei miei file di sviluppo?
- 21. Matplotlib: traccia linee con larghezza data in coordinate dati
- 22. Matplotlib - Traccia un piano e punti in 3D contemporaneamente
- 23. python: traccia una barra usando matplotlib usando un dizionario
- 24. Perché xgboost non sta pianificando i miei alberi?
- 25. Perché il mio stack traccia i passaggi mancanti?
- 26. Perché i miei frammenti onSaveInstanceState() non vengono chiamati?
- 27. Perché tutti i miei schemi di colori MacVim sembrano sbagliati?
- 28. Perché "mvn verify" non esegue i miei test di integrazione?
- 29. Perché C stampa i miei valori esadecimali in modo errato?
- 30. Perché i miei messaggi WCF in coda scompaiono silenziosamente?
Avete controllato la risoluzione video per assicurarsi che sia lo stesso della risoluzione del tuo monitor? Potrebbe essere che tutto ciò che stai visualizzando è distorto. –