【问题标题】:Library/tool for drawing ternary/triangle plots [closed]用于绘制三元/三角形图的库/工具 [关闭]
【发布时间】:2010-10-16 15:08:16
【问题描述】:

我需要画ternary/triangle plots 代表各种物质/混合物( x + y + z = 1)。每个图代表等值物质,例如熔点相同的物质。这些图需要用不同的颜色/符号绘制在同一个三角形上,如果我也可以连接这些点就好了。

我看过 matplotlib、R 和 gnuplot,但他们似乎无法画出这种情节。 R 的第 3 方 ade4 包似乎可以绘制它,但我不确定是否可以在同一个三角形上绘制多个图。

我需要在 Linux 或 Windows 下运行的东西。我愿意接受任何建议,包括其他语言的库,例如Perl、PHP、Ruby、C# 和 Java。

【问题讨论】:

  • R 选项比下面列出的要多一些;试试library(sos); findFn("{ternary plot}")
  • 我刚刚编写的一个 R 包可以满足您的要求(以及更多)它基于 ggplot,网站是 www.ggtern.com
  • @CristianCiupitu 完成

标签: python r plot gnuplot


【解决方案1】:

创建了一个非常基本的脚本来生成三元(或更多)图。没有网格线或刻度线,但使用“基础”数组中的向量添加这些不会太难。

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

【讨论】:

    【解决方案2】:

    R 有一个名为VCD 的外部包,它应该可以满足您的需求。

    文档非常好(122 页手册随包分发);还有一本同名的书,Visual Display of Quantitative Information,作者是包的作者(Michael Friendly 教授)。

    要使用 vcd 创建三元图,只需调用 ternaryplot() 并传入一个 mx 3 矩阵,即具有三个的矩阵列。

    方法签名很简单;只需要一个参数(m x 3 数据矩阵);并且所有关键字参数都与绘图的美感有关,除了 scale,当它设置为 1 时,会按列对数据进行规范化。

    为了在三元图上绘制数据点,给定点的坐标被计算为质心点,其中构成数据矩阵的每个特征值都是一个单独的权重,因此点 V(a, b, c) 的坐标为

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

    为了生成下图,我刚刚创建了一些假数据来表示四种不同的化学混合物,每种都由三种物质(x、y、z)的不同比例组成。我缩放了输入(所以 x + y + z = 1)但是如果您为其“缩放”参数传入一个值,该函数将为您完成(实际上,默认值为 1,我相信这是您的问题要求)。我使用不同的颜色和符号来表示四个数据点,但您也可以只使用单一颜色/符号并标记每个点(通过“id”参数)。

    【讨论】:

    • 它看起来确实很有趣,可惜它有很多依赖项,而我的 Fedora 12 机器上没有:-( 无论如何,谢谢你的回答和我的 +1。
    • 那太糟糕了——我想你可能会喜欢使用那个库。 (很巧合的是,当我在上面输入我的答案时,我正坐在布加勒斯特机场,在从华丽的 Fagaras 山脉攀登返回西班牙的途中。)我认为我没有代表可以添加“ r' 标签添加到您的 Q 中,所以如果您同意,可以在有机会时添加该标签。
    • 我通过运行 R 并在 R 提示符下输入 install.packages(c("vcd")) 设法将它安装在 Fedora 12 上。 ternaryplot 手册页中的示例也很有魅力。再次感谢你!至于r标签,我没有注意到你的评论,否则我会自己添加它。 P.S.:很高兴您喜欢您的攀岩之旅。
    【解决方案3】:

    我在 R 中编写的一个包刚刚被 CRAN 接受,网页是 www.ggtern.com:

    它基于我用作平台的 ggplot2。对我来说,驱动力是希望在我的工作中保持一致性,而且由于我大量使用 ggplot2,因此该软件包的开发是一个合乎逻辑的过程。

    对于那些使用 ggplot2 的人来说,使用 ggtern 应该是轻而易举的事,这里有几个演示可以实现什么。

    使用以下代码生成:

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

    等值线图也已针对三元环境进行了修补,并包含了一个新几何图形,用于通过 马氏距离表示置信区间。

    使用以下代码生成:

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

    【讨论】:

      【解决方案4】:

      Veusz 支持三元图。下面是来自documentation 的示例:

      【讨论】:

        【解决方案5】:

        Chloë Lewis 开发了一个三角形图通用类,旨在支持土壤质地三角形 使用 Python 和 Matplotlib。可在此处获得 http://nature.berkeley.edu/~chlewis/Sourcecode.html https://github.com/chlewissoil/TernaryPlotPy

        Chloe 编辑添加:将其移至更可靠的主机!此外,它是一个公共回购,所以如果你想请求图书馆化,你可以添加一个问题。希望它对某人有用。

        【讨论】:

        • 漂亮的图和 +1 太糟糕了,代码不够通用,不能用作库。
        • @chplewis:感谢您的编辑!
        【解决方案6】:

        我刚刚发现了一个使用 Python/Matplotlib 生成三元图的工具,称为 wxTernary。它可以通过http://wxternary.sourceforge.net/ 获得——我第一次尝试就成功地生成了一个三元图。

        【讨论】:

        • 项目似乎没有在 SCM 中签入脚本 :(
        【解决方案7】:

        在 gnuplot 中似乎有一个实现here
        (来源:ugm.ac.id

        【讨论】:

        • 看起来很有趣,但我在使用最后一个命令时遇到了问题。我不得不修改(截断)它。我会进一步调查。谢谢。
        【解决方案8】:

        如果找不到更简单的方法,请查找矢量绘图库并从头开始绘制。

        【讨论】:

        • 我也想过这个,但它会做太多(咕噜声)的工作。有很多细节需要弄清楚,例如轴标签或刻度线的位置。顺便说一句,Phil 的解决方案基本上是从头开始绘制情节。
        【解决方案9】:

        有一个名为 soiltexture 的 R 包。主要针对土壤质地三角图,但也可以针对某些方面进行定制。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-07
          • 1970-01-01
          • 2014-12-10
          • 2023-03-17
          • 2014-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多