Треугольный контур с сеткой - PullRequest
0 голосов
/ 03 апреля 2011

Я пытаюсь воссоздать диаграмму (или просто контурный график будет в порядке) для дистрибутива Дирихле , который находится в Википедии с использованием matplotlib и numpy.У меня проблемы с легкостью создания треугольного контура.Первая проблема заключается в том, что meshgrid не возвращает треугольник точек.Даже если я получу треугольник точек, contourf будет обрабатывать непрямоугольный ввод?

Вот что у меня есть:

#!/usr/bin/env python
from __future__ import division
import matplotlib
matplotlib.use("TkAgg")
matplotlib.rc('text', usetex=True)
matplotlib.rcParams['text.latex.preamble']=r"""\usepackage{amsmath}
"""
import math
import scipy.special

root_three_over_two = np.sqrt(3) / 2

def new_figure():
    # 1.45
    plt.figure(figsize = [2.6, 2.6 * root_three_over_two], dpi = 1200)
    plt.axes([0.05, 0.10, 0.90, 0.90], frameon = False)

xsize = 1.0
ysize = root_three_over_two * xsize
plt.axis([0, xsize, 0, ysize])
resolution = 0.05

R = inclusive_arange(0.0, 1.0, resolution)
x, y = np.meshgrid(inclusive_arange(0.0, 1.0, resolution),
                   inclusive_arange(0.0, 1.0, resolution))
# UNFORTUNATELY x, and y include a lot of points where x+y>1
x = []
y = []
for yy in R:
    x.append(list(inclusive_arange(0.0, 1.0 - yy, resolution)))
    y.append([yy for xx in R])
print x
print y
z = 1 - x - y

# We can use these to convert to and from the equilateral triangle.
M = [[1, 0.5], [0, root_three_over_two]]
Mi = np.linalg.inv(M)

def dirichlet(x, y, z, a, b, c):
    if z < 0:
        return 0
    return x ** (a - 1) * y ** (b - 1) * z ** (c - 1) \
            * math.gamma(a + b + c) \
            / (math.gamma(a) * math.gamma(b) * math.gamma(c))

dirichlet = np.frompyfunc(dirichlet, 6, 1)

for (dirichlet_parm, filename) in [((5.0, 1.5, 2.5), "dir_small.pdf")]:
    new_figure()
    height = dirichlet(x, y, z, *dirichlet_parm)
    M = np.max(height)
    cs = plt.contourf(x, y, height, 50)
    S = sum(dirichlet_parm)
    plt.savefig(filename)

1 Ответ

2 голосов
/ 03 апреля 2011

Вам не нужна прямолинейная сетка для создания контурного графика.Вы можете определить периметр и выполнить триангуляцию Делоне.Координаты, конечно, все еще будут прямолинейными и (кажется) вам нужно будет выполнить преобразование. Этот пример должно быть достаточно для создания 2D контура.Я создал несколько трехмерных поверхностных графиков с не прямоугольным периметром, и вы получите некоторые краевые артефакты, которые могут быть неприглядными.Очень тонкая сетка может улучшить некоторые из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...