代码之家  ›  专栏  ›  技术社区  ›  Martin Drozdik rlbond

如何用Python绘出三值等值线图?

  •  2
  • Martin Drozdik rlbond  · 技术社区  · 6 年前

    do it very nicely using the Matlab API

    enter image description here

    但我不知道如何使用pythonapi实现这一点。引用有一个名为 Ternary Contour Plots in Python 但它不绘制数值函数,而是将单纯形映射到给定离散集的函数。

    import plotly as py
    
    A = [0, .2, .2, .2, 0, .6, .75, .9, 0, 1, .8, .3]
    B = [1, .2, .4, .1, 0, .4, .05, 0, .8, 0, .05, .3]
    C = [0, .6, .4, .7, 1, 0, .2, .1, .2, 0, .15, .4]
    Z = [.1, .5, .1, .2, 1, .8, .4, 0, .1, .6, 1, .7]
    
    trace = {
        "type": 'scatterternary',
        "carpet": 'scattercontour',
        "a": A,
        "b": B,
        "c": C,
        "z": Z
    }
    
    layout = {
        'title': 'Simple Ternary Contour Plot with Python'
    }
    
    figure = dict(data=[trace], layout=layout)
    py.offline.plot(figure, validate=False)
    

    但我得到的却是这样的情节:

    enter image description here

    2 回复  |  直到 6 年前
        1
  •  1
  •   petem    6 年前

    如果有人还感兴趣, here 是一个Jupyter笔记本,看看如何生成一个绘出的三元等高线图。

        2
  •  0
  •   Martin Drozdik rlbond    6 年前

    如果可以生成要绘制任意比例轮廓的数据,则有一种解决方法。在这种情况下,你可以用三元坐标来计算曲面坐标。

    import plotly as py
    import plotly.graph_objs as go
    import numpy as np
    
    
    def compute_in_barycentric_coordinates(a, b, c):
        epsilon = 1e-6
        if 0.0 < a < 1.0 and 0.0 < b < 1.0 and 0.0 < c < 1.0 and abs(a + b + c - 1.0) < epsilon:
            return pow(a, 2) * pow(b, 1.5) * pow(c, 1.8)
        return None
    
    
    x_data = np.linspace(0, 1, 101)
    y_data = np.linspace(0, 1, 101)
    z_data = []
    f = 1.0 / pow(3.0, 0.5)
    for y in y_data:
        next_slice = []
        for x in x_data:
            a = 1 - x - f*y
            b = x - f*y
            c = 2*f*y
            z = compute_in_barycentric_coordinates(a, b, c)
            next_slice.append(z)
        z_data.append(next_slice)
    
    
    data = [
        go.Contour(
            x=x_data,
            y=y_data,
            z=z_data,
        )
    ]
    
    
    py.offline.plot(data)
    

    enter image description here

    不过,这仍然是一个解决办法,所以如果你有一个更好的想法,我会很高兴听到你。