Domanda

Ho bisogno di disegnare ternari trame / triangolo rappresentano frazioni molari ( x , y , z ) di varie sostanze / miscele ( x + y + z = 1). Ogni trama rappresenta sostanze iso-valore, per esempio sostanze che hanno lo stesso punto di fusione. Le trame devono essere disegnati sullo stesso triangolo con diversi colori / simboli e sarebbe bello se potessi anche unire i puntini.

Ho guardato matplotlib, R e gnuplot, ma loro non sembrano essere in grado di disegnare questo tipo di trama. Il 3rd party ade4 pacchetto per R sembra essere in grado di disegnare, ma non sono sicuro se posso disegnare più lotti sullo stesso triangolo.

Ho bisogno di qualcosa che gira sotto Linux o Windows. Sono aperto a qualsiasi suggerimento, tra cui librerie per altre lingue, per esempio Perl, PHP, Ruby, C # e Java.

È stato utile?

Soluzione

R ha un pacchetto esterno chiamato VCD che dovrebbe fare quello che vuoi.

La documentazione è molto buona (122 pagine di manuale distribuito w / confezione); c'è anche un libro con lo stesso nome, Visual Display di Informazioni di natura quantitativa , dall'autore del pacchetto (Prof. Michael Friendly).

Per creare diagramma ternario utilizzando VCD , basta chiamare ternaryplot () e passare in una matrice mx 3, ossia una matrice con tre colonne.

La firma di metodo è molto semplice; solo è necessario un solo parametro (la matrice m x dati 3); e tutti i parametri di parole chiave riguardano l'estetica del trama, fatta eccezione per la scala, che quando è impostato a 1, normalizza i dati della colonna-saggio.

Per tracciare punti dati sul diagramma ternario, le coordinate per un dato punto sono determinati come baricentro dei punti di massa in cui ogni valore caratteristica comprendente la matrice dei dati è un separato peso , quindi le coordinate di un punto V (a, b, c) sono

V(b, c/2, c * (3^.5)/2

Per generare lo schema qui sotto, gli appena creato alcuni dati falsi per rappresentare quattro diverse miscele chimiche, ciascuno costituito varie frazioni di tre sostanze (x, y, z). Ho scalato l'ingresso (quindi x + y + z = 1) ma la funzione lo farò per voi, se si passa a un valore per il suo parametro 'scala' (in realtà, il valore predefinito è 1, che credo sia quello che la tua domanda richiede). Ho usato diversi colori e simboli per rappresentare i quattro punti di dati, ma si può anche semplicemente utilizzare un solo colore / simbolo ed etichettare ogni punto (tramite l'argomento 'id').

Altri suggerimenti

creato uno script molto di base per la generazione di diagramma ternario (o più). Non ci sono le griglie o ticklines, ma coloro che non sarebbe troppo difficile aggiungere utilizzando i vettori nella matrice "basi".

entrare descrizione dell'immagine qui

from pylab import *


def ternaryPlot(
            data,

            # Scale data for ternary plot (i.e. a + b + c = 1)
            scaling=True,

            # Direction of first vertex.
            start_angle=90,

            # Orient labels perpendicular to vertices.
            rotate_labels=True,

            # Labels for vertices.
            labels=('one','two','three'),

            # Can accomodate more than 3 dimensions if desired.
            sides=3,

            # Offset for label from vertex (percent of distance from origin).
            label_offset=0.10,

            # Any matplotlib keyword args for plots.
            edge_args={'color':'black','linewidth':2},

            # Any matplotlib keyword args for figures.
            fig_args = {'figsize':(8,8),'facecolor':'white','edgecolor':'white'},
        ):
    '''
    This will create a basic "ternary" plot (or quaternary, etc.)
    '''
    basis = array(
                    [
                        [
                            cos(2*_*pi/sides + start_angle*pi/180),
                            sin(2*_*pi/sides + start_angle*pi/180)
                        ] 
                        for _ in range(sides)
                    ]
                )

    # If data is Nxsides, newdata is Nx2.
    if scaling:
        # Scales data for you.
        newdata = dot((data.T / data.sum(-1)).T,basis)
    else:
        # Assumes data already sums to 1.
        newdata = dot(data,basis)

    fig = figure(**fig_args)
    ax = fig.add_subplot(111)

    for i,l in enumerate(labels):
        if i >= sides:
            break
        x = basis[i,0]
        y = basis[i,1]
        if rotate_labels:
            angle = 180*arctan(y/x)/pi + 90
            if angle > 90 and angle <= 270:
                angle = mod(angle + 180,360)
        else:
            angle = 0
        ax.text(
                x*(1 + label_offset),
                y*(1 + label_offset),
                l,
                horizontalalignment='center',
                verticalalignment='center',
                rotation=angle
            )

    # Clear normal matplotlib axes graphics.
    ax.set_xticks(())
    ax.set_yticks(())
    ax.set_frame_on(False)

    # Plot border
    ax.plot(
        [basis[_,0] for _ in range(sides) + [0,]],
        [basis[_,1] for _ in range(sides) + [0,]],
        **edge_args
    )

    return newdata,ax


if __name__ == '__main__':
    k = 0.5
    s = 1000

    data = vstack((
        array([k,0,0]) + rand(s,3), 
        array([0,k,0]) + rand(s,3), 
        array([0,0,k]) + rand(s,3)
    ))
    color = array([[1,0,0]]*s + [[0,1,0]]*s + [[0,0,1]]*s)

    newdata,ax = ternaryPlot(data)

    ax.scatter(
        newdata[:,0],
        newdata[:,1],
        s=2,
        alpha=0.5,
        color=color
        )
    show()

Un pacchetto che ho scritto in R ha solo stato accettato per CRAN, pagina web è www.ggtern .it :

Si basa off ggplot2 , che ho usato come piattaforma. La forza trainante per me, è stato il desiderio di avere coerenza nel mio lavoro, e, dato che io uso ggplot2 pesantemente, lo sviluppo del pacchetto era una progressione logica.

Per quelli di voi che usano ggplot2, uso di ggtern dovrebbe essere un gioco da ragazzi, e, ecco un paio di manifestazioni di ciò che può essere raggiunto.

feldspato

Prodotto con il seguente codice:

# Load data
data(Feldspar)

# Sort it by decreasing pressure 
# (so small grobs sit on top of large grobs
Feldspar <- Feldspar[with(Feldspar, order(-P.Gpa)), ]

# Build and Render the Plot
ggtern(data = Feldspar, aes(x = An, y = Ab, z = Or)) + 
#the layer
geom_point(aes(fill = T.C, 
               size = P.Gpa, 
               shape = Feldspar)) + 
#scales
scale_shape_manual(values = c(21, 24)) + 
scale_size_continuous(range = c(2.5, 7.5)) + 
scale_fill_gradient(low = "green", high = "red") + 

#theme tweaks
theme_tern_bw()  + 
theme(legend.position      = c(0, 1), 
      legend.justification = c(0, 1), 
      legend.box.just      = "left") + 

#tweak guides
guides(shape= guide_legend(order   =1,
                           override.aes=list(size=5)),
       size = guide_legend(order   =2),
       fill = guide_colourbar(order=3)) +

#labels and title
labs(size = "Pressure/GPa", 
     fill = "Temperature/C") + 
ggtitle("Feldspar - Elkins and Grove 1990")

grafici di contorno sono state anche patch per l'ambiente ternario, e, l'inserimento di una nuova geometria per rappresentare intervalli di confidenza con il Mahalanobis Distanza .

contorno

Prodotto con il seguente codice:

ggtern(data=Feldspar,aes(An,Ab,Or)) +
  geom_confidence(aes(group=Feldspar,
                      fill=..level..,
                      alpha=1-..level..),
                      n=2000,
                  breaks=c(0.01,0.02,0.03,0.04,
                           seq(0.05,0.95,by=0.1),
                           0.99,0.995,0.9995),
                  color=NA,linetype=1) +
  geom_density2d(aes(color=..level..)) + 
  geom_point(fill="white",aes(shape=Feldspar),size=5) +  
  theme_tern_bw() + 
  theme_tern_nogrid() + 
  theme(ternary.options=element_ternary(padding=0.2),
                        legend.position=c(0,1),
                        legend.justification=c(0,1),
                        legend.box.just="left") +
  labs(color="Density",fill="Confidence",
   title="Feldspar - Elkins and Grove 1990 + Confidence Levels + Density") +
  scale_color_gradient(low="gray",high="magenta") +
  scale_fill_gradient2(low="red",mid="orange",high="green",
                       midpoint=0.8) +
  scale_shape_manual(values=c(21,24)) + 
  guides(shape= guide_legend(order   =1,
                             override.aes=list(size=5)),
         size = guide_legend(order   =2),
         fill = guide_colourbar(order=3),
         color= guide_colourbar(order=4),
         alpha= "none")

Veusz supporta diagramma ternario. Ecco un esempio dalla : Esempio complotto

Chloë Lewis sviluppato una classe generale triangolo-plot, destinato a sostenere il triangolo tessitura del suolo con Python e Matplotlib. E 'disponibile qui http://nature.berkeley.edu/~chlewis/Sourcecode.html https : //github.com/chlewissoil/TernaryPlotPy

editing Chloe per aggiungere: spostato a un host più affidabile! Inoltre, si tratta di un pronti contro termine pubblico, quindi se si desidera richiedere biblioteca-zione, si potrebbe aggiungere un problema. La speranza è utile a qualcuno.

Ho appena scoperto uno strumento che utilizza Python / Matplotlib per generare diagramma ternario chiamati wxTernary. E 'disponibile via http://wxternary.sourceforge.net/ - sono stato in grado di generare con successo un diagramma ternario al primo tentativo.

Sembra che ci sia un'implementazione al lavoro qui in gnuplot: diagramma ternario
(fonte: ugm.ac.id )

Trovare una libreria di disegno vettoriale e disegnare da zero se non riesci a trovare un modo più semplice per farlo.

Esiste un pacchetto R chiamato soiltexture . E 'rivolto a tessitura del suolo trama triangolo, ma può essere personalizzato per alcuni aspetti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top