I have a Graph in Python like this one:
# Each element is a tuple with coordinates (x,y,z).
# The index is the id of the vertex
vertexList = [(0,0,0),(1,0,0),(1,1,0),(0,1,0),
(0,0,1),(1,0,1),(1,1,1),(0,1,1)]
# Each element is a tuple with the vertex-ids and a weight (vertexId1, vertexId2, weight)
edgeList = [(0,1,1), (1,2,1), (2,3,1), (3,0,1),
(0,4,1),
(4,5,1), (5,6,1), (6,7,1), (7,4,1)]
graph = (vertexList, edgeList)
This is a small example. The application I wrote uses graphs with about 100 vertexes and 300 edges.
I would like to visualize this with python, preferably with a library which is available for Ubuntu. It would be great if it were possible to move the graph in the 3D-visualisation.
What I've done so far
At the moment I use UBIGRAPH. The visualization and interaction is very good, but I can't specify coordinates for the vertexes:
def visulizeGraph(Graph):
vertexList, edgeList = Graph
server_url = 'http://127.0.0.1:20738/RPC2'
server = xmlrpclib.Server(server_url)
G = server.ubigraph;
G.clear()
for identifier, vertex in enumerate(vertexList):
G.new_vertex_w_id(identifier)
for vertex1, vertex2, weight in edgeList:
x1, y1, z1 = vertexList[vertex1]
x2, y2, z2 = vertexList[vertex2]
G.new_edge(vertex1, vertex2)
matplot
I've found matplotlib, but its very big. I didn't find an example which does what I like, but I might have missed it. Its available for Ubuntu.
vtk
The same problem as with matplot. If you could give me some working examples it might be the best solution.
When you looked at matplotlib, did you see mplot3d? This may be what you require.
MPlot3D
If not, I'm sorry I probably can't help any more than that.
I've not used this myself yet (beyond running example scripts) but mayavi2 looks promising. It comes bundled with the enthought python distribution.
Also, a little of topic as it's not in your question, but networkx is pretty nice if your working with graphs in python.
Hope this helps a bit.
Related
I am trying to learn if in Python or R, there exist within the graph-theory related modules features that would enable one to start from a degree distribution (or expressed as a sequence once we set the number of vertices), and generate (random) graphs that satisfy the prescribed degree sequence.
As an example, we might be given the following distribution: p=(0.179,0.49,0.34) which are the probabilities of degree values 1,2 and 3 respectively. So we can set the number of vertices, n=500, map p to a degree sequence deseq list: filled with 0.179*n times of 1, and so on for the rest.
Any pointers towards previously discussed cases for such problems or library suggestions would be very helpful.
Here's an attempt to answer my own question after having learned how to use igraph in R and Python for generating the desired type of graphs.
In R:
For the purposes of this example, let's suppose the following degree sequence: total nodes n=20, 5,10 and 5 nodes with degrees 1,2, and 3 respectively. We create the degree sequence using c() and rep(). Then we'll use sample_degseq() from igraph to generate a graph corresponding to the above degree sequence. Then we'll draw its degree histogram to sanity check.
First install and call the igraph module in the R console using:
install.packages("igraph")
library(igraph)
Now we can proceed as described:
degreels <- c(rep(1,5),rep(2,10),rep(3,5))
graph <- sample_degseq(degreels, method="simple")
degreehist <- hist(degree(graph))
is.connected(graph)
In Python:
Now let's do the exact same thing with the igraph module in Python:
To install see here.
import igraph as ig
import matplotlib.pyplot as plt
degcounts = [5,10,5]
degreels = []
for i in range(len(degcounts)):
degreels += degcounts[i]*[i+1]
graph = ig.GraphBase.Degree_Sequence(degreels,method="simple")
plt.hist(graph.degree())
plt.show()
and the obtained histogram:
I don't know how much have you already researched on the topic but there is a pretty wellknown package in R and module in Python called igraph. It might have what you seek for.
For Python, the networkx package also provides what you are looking for.
In particular, the functionalities regarding random graphs from degree sequences (e.g. configuration_model with the idea from #Alex_6's comment) might be helpful.
I am trying to remove the border of node vertices in igraph, but I can't find a way. I found many references on google that in R, you can change this attribute:
vertex.frame.color
but in igraph for python, I could not find a way. Any ideas?
Thanks
If you look into the documentation, it's done in basically the same way. Example:
import igraph
g = igraph.Graph([(0,1), (0,2), (2,1)])
igraph.plot(g, vertex_frame_color='red')
I'm wondering how, given contour lines generate trough the contour() function from Matplotlib, one can iterate to each level to get its vertices. I know that I can iterate over the paths with this code:
cs = plt.contour(x, y, (f - g))
for collection in cs.collections:
paths = collection.get_paths()
for path in paths:
print(path.vertices.shape)
plt.show()
However, how could I find the level of each path, or directly iterate over each level of a contour?
Thank you.
This is maybe very clear to you, but I would like to highlight that care is needed with the proposed code.
See also:
https://github.com/matplotlib/matplotlib/issues/367
Each path may be just an array of vertices corresponding to a single open or closed polygon, which is what most people expect, but a path may also correspond to 2 or more polygons if the member codes is set to indicate at which indices the polygons start. Naive use of the paths may not be what is wanted; often the use of path.to_polygons() is better.
In short, this code will work as expected on most simple examples but might cause problems for complex cases. A better alternative is:
cs = plt.contour(x, y, (f - g))
for collection in cs.collections:
for path in collection.get_paths():
print path.to_polygons()
I am creating a toolset for creating nurbs curves/surfaces inside maya using python.
I have a set of dictionaries that include cvPositions, knots, form etc. each of which describe a preset 3d shape (cube, circle, pyramid etc).
I also have a 3d matrix stored in the nodes metadata that is used as an offset for the shape. This allows you to scale/move/rotate the shape without moving the transform.
The problem is in the way I am applying this matrix is very slow:
First I will create a new (edit)transform at the position of the (orig)transform containing the curves.
Next I will transfer cv positions in world space from (orig)transform to (edit)transform
Next i will move the (edit)transform into the matrix position.
Finally I will transfer the cvPositions back to the (orig)transform
When creating hundreds of shapes, this is becoming prohibitively slow...
Can someone describe a mathematical way to apply a matrix to a set of 3d points?
Perhaps using one of the math modules or numpy?
Alternatively,
Is there a way using OpenMaya api functions to do this? Perhaps with MPointArray? This is as far as I have gotten on that front:
crv = OpenMaya.MFnNurbsCurve( self.dagPath )
cvs = OpenMaya.MPointArray()
space = OpenMaya.MSpace.kWorld
crv.getCVs(cvs, space)
positions = []
for i in range(cvs.length()):
pt = cvs[i]
positions.append( (pt[0], pt[1], pt[2]) )
The easiest method is to use pymel's built-in versions of points and matrices (pymel is built in to maya 2011+). The math types are in pymel.datatatypes; here's an example of transforming a point by a matrix in pymel:
import pymel.core as pm
pt = pm.datatypes.Point(0,0,0)
mt = pm.datatypes.Matrix(1,0,0,0, 0,1,0,0, 0,0,1,0, 5,5,5,1 )
moved = pt * mt
print moved
# [5,5,5]
Pymel points and matrices will let you do your algorithm. The math is going to be done in the API but the Python <> C++ conversions may still make it feel pretty slow for big data.
It sounds like you're basically re-creating 'freeze transforms' followed by 'zero pivots'. Maybe you should try that as an alternative to doing this in python math...
I have a pet project to create images of maps, where I draw the roads and other stuff over a contour plot of the terrain elevation. It is intended to plan mountain bike routes (I have made some vectorial drawings by hand, in the past, and they work great for visualization).
Currently, I download Digital Elevation Model, in GeoTIFF, from here:
http://www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar
and then create the plot with GDAL and Matplotlib contourf function:
from osgeo import gdal
import matplotlib
import matplotlib.pyplot as plt
from pylab import cm
import numpy
f = 'rs.tif'
elev = gdal.Open(f)
a = elev.GetRasterBand(1).ReadAsArray()
w = elev.RasterXSize
h = elev.RasterYSize
print w, h
altura = (0.35, 0.42)
largura = (0.70, 0.82)
a = a[int(h*altura[0]):int(h*altura[1]),
int(w*largura[0]):int(w*largura[1])]
cont = plt.contourf(a, origin='upper', cmap=cm.gist_earth, levels=numpy.arange(0,1000,20))
plt.title('Altitudes - max: %d m; min: %d m' % (numpy.amax(a), numpy.amin(a)))
plt.show()
Which gives:
The problem is that contour lines are "white", and generate some visual pollution, which is undesired since I want to plot roads and rivers later.
So, I am trying to modify the way contourf create these lighter lines, either via parameter setting, or via hack (changing source code), similar to the one proposed here:
How to format contour lines from Matplotlib
Also, if anyone knows how to generate such a map in a more elegant way, using other libraries, I would appreciate the tip very much!
Thanks for reading.
I finally found a proper solution to this long-standing problem (currently in Matplotlib 3), which does not require multiple calls to contour or rasterizing the figure.
Note that the problem illustrated in the question appears only in saved publication-quality figures formats like PDF, not in lower-quality raster files like PNG.
My solution was inspired by this answer, related to a similar problem with the colorbar. A similar solution turns out to solve the contour plot as well, as follows:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(123)
x, y = np.random.uniform(size=(100, 2)).T
z = np.exp(-x**2 - y**2)
levels = np.linspace(0, 1, 100)
cnt = plt.tricontourf(x, y, z, levels=levels, cmap="ocean")
# This is the fix for the white lines between contour levels
for c in cnt.collections:
c.set_edgecolor("face")
plt.savefig("test.pdf")
Here below is an example of contours before the fix
And here below is the same figure after the above fix
The solution to the problem, despite not being a real solution, but more a workaround, is simple: Just repeat the same contourf command and this will magically get rid of spurious contours.
As stated by the OP, spurious contours show up when doing contour fill (contourf) with intervals too close to each other. We can reproduce this behavior by setting a very large number of intervals, e.g.:
plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # 2001 intervals
This gives us as output:
The thin spurious contours obviously affect the net color of the contour fill.
If you do the command twice:
plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # Not once,
plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # but twice!
gives me:
Much better now. Here's the finest one, with 3 successive contourf commands:
I can't see any thin contours anymore! Unfortunately, this may slow down your scripts significantly, depending on array size and number of contour intervals. The spurious contours stand out more if more contour intervals are used. What usually works best for me is to use 50 to 100 contour intervals, and do the contourf twice.
Notice that the version of matplotlib I am using is not the latest one. This issue might have been resolved in version 1.1.0. If it has, please let me know.
Python 2.7.1 |EPD 7.0-2 (32-bit)| (r271:86832, Nov 29 2010, 13:52:51)
In [1]: matplotlib.__version__
Out[1]: '1.0.1'
The posted solution did not work for me with alpha set to <1, but I found the answer in this solution: Matplotlib Contourf Plots Unwanted Outlines when Alpha < 1
Adding the argument antialiased=True solved the issue for me.
Try adding the kw argrument to plt.contourf(...) call: either lw=0 or ls=None.
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf