port networkx graph to graphviz without pygraphviz - networkx

I am working in Python 3 on a windows machine and despite many efforts have not been able to get pygraphviz installed. Separate discussion.
I have networkx and graphviz modules...Is there a paradigm for building network graphs in networkx and extracting to a graphviz format for display that does not use pygraphviz?
It seems all the relevant functionality in drawing.nx_agraph and nx_agraph requires pygraphviz but I have gotten accustomed to using networkx and like the functionality therein. In the documentation for networkx it even says they are focusing on the development of graph objects and not on the actual display.

I know this is an old question, but I was looking for the same thing: How to get dot notation from a graph in NetworkX?
(If you are only interested in the answer, skip this paragraph. I actually wanted to display a NetworkX multigraph, but even though NetworkX is powerful python library for manipulation of networks and graphs, it has fairly limited options when it comes displaying (rendering) graphs and networks. NetworkX uses Matplotlib to provide basic functionality for visualizing graphs, which doesn't have the option for visualizing multigraph. NetworkX is not intended for visualizing graphs so in NetworkX documentation they recommend using some of graph visualization tools, Cytoscape, Gephi, Graphviz. All of this tools have some kind of python interfaces but the best one (easiest and simplest to use) is graphviz which supports the DOT language of the Graphviz drawing software. Visualizing graphs in graphviz is very simple and convenient, you can use one short line such as graph.view() which by default creates a PDF file and opens it in your system's default PDF viewer, but you can also view and create image files such as SVG and PNG. So it would be ideal to convert NetworkX graph to graphviz graph and to do that you need to convert NetworkX graph to DOT notation which can then be read by graphviz.)
Solution by Aric is simple and works for printing out DOT notation of graph, but is kind of a hack and also in my case, I need to save DOT notation in string variable so I can use it to create a graph in graphviz from that DOT notation.
networkx.drawing.nx_pydot.write_dot(source) is a function that creates DOT format and saves it to a path (file handle). Code of this function is:
#open_file(1, mode='w')
def write_dot(G, path):
P = to_pydot(G)
path.write(P.to_string())
return
And this gives us the solution for answer:
from networkx import path_graph
from networkx.drawing.nx_pydot import to_pydot
G = path_graph(4)
dot = to_pydot(G).to_string()
print(dot)
Function to_pydot (source) uses pydot library to create pydot.Dot object which has to_string (source) method that returns string representation of graph in DOT language.
P.S.:
To render a DOT source code in graphviz you can do something like this:
from graphviz import Source
src = Source(dot) # dot is string containing DOT notation of graph
src.view()
P.P.S.:
Two following pictures show difference when you use Matplotlib (left side of image) and graphviz (right side of image) to visualize graph networkx.margulis_gabber_galil_graph(3):

You can use pydot (https://pypi.python.org/pypi/pydot) as a pure Python alternative to PyGraphviz
In [1]: import networkx
In [2]: import sys
In [3]: G = networkx.path_graph(4)
In [4]: networkx.drawing.nx_pydot.write_dot(G,sys.stdout)
strict graph {
0;
1;
2;
3;
0 -- 1;
1 -- 2;
2 -- 3;
}

Related

How to visualize HeteroData pytorch geometric graph with any tool?

Hello what is a good way to visualize a pyg HeteroData object ?
(defined similarly: https://pytorch-geometric.readthedocs.io/en/latest/notes/heterogeneous.html#creating-heterogeneous-gnns )
I tried with networkx but I think it is restricted to homogeneous graph ( it is possible to convert it but it is much less informative).
g = torch_geometric.utils.to_networkx(data.to_homogeneous(), to_undirected=False )
Did anyone try to do it with other python lib (matplotlib) or js (sigma.js/d3.js)?
Any docs link you can share?
I have done the following:
import networkx as nx
from matplotlib import pyplot as plt
from torch_geometric.nn import to_hetero
g = torch_geometric.utils.to_networkx(data.to_homogeneous())
# Networkx seems to create extra nodes from our heterogeneous graph, so I remove them
isolated_nodes = [node for node in g.nodes() if g.out_degree(node) == 0]
[g.remove_node(i_n) for i_n in isolated_nodes]
# Plot the graph
nx.draw(g, with_labels=True)
plt.show()
However, it's true that it was "flattened" to a homogeneous, while it'd be more interesting to, for example, use different colors for different types of nodes.

How can I print a figure to a pdf file with embedded greek letters or formulas in MATLAB?

I cannot find a solution to print a figure with embedded Greek letters using the print function (or the File Exchange function export_fig() of Yair Altman).
While this functionality was available in earlier matlab releases (e.g. R2016a), the following code does not produce the desired result with version R2018a:
figure()
rng = 0:0.01:2;
plot(rng, sin(rng.*pi()))
text(1, 0.6, 'sin of {\alpha}')
print('simple_test_p', '-dpdf')
% export_fig('simple_test_e','-pdf', '-transparent')
While the text before '{\alpha}' is embedded in the resulting pdf file, alpha itself appears to be an image rather than an embedded font (see image).
I tried several different fonts to exclude the possibility of a missing default font (besides double-checking the font folder). Moreover, I used both latex and tex interpreters. Nevertheless, none of these procedures worked.
If this problem cannot be solved with Matlab, is there any other way to get a pdf file with embedded Greek letters and mathematical formulas?
I very much appreciate your help. Thank you in advance.
MATLAB uses Unicode text everywhere. You should be able to simply do:
text(1, 0.6, 'sin of 𝛼')
If you can't type the Greek letters, you can always search for them on Google* and copy-paste them. I found the above here.
*or whatever your favorite search engine is.
Or just use matplotlib, which gets along well with unicode:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(10000)
y = np.sin(np.pi * x * 0.001)
plt.plot(x, y)
plt.ylabel(u"\u03B1")
plt.xlabel('β')
plt.savefig(r'<insert your path here>/sinewave.pdf')
plt.show()

How to use a MATLAB file as a file source in GNU Radio

I designed a filter and applied it to a random noise signal using SPTool in MATLAB. My noise signal was x = (1/sqrt(2))*(randn(1024,1)+j*randn(1024,1))
Once I've applied my filter to this noise signal, how can I take that filtered signal and use it as a file source in GNU Radio Companion (which I will connect to QT GUI Frequency Sink)? I tried exporting the signal using SPTool but I'm unsure what file extension I can use for GNU Radio. Thanks in advance.
Use fwrite with the right precision parameter that gives you float 32 binaries.
Or just use the octave/Matlab scripts in GNU Radio that do exactly that: write raw binary data. For more info, see the GNU Radio FAQ entry on the file format. (On https://wiki.gnuradio.org )
If you have a .mat file, another option is to use a Vector Source block putting in the Vector field:
loadmat('filename')['varname'].flatten()
For this to work you need to:
import numpy
from scipy.io import loadmat
Note this loads the whole file in memory (but you can specify which variables to load from the file if that's a problem). Also if the data is stored as float64 (as is the norm in Matlab) then I think there could be some rounding/truncation since GR Vector Source expects float32 (don't know enough about how SWIG handles that).

How can I visualise results of a simulation in OpenModelica as animation?

I want to know how I can visualise the results of a Modelica simulation in the form of an animation.
Imagine I have a simple simulation as below:
model test
//parameters
parameter Real m_1 = 1;
parameter Real m_2 = 10;
parameter Real K_c = 100000;
//variables
Real x_1;
Real v_1;
Real x_2;
Real v_2;
Real f_1;
Real f_12;
initial equation
x_1 = 0;
v_1 = 0;
x_2 = 0.2;
v_2 = 0;
equation
v_1 = der(x_1);
m_1 * der(v_1) = f_1 - f_12;
v_2 = der(x_2);
m_2 * der(v_2) = f_12;
f_12 = if x_2 >= x_1 then 0 else K_c * (x_1 - x_2);
f_1 = 1;
end test;
(it is actually a very simple elastic collision)
and I have part1.obj and part2.obj (or other possible formats rather than .obj), designed in other CAD software, which I want to import and assign to x_1 and x_2 and then animate. OpenModelica 1.11.0 is already installed on Ubuntu using these instructions.
What I have found so far and the problems I have encountered:
From this page I have learned that Modelica3D should also be installed. However I couldn't find this library using apt or aptitude.
I found the installation instructions for windows and mac on OpenModelica official website, but no Ubuntu (or other Linux distro) one.
I have also found this github repo which claims to be a regularly maintained mirror of the original distribution, however the latest commit is for 2 years ago! Not to mention that the original website is dead.
Do I still need to install this library separately or it has already been integrated into the latest stable OpenModelica release? if yes how can I install it? what other libraries/packages might be needed?
Edit: It seems that Modelica3D has been depreciated (same for OMVisualize). Now the ModelicaServices is being used for animation. more information here
This post gives a very simple example of animating using Wolfram SystemModeller. When I open it into the OpenModelica, it does compile and shows the results. I tried exporting the model as FMU and XML and then use animation icon from the top menus to import the model.
but when tried to import the .mat file I got the error:
Scripting Error
Could not find the visual XML file /tmp/OpenModelica_user/OMEdit/SimpleCarModel_visual.xml.
Is this example compatible with OpenModelica? and if yes what is the problem and how I can solve it? (you can also download the example from this Github gist)
Edit: This example is compatible with OpenModelica. I was doing it wring. I had to choose the "simulate with Animation" instead of "Simulate". I still can't assign an external CAD object to the simulation and a cylinder is being shown instead.
I also tried to learn using OMShell scripting to run the Modelica3D example from this page. However it seems that the code is wrong because I get many errors running it in my OMShell.
One of the linked websites has mentioned that it is possible to use blender for animated results however the author hadn't succeed to do so. I would appreciate if you could help learn this in simple and clear steps.
Visualizing CAD-files is currently only possible for .stl and .dxf.
You can specify the URI of your CAD-file in the shapeType-parameter of your shape. Please use the following notation:
"modelica://packageName/relativePath/To/Your/CADfile.stl"
It is also possible to set the absolute path in the *_visual.xml that has been generated with your simulation results(and should be in the same directory if you want to load simulation from OMEdit).
If you want to move your animation shapes, simply assign variables to i.e. the position vector
r = {x,0,0};

(De)Serialize/deserialize MATLAB graph objects from and to Python

MATLAB has a representation of a directed/undirected graph. I would like to deserialize a graph with many node and edge attributes serialized via MATLAB's save function into Python. I know about scipy.io.loadmat and h5py's File (for MATLAB v7.3 saved files), but neither seems to produce a representation in Python that actually holds intelligible vertex/edge data.
How do I do this? I'm concerned with this and the inverse operation, i.e writing an object from Python to a format MATLAB load can read. Is there a bytewise data description of a serialized MATLAB object and/or a Graph looks like somewhere?
For example, in MATLAB I could:
s = [1 1 2 2 3];
t = [2 4 3 4 4];
G = digraph(s,t);
G.Edges.Rand = rand(size(G.Edges)); % Add an edge attribute
G.Nodes.Val = rand(size(G.Nodes)); % Add a node attribute
save('loadmat.mat', 'G'); % Readable by scipy.io.loadmat
save('h5py.mat', 'G', '-v7.3'); % Readable by h5py.File
then, in Python I could read these
from scipy.io import loadmat
G0 = loadmat('loadmat.mat')
from h5py import File
G1 = File('h5py.mat')
Neither seems to give me the vertex/edge data or am I just missing it?
Thanks
The lengthy but certain way to do this is to define a schema for G in something like Google Protocol Buffers. With that schema you can automatically generate serialiser source code for Python and Java (that you could use in Matlab). This would allow you exchange G between Matlab and Python, or indeed between anything else.
You would probably have to hand write code to translate between how G is stored in Matlab and however protoc chose to represent in Java the message you had defined in the schema. You won't (I'm fairly certain) be able to do Ggpb = G. If both Java and Matlab supported type reflection then you could probably write something neat to do it automatically...
The digraph object is an user-defined object type, not one of the fundamental MATLAB types; no wonder python doesn't understand it. Please note that even MATLAB will not understand the saved object layout if it doesn't have a working definition of the saved object's class, accessible in the path.
You might want to save the adjacency matrix:
A = full(adjacency(G));
save('adjacency.mat', 'A');
or the incidence matrix:
I = full(incidence(G));
save('incidence.mat', 'I');
whatever suits you better.
Late edit
Another way is to force the object to become a POD (plain old data) that has better chances to be understood by loadmat:
S = struct(G);
save('pod_digraph.mat', 'S');
But mind that you'll have access to all information; the dependent properties will be saved as such; you'll need to recreate the class' interface by yourself in order to maintain consistency (e.g. the adjacency matrix and the incidence matrix can be both constructed on-the-fly from the same internal information, which may look like neither of them). Also, one cannot convert a POD to the original object unless the constructor knows how to do this.