I have a graph with vertices labeled by some pairs (a,b).
Can I plot it in such a way that I only see the first component "a" printed over each vertex?
I cannot just relabel, since my map (a,b)->a is not injective.
For a small example, take
G = Graph()
G.add_edge((1,1),(1,2))
The usual G.plot() gives (1,1)---(1,2).
Instead, how to produce only 1---1 ?
Plot a Sage graph with non-injective vertex labals
We describe a slightly tedious workaround, and then
a way to recover our comfort.
New class for vertices
One solution consists in writing a new class for vertices
that inherits from tuple and has a custom __str__ method
that returns a string for only the first entry in the tuple.
class MyVertex(tuple):
r"""
Class for vertices for special plotting of graphs.
Use with tuples, and only the first entry in the tuple
will be used as a vertex label when plotting the graph.
"""
def __init__(self, v):
self.vertex = v
def __str__(self):
return str(self.vertex[0])
Using this to define the vertices of the graph,
we obtain the desired behaviour.
Define a graph and add an edge from (1, 1) to (1, 2):
sage: G = Graph()
sage: G.add_edge(MyVertex((1, 1)), MyVertex((1, 2)))
When plotting the graph, both vertices have the label 1.
sage: G.plot()
Launched png viewer for Graphics object consisting of 4 graphics primitives
When listing the vertices, they still appear fully:
sage: G.vertices()
[(1, 1), (1, 2)]
Using usual graphs
To avoid having to use MyVertex explicitly, we write a graph-plotting
function that creates an intermediate "MyVertex"-style copy of a usual graph
for the sake of plotting.
def plot_graph(G):
r"""
Return a plot of this graph with special vertex labels.
The graph vertices are assumed to be tuples. The plot
uses the first component of each tuple as a vertex label.
"""
E = [(MyVertex(a), MyVertex(b)) for (a, b) in G.edges(labels=False)]
return Graph(E).plot()
Now compare:
sage: G = graphs.Grid2dGraph(3, 4)
sage: G.plot()
Launched png viewer for Graphics object consisting of 30 graphics primitives
sage: plot_graph(G)
Launched png viewer for Graphics object consisting of 30 graphics primitives
Related
I've been trying to query some edge information from an exported network from Openstreet map via this package OpenstreetmapX.jl . However, it appears that some functionality are not directly available. For instance:
Suppose you have a set of links in the form of Vector{Tuple{Int64, Int64}} and you wish to identify their distance, travel time, and class type. I know for the distance you can call something like the following command:
Links = [(301972446, 60649731)
(60649731, 301972446)
(2505989518, 2489651510)
(2489651510, 60649731)
(60649731, 301972503)
(267224410, 2895172669)
(2895172669, 267224410)
(582794232, 582794289)]
# for example to know the distance of the first edge in Link set
distance(map.nodes[links[1][1]],map.nodes[links[1][2]] )
But this is not efficient. Is there anything that directly return the distance, time, and class of each edges? Like:
distance( (582794232, 582794289))
distance( links[1])
time(links[1])
class(links[1])
You will need to access the MapData struct (type ?MapData for details).
Edges
Suppose you have a map:
using OpenStreetMapX
m = get_map_data(joinpath(dirname(pathof(OpenStreetMapX)),"..","test/data/reno_east3.osm");use_cache=false);
All edges are just a Vector
julia> links = m.e[1:2] # sample 2 edges on map
2-element Vector{Tuple{Int64, Int64}}:
(2441017888, 2975020216)
(139988738, 385046328)
Edge classes
Edge classes are also a vector so for the above example you could do m.class[1:2]. Or you could search the id on the edge list:
m.class[findfirst(==((140044645, 140044632)), m.e)]
This yields class number - for translation to class name use OpenStreetMapX.ROAD_CLASSES
Edge lenghts
The distances are available in w matrix, so you can do:
julia> m.w[m.v[140044645], m.v[140044632]]
41.239883456012905
You can also recalculate it using distance function:
julia> distance(m.nodes, [(140044645, 140044632)])
1-element Vector{Float64}:
40.99997118352562
You might notice that this value is slightly lower as the distance function just calculates a stright line distance. However the get_map_data function when parsing the map, by default compresses irrelevant edges (the parameter only_intersections=true), and the distances in w are calculated before compression. In other words w includes curvature of the road and distance is just a straight line.
Travel times
You can get the travel times for edges at once:
julia> OpenStreetMapX.network_travel_times(m)
4220-element Vector{Float64}:
1.5857447369115734
2.3649894625077863
...
Routing
Finally, you can use A-star algorithm to find a distance between any two nodes:
julia> shortest_route(m, 140044645, 140044632)
([140044645, 140044632], 41.239883456012905, 1.4846358044164647)
The returned tuple contains:
the shortest route (nodes)
the distance in meters
the driving time in seconds
using Plots
p_arr = Array{Plots.Plot{Plots.GRBackend}}(undef,10,10);
x=5;
y=10;
p_arr[1,1] = scatter!([x],[y],markersize=5,legend=false,markercolor = :green, showaxis =
false,size=(500,500));
p_arr[1,2] = scatter!([x],[y],markersize=5,legend=false,markercolor = :green, showaxis =
false,size=(500,500));
this is a very simple code of storing a point plot into an array. I just want to know how to change the x and y coordination for this point by the object it is stored in ?. in other words, I want to set x and y values by the object itself.
is there a better way to do this.
I am new to julia and I do not know where to search
While I'm not quite sure what you'll need for your end use case, storing an array of Plots.jl Plots.Plots has a lot of overhead and will not make it at all easy to modify the underlying points.
One approach that could be dramatically simpler would be to work directly with an array of Points instead. For example, let us first define:
struct Point{T}
x::T
y::T
end
then you have a type which can represent just an x-y point by itself. You can make an array of them:
p_arr = Array{Point{Int64}}(undef, 10, 10) # uninitialized, Int64
or to make this a little more interesting, an array of random points:
julia> p_arr = Point.(rand(10,10), rand(10,10))
10×10 Matrix{Point{Float64}}:
Point{Float64}(0.561232, 0.39038) … Point{Float64}(0.0564275, 0.851144)
⋮ ⋱
Point{Float64}(0.804435, 0.0717767) Point{Float64}(0.110489, 0.670536)
If you want to be able to plot these, then let's define some functions to let Plots.jl know how to plot our Point type:
using Plots
import Plots.scatter
scatter(p::Point, args...; kwargs...) = scatter([p.x], [p.y], args...; kwargs...)
scatter(p::AbstractArray{<:Point}, args...; kwargs...) = scatter(map(p->p.x, p), map(p->p.y, p), args...; kwargs...)
# You can do the same for `scatter!` if you want that version too
then you can write
scatter(p_arr, label="", framestyle=:box)
to obtain a plot that looks like:
(note that each column gets its own series in Plots.jl, hence the multiple colors; call vec on your matrix of Points first if you don't want that)
Now, say you want to move one of those points. Let's say the first one:
julia> p_arr[1,1] = Point(5.0, 10.0)
Point{Float64}(5.0, 10.0)
Then plotting again
scatter(p_arr, label="", framestyle=:box)
will yield
I have data in the form of a list of tuples (x,y,z) with no particular ordering on the (x,y) values. I want to make a color plot in the x-y plane where z is represented by a color, using the PyPlot function
pcolor
The issue is this function accepts data in the format arr_x,arr_y,image where arr_x and arr_y are 1D arrays and image is a 2d Array such that image[i,j] corresponds here to the z value for x=arr_x[i],y=arr_y[j].
Is there a simple way to do this (without constructing the 2D array image, which would be annoying).
Are you looking for scatter?
using Plots, Unzip # Unzip to go from list of tuples to tuple of lists
data = [(randn(), randn(), randn()) for _ in 1:200] # list of (x,y,z) tuples
x, y, z = unzip(data) # get vectors out of the tuple
scatter(x, y, zcolor=z)
will output
Disclaimer: I have no experience with sage, programming or any computer calculations.
I want to expand a polynomial in Sage. The input is a factored polynomial and I need a certain coefficient. However, since the polynomial has 30 factors, my computer won't do it.
Should I look for somebody with a better computer or are 30 factors simply too much?
Here is my sage code:
R.<x_1,x_2,x_3,x_4,x_5,x_6,x_7,x_8,x_9,x_10,x_11,x_12> = QQbar[]
f = (x_1-x_2)*(x_1-x_3)*(x_1-x_9)*(x_1-x_10)*(x_2-x_3)*(x_2-x_10)*(x_2-x_11)*(x_2-x_12)*(x_3-x_4)*(x_4-x_11)*(x_4-x_5)*(x_4-x_6)*(x_4-x_11)*(x_5-x_6)*(x_5-x_10)*(x_5-x_11)*(x_5-x_12)*(x_6-x_7)*(x_6-x_12)*(x_7-x_9)*(x_7-x_8)*(x_7-x_12)*(x_8-x_9)*(x_8-x_10)*(x_8-x_11)*(x_8-x_12)*(x_9-x_10)*(x_10-x_11)*(x_10-x_12)*(x_11-x_12);
c = f.coefficient({x_1:2,x_2:2,x_3:2,x_4:2,x_5:2,x_6:2,x_7:2,x_8:2,x_9:2,x_10:5,x_11:5,x_12:5}); c
Just some background. I'm trying to solve an instance of list edge colouring with the combinatorial Nullstellensatz.
https://en.wikipedia.org/wiki/List_edge-coloring
Given a graph G=(V,E) we associate a variable x_i with each vertex i in V. The graph monomial eps(G) is defined as the product \prod_{ij \in E} (x_i-x_j). (Note that we fixed an orientation of the edges, but that's not important here.)
Suppose that there are lists of colours assigned to the vertices, such that the vertex i has a list of size a(i). Then, by the combinatorial Nullenstellensatz there is a colouring from those lists (i.e. each vertex receives a colour from its list and two adjacent vertices do not receive the same colour), if the coefficient of \prod_{i \in V} x_i^{a(i)-1} is non-zero in eps(G).
I want to apply this to the line graph of the graph G(M) with incidence matrix:
M = Matrix([0,0,0,3,3,0,3],[0,0,0,0,3,3,3],[0,0,0,3,0,3,3],[0,0,0,3,3,0,3],[3,0,3,0,0,0,6],[3,3,0,0,0,0,6],[0,3,3,0,0,0,6],[3,3,3,6,6,6,0])
(Here the size of the lists are indicated by the integers).
I believe that it takes so long because your coefficients are in QQbar, and arithmetic in QQbar is much slower than over QQ, for example. Is there a good reason for not using QQ?
If I change the coefficient ring to QQ, Sage fairly quickly tells me that c is 0:
sage: R.<x_1,x_2,x_3,x_4,x_5,x_6,x_7,x_8,x_9,x_10,x_11,x_12> = QQ[]
sage: f = (x_1-x_2)*(x_1-x_3)*(x_1-x_9)*(x_1-x_10)*(x_2-x_3)*(x_2-x_10)*(x_2-x_11)*(x_2-x_12)*(x_3-x_4)*(x_4-x_11)*(x_4-x_5)*(x_4-x_6)*(x_4-x_11)*(x_5-x_6)*(x_5-x_10)*(x_5-x_11)*(x_5-x_12)*(x_6-x_7)*(x_6-x_12)*(x_7-x_9)*(x_7-x_8)*(x_7-x_12)*(x_8-x_9)*(x_8-x_10)*(x_8-x_11)*(x_8-x_12)*(x_9-x_10)*(x_10-x_11)*(x_10-x_12)*(x_11-x_12)
sage: c = f.coefficient({x_1:2,x_2:2,x_3:2,x_4:2,x_5:2,x_6:2,x_7:2,x_8:2,x_9:2,x_10:5,x_11:5,x_12:5})
sage: c
0
I'm a complete beginner at the Z notation. I need to represent a graph type in Z. The idea I have is to use an incidence matrix so that I can traverse freely between nodes and edges with ease.
The only problem is, I don't know how to specify the incidence matrix in Z. I would think that I need a 2D array, but looking through the reference material available for the Z notation, arrays are commonly represented using seq. Is there another way to specify a multi dimensional array?
Thanks in advance.
I think a relation between nodes would be a better representation for an incidence matrix. Lets assume that we have a type node:
[node]
Then a graph could be modelled as a relation between nodes:
graph : node \rel node
This would be a directed graph because there could be an edge n1->n2 in graph but not n2->n1. If you need an undirected graph you can add a further restriction:
graph\inv = graph
(The inverse of graph is the same as graph, i.e. if n1->n2 in graph, then n2->n1 must be in graph, too.)
If you really want to model an incidence matrix as a multidimensional array, you can define a function that maps from a position in the array to an integer, e.g.:
matrix: (node \cross node) \fun {0,1}
The relation between the two representations can be expressed as:
\forall n1,n2:node # (n1,n2)\in graph \iff graph( (n1,n2) ) = 1