Tenho uma lista de 3 tuplas que representam um conjunto de pontos no espaço 3D. Quero traçar uma superfície que cubra todos esses pontos.
A plot_surface
função no mplot3d
pacote requer que os argumentos X, Y e Z sejam matrizes 2d. É plot_surface
a função certa para plotar a superfície e como faço para transformar meus dados no formato necessário?
data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
python
numpy
matplotlib
surface
Graddy
fonte
fonte
Respostas:
Para superfícies é um pouco diferente de uma lista de 3 tuplas, você deve passar uma grade para o domínio em matrizes 2d.
Se tudo o que você tem é uma lista de pontos 3d, ao invés de alguma função
f(x, y) -> z
, então você terá um problema porque existem várias maneiras de triangular essa nuvem de pontos 3d em uma superfície.Aqui está um exemplo de superfície lisa:
fonte
f(x,y) -> z
fornece mais informações do que simplesmente usar uma abordagem de lista como o OP inicialmente tinha.plot_trisurf
vez disso. Mas, como mencionei, não é trivial porque você precisa triangular a superfície e há várias soluções. Como exemplo básico, considere apenas os 4 pontos dados por (0, 0, 0,2), (0, 1, 0), (1, 1, 0,2), (1, 0, 0). Visto de cima, parece apenas um quadrado com uma ligeira dobra. Mas ao longo de qual diagonal a "dobra" ocorre? É a diagonal "alta" em 0,2 ou a diagonal "baixa" em 0? Ambas são superfícies válidas! Portanto, você precisa escolher um algoritmo de triangulação antes de ter uma solução bem definida.projection='3d'
na chamadafig.add_subplot
ficará indisponível sem essa importação.Você pode ler os dados direto de algum arquivo e traçar
Se necessário, você pode passar vmin e vmax para definir a faixa da barra de cores, por exemplo
Seção de bônus
Eu queria saber como fazer alguns gráficos interativos, neste caso com dados artificiais
fonte
Acabei de encontrar o mesmo problema. I se uniformemente espaçadas de dados que é, em 3 1-matrizes d, em vez das matrizes de 2-D, que
matplotlib
'splot_surface
necessidades. Meus dados estavam em umpandas.DataFrame
então aqui está omatplotlib.plot_surface
exemplo com as modificações para plotar 3 arrays 1-D.Esse é o exemplo original. Adicionar este próximo bit cria o mesmo gráfico de 3 arrays 1-D.
Aqui estão os números resultantes:
fonte
Só para entrar na conversa, Emanuel tinha a resposta que eu (e provavelmente muitos outros) estamos procurando. Se você tiver dados espalhados em 3D em 3 arrays separados, o pandas é uma ajuda incrível e funciona muito melhor do que as outras opções. Para elaborar, suponha que x, y, z são algumas variáveis arbitrárias. No meu caso, foram c, gama e erros porque estava testando uma máquina de vetores de suporte. Existem muitas opções possíveis para plotar os dados:
Gráfico de wireframe dos dados
Dispersão 3D dos dados
O código é parecido com este:
Aqui está o resultado final:
fonte
verifique o exemplo oficial. X, Y e Z são de fato matrizes 2d, numpy.meshgrid () é uma maneira simples de obter a malha 2d x, y dos valores 1d xey.
http://matplotlib.sourceforge.net/mpl_examples/mplot3d/surface3d_demo.py
aqui está uma maneira pythônica de converter suas 3-tuplas em arrays 3 1d.
Aqui está a triangulação mtaplotlib delaunay (interpolação), ela converte 1d x, y, z em algo compatível (?):
http://matplotlib.sourceforge.net/api/mlab_api.html#matplotlib.mlab.griddata
fonte
No Matlab fiz algo semelhante usando a
delaunay
função emx
,y
coords only (não thez
), e plotando comtrimesh
outrisurf
, usandoz
como a altura.SciPy tem a classe Delaunay , que é baseada na mesma biblioteca QHull subjacente que a
delaunay
função do Matlab , então você deve obter resultados idênticos.A partir daí, deve haver algumas linhas de código para converter este exemplo de Plotagem de polígonos 3D no python-matplotlib no que você deseja alcançar, pois
Delaunay
fornece a especificação de cada polígono triangular.fonte
ax.plot_trisurf(..)
.Apenas para adicionar mais algumas idéias que podem ajudar outras pessoas com problemas de tipo de domínio irregular. Para uma situação em que o usuário tem três vetores / listas, x, y, z representando uma solução 2D onde z deve ser plotado em uma grade retangular como uma superfície, os comentários 'plot_trisurf ()' de ArtifixR são aplicáveis. Um exemplo semelhante, mas com domínio não retangular é:
O código acima produz:
No entanto, isso pode não resolver todos os problemas, especialmente quando o problema é definido em um domínio irregular. Além disso, no caso em que o domínio tem uma ou mais áreas côncavas, a triangulação delaunay pode resultar na geração de triângulos espúrios exteriores ao domínio. Em tais casos, esses triângulos errados devem ser removidos da triangulação para obter a representação correta da superfície. Para essas situações, o usuário pode ter que incluir explicitamente o cálculo de triangulação delaunay para que esses triângulos possam ser removidos programaticamente. Nessas circunstâncias, o código a seguir pode substituir o código de plotagem anterior:
Os gráficos de exemplo são fornecidos abaixo, ilustrando a solução 1) com triângulos espúrios e 2) onde eles foram removidos:
Espero que o exposto acima possa ajudar as pessoas com situações de concavidade nos dados da solução.
fonte
Não é possível fazer diretamente uma superfície 3D usando seus dados. Eu recomendaria que você construísse um modelo de interpolação usando algumas ferramentas como o pykridge . O processo incluirá três etapas:
pykridge
X
eY
usandomeshgrid
Z
Tendo criado sua grade e os
Z
valores correspondentes , agora você está pronto para prosseguirplot_surface
. Observe que, dependendo do tamanho dos seus dados, ameshgrid
função pode ser executada por um tempo. A solução alternativa é criar amostras com espaçamento uniforme usando os eixosnp.linspace
forX
e eY
, em seguida, aplicar a interpolação para inferir osZ
valores necessários . Nesse caso, os valores interpolados podem ser diferentes do originalZ
porqueX
eY
foram alterados.fonte