Pergunta

Eu preciso desenhar ternário / parcelas triângulo representando frações molares ( x , y , Z ) de diversas substâncias / misturas ( x + y + Z = 1). Cada gráfico representa substâncias com valor de, por exemplo, iso substâncias que tenham o mesmo ponto de fusão. As parcelas precisam ser desenhados no mesmo triângulo com diferentes cores / símbolos e seria bom se eu poderia também ligar os pontos.

Eu olhei matplotlib, R e gnuplot, mas eles não parecem ser capazes de tirar este tipo de enredo. The 3rd party ade4 pacote para R parece ser capaz de desenhá-lo, mas Eu não tenho certeza se eu posso desenhar várias parcelas no mesmo triângulo.

Eu preciso de algo que é executado sob Linux ou Windows. Estou aberto a todas as sugestões, incluindo bibliotecas para outras línguas, por exemplo, Perl, PHP, Ruby, C # e Java.

Foi útil?

Solução

R tem um pacote externo chamado VCD que deve fazer o que quiser.

A documentação é muito bom (122 página do manual distribuído w / o pacote); há também um livro com o mesmo nome, Visual exibição de informações quantitativas , pelo autor do pacote (Prof. Michael Friendly).

Para criar ternários parcelas usando vcd , assim chamada ternaryplot () e passar em uma matriz mx 3, ou seja, uma matriz com três colunas.

A assinatura do método é muito simples; apenas um único parâmetro (a matriz de m x dados 3) é necessária; e todas as palavras-parâmetros se relacionam com a estética do enredo, com exceção de escala, que quando definido como 1, normaliza os dados da coluna-wise.

Para traçar pontos de dados na trama ternário, as coordenadas para um dado ponto são calculadas como o centro de gravidade dos pontos de massa em que cada valor de recurso compreendendo a matriz de dados é um separada peso , daí as coordenadas de um ponto de V (a, b, c) são

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

Para gerar o diagrama abaixo, i criado apenas alguns dados falsos para representar quatro misturas químicas diferentes, cada um composto por diferentes fracções de três substâncias (x, y, z). I escalado a entrada (para x + y + z = 1), mas a função vai fazer isso por você, se você passar um valor para o seu parâmetro de 'escala' (na verdade, o padrão é 1, o que eu acredito é o que a sua pergunta requer). Eu usei diferentes cores e símbolos para representar os quatro pontos de dados, mas você também pode usar apenas uma única cor / símbolo e etiquetar cada ponto (via o argumento 'id').

Outras dicas

Criado um script muito básico para ternária de geração (ou mais) parcelas. Não há linhas de grade ou ticklines, mas aqueles que não seria muito difícil para adicionar usando os vetores na matriz "base".

enter descrição da imagem aqui

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()

Um pacote que tenho criado em R tenha apenas foi aceito para CRAN, webpage é www.ggtern .com :

É baseado off ggplot2 , que tenho usado como uma plataforma. A força motriz para mim, era um desejo de ter consistência no meu trabalho, e, desde que eu uso ggplot2 fortemente, o desenvolvimento do pacote foi uma progressão lógica.

Para aqueles de vocês que usam ggplot2, uso de ggtern deve ser uma brisa, e, aqui está um par de demonstrações de que pode ser alcançado.

feldspato

Produzido com o seguinte código:

# 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")

Gráficos de contorno também foram corrigidos para o ambiente ternário, e, a inclusão de uma nova geometria para representar intervalos de confiança através da Mahalanobis Distância .

Contour

Produzido com o seguinte código:

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 suporta diagrama ternário. Aqui está um exemplo do documentação : Exemplo trama

Chloë Lewis desenvolveu uma classe geral triângulo-enredo, destina-se a apoiar o triângulo textura do solo com Python e Matplotlib. Ele está disponível aqui http://nature.berkeley.edu/~chlewis/Sourcecode.html https : //github.com/chlewissoil/TernaryPlotPy

Chloe edição para adicionar: mudou-se para um host mais confiável! Além disso, é um repositório público, por isso, se você deseja solicitar biblioteca-ização, você pode adicionar um problema. Espero que seja útil para alguém.

Eu só descobri uma ferramenta que utiliza Python / Matplotlib para gerar ternários parcelas chamados wxTernary. Ele está disponível via http://wxternary.sourceforge.net/ - eu era capaz de gerar com sucesso um plot ternário na primeira tentativa.

Parece haver uma implementação no trabalho aqui em gnuplot: plot ternário
(fonte: ugm.ac.id )

Encontre uma biblioteca de desenho vetorial e desenhá-la a partir do zero, se você não consegue encontrar uma maneira mais fácil de fazê-lo.

Há um pacote de R chamado soiltexture . É destinado a trama triângulo textura do solo, mas pode ser personalizado para alguns aspectos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top