daily pastebin goal
53%
SHARE
TWEET

Sociogram--graph_plotly.jl

BenjaminLind May 10th, 2014 442 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #####
  2. ### The code below is written by Benjamin Lind under CC: BY-NC-SA 3.0
  3. ### If you use or develop this code, please provide proper attribution.
  4. ### You may contact me at lind.benjamin//at//gmail//d0t//com
  5. ### You may also find me @benjaminlind on Twitter
  6. #####
  7.  
  8. # To use this code, uncomment the next line and enter it into Julia:
  9. # download("http://pastebin.com/raw.php?i=ymrmxPtU", "Sociogram--graph_plotly.jl"); include("Sociogram--graph_plotly.jl"); rm("Sociogram--graph_plotly.jl")
  10.  
  11. using Graphs, Color, Plotly
  12.  
  13. #####
  14. ### Sociogram plotting in Plotly using the Graphs library in the language of Julia.
  15. ### For more information on the library, see: graphsjl-docs.readthedocs.org/en/
  16. ### For more information on Plotly in Julia, see: https://plot.ly/julia/getting-started
  17. #####
  18.  
  19. # NOTEs:
  20.     # Graph coordinates _MUST_ be saved as vertex attributes, "x" and "y".
  21.     # The vertices _MUST_ therefore be of type ExVertex.
  22.     # Undirected curved edges are not yet implemented
  23.     # Directed graphs will take considerable time to load in Plotly due to the intensity tapering.
  24.         # Lower the gradient and/or sample the network to increase the load time.
  25.         # At this time, conventional "stick and arrow" approaches are not yet implemented
  26.         # To speed up time and ignore directionality, set _directed_ equal to false.
  27.  
  28. function graph_plotly(g::GenericGraph, signin::String, apikey::String; directed::Bool = true, label::Bool = false, labelpos = "center", labelsize = 1, labelfamily = "sans serif", labelcol = "#000000", labelopac = 1, vertexsize = 1, vertexcolor = "#F297A0", vertexsymbol = "circle", vertexopacity = .9, vertexbordercolor = "#6F95A2", vertexborderwidth = 1, vertexborderopacity = .95, edgecolor = "#B6BFBE", edgeopacity = .95, edgewidth = 1, edgecolortip = "#FFFFFF", curved::Bool = true, curveintensity::Real = 1, gradient::Integer = 100)
  29.  
  30.     Plotly.signin(signin, apikey)
  31.  
  32.     #Some scaling constants
  33.     vertexsize = vertexsize .* 32
  34.     vertexborderwidth = vertexborderwidth .* 3
  35.     edgewidth = edgewidth .* 6
  36.     labelsize = labelsize .* 18
  37.     curveintensity = curveintensity * 3
  38.  
  39.     ecount = num_edges(g)
  40.     vcount = num_vertices(g)
  41.    
  42.     #Coordinates
  43.     x = map((f)->f.attributes["x"], g.vertices)
  44.     y = map((f)->f.attributes["y"], g.vertices)
  45.     graphcenter = [mean(x), mean(y)]
  46.     xel = Array(Real, ecount, 2)
  47.     yel = Array(Real, ecount, 2)
  48.     for i = 1:ecount
  49.         sind = source(g.edges[i]).index
  50.         tind = target(g.edges[i]).index
  51.         xel[i,:] = [x[sind], x[tind]]
  52.         yel[i,:] = [y[sind], y[tind]]
  53.     end
  54.  
  55.     # This function probably already exists in Julia, but I can only find it in the DataFrames library
  56.     function my_rep(anyvalue::Any, times::Integer)
  57.         anyvaluetype = typeof(anyvalue)
  58.         anyvaluearray = Array(anyvaluetype, times)
  59.         anyvaluearray[:] = anyvalue
  60.         return anyvaluearray
  61.     end
  62.     if length([edgecolor]) != ecount
  63.         edgecolor = my_rep([edgecolor][1], ecount)
  64.     end
  65.     if length(edgeopacity) != ecount
  66.         edgeopacity = my_rep([edgeopacity][1], ecount)
  67.     end
  68.     if length(edgewidth) != ecount
  69.         edgewidth = my_rep([edgewidth][1], ecount)
  70.     end
  71.     if length([edgecolortip]) != ecount
  72.         edgecolortip = my_rep([edgecolortip][1], ecount)
  73.     end
  74.  
  75.     #Suppress axes
  76.     axesstyle = [
  77.         "autorange" => true,
  78.         "autotick" => true,
  79.         "showgrid" => false,
  80.         "showline" => false,
  81.         "showticklabels" => false,
  82.         "zeroline" => false,
  83.         "ticks" => ""
  84.         ]
  85.  
  86.     #Suppress legend and hover mode.
  87.     #Hover mode might be interesting for the vertex attributes, but it's distracting for everything else.
  88.     layout = [
  89.         "xaxis" => axesstyle,
  90.         "yaxis" => axesstyle,
  91.         "showlegend" => false,
  92.         "hovermode" => "none"
  93.         ]
  94.  
  95.     function bezier_edges(x1::Real, y1::Real, x2::Real, y2::Real, edgew::Real, edgeo::Real, edgec::String, edgect::String)
  96.         # See: http://is-r.tumblr.com/post/38459242505/beautiful-network-diagrams-with-ggplot2
  97.         # And: https://en.wikipedia.org/wiki/B%C3%A9zier_curve        
  98.  
  99.         # _x1_ and _y1_ are the source coordinates.
  100.         # _x2_ and _y2_ are the target coordinates.
  101.         # _edgew_ is the edge's weight/thickness. Goes from _edgew_ to 0.
  102.         # Color:
  103.             # Ranges from _edgec_ to _edgec_.
  104.             # Color opacity ranges from _edgeo_ to 0.      
  105.  
  106.         # Curve midpoint
  107.         if curved == false
  108.             beziermid = ([x1, y1] .+ [x2. y2]) ./ 2
  109.         else
  110.             beziermid = [x1, y2]
  111.             distance1 = sum([(graphcenter[1] - beziermid[1])^2, (graphcenter[2] - beziermid[2])^2])
  112.             criticalbezier = sum(graphcenter .- [x2^2, y1^2])
  113.             if distance1 < criticalbezier
  114.                 beziermid = [x2, y1]
  115.             end
  116.             beziermid = ([x1, y1] .+ [x2, y2] .+ beziermid) ./ curveintensity        
  117.         end
  118.  
  119.         # Create continuous x and y coordinates
  120.         function bezier_fun(p0, p1, p2, t)
  121.             return ((1-t)^2) * p0 + 2 * (1-t) * t * p1 + (t^2) * p2
  122.         end
  123.         xbezier = Array(Real, gradient)
  124.         ybezier = Array(Real, gradient)
  125.         tvals = linspace(0, 1, gradient)
  126.         for j = 1:gradient
  127.             xbezier[j] = bezier_fun(x1, beziermid[1], x2, tvals[j])
  128.             ybezier[j] = bezier_fun(y1, beziermid[2], y2, tvals[j])
  129.         end
  130.  
  131.         # Taper the edge width, opacity, and color
  132.         twidth = linspace(edgew, 0, gradient) # Perhaps a variable could be used instead of 0 here.
  133.         topacity = linspace(edgeo, 0, gradient) # Perhaps a variable could be used instead of 0 here.
  134.         function rgb_2_string(rgbinput::RGB)
  135.             colr = rgbinput.r
  136.             colg = rgbinput.g
  137.             colb = rgbinput.b
  138.             stringoutput = "rgb($colr,$colg,$colb)"
  139.             return stringoutput
  140.         end
  141.         tcolor = linspace(color(edgec), color(edgect), gradient)
  142.         tcolor = map(rgb_2_string, tcolor) #Needs to be turned into a string for Plotly.
  143.  
  144.         # Output many tiny lines
  145.         outtrace = Array(Any, gradient - 1)
  146.         for k = 1:(gradient-1)
  147.             outtrace[k] = [
  148.             "x" => xbezier[k:(k+1)],
  149.             "y" => ybezier[k:(k+1)],
  150.             "type" => "scatter",
  151.             "mode" => "lines",
  152.             "line" => [
  153.                 "color" => tcolor[k],
  154.                 "opacity" => topacity[k],
  155.                 "width" => twidth[k]
  156.                 ]
  157.             ]
  158.         end        
  159.         return outtrace
  160.     end
  161.  
  162.     #Add the edges to the plot
  163.     if (is_directed(g) == false) | (directed == false)
  164.         traceel = Array(Any, ecount)
  165.         for i = 1:ecount        
  166.             traceel[i] = [
  167.                 "x" => [xel[i, 1], xel[i, 2]],
  168.                 "y" => [yel[i, 1], yel[i, 2]],
  169.                 "type" => "scatter",
  170.                 "mode" => "lines",
  171.                 "line" => [
  172.                     "color" => [edgecolor][i],
  173.                     "opacity" => edgeopacity[i],
  174.                     "width" => edgewidth[i]
  175.                     ]
  176.                 ]
  177.         end
  178.     else
  179.         traceel = Any[]
  180.         for i = 1:ecount            
  181.             smalledge = bezier_edges(
  182.                 xel[i, 1],
  183.                 yel[i, 1],
  184.                 xel[i, 2],
  185.                 yel[i, 2],
  186.                 edgewidth[i],
  187.                 edgeopacity[i],
  188.                 edgecolor[i],
  189.                 edgecolortip[i]
  190.                 )
  191.             for l = 1:length(smalledge)
  192.                 push!(traceel, smalledge[l])
  193.             end
  194.         end
  195.     end
  196.  
  197.     #Add the vertices to the plot
  198.     push!(traceel, [
  199.         "x" => x,
  200.         "y" => y,
  201.         "type" => "scatter",
  202.         "mode" => "markers",
  203.         "marker" => [
  204.             "symbol" => vertexsymbol,
  205.             "size" => vertexsize,
  206.             "color" => vertexcolor,
  207.             "opacity" => vertexopacity,
  208.             "line" => [
  209.                 "width" => vertexborderwidth,
  210.                 "color" => vertexbordercolor,
  211.                 "hovermode" => "none"
  212.                 ]
  213.             ]
  214.         ])
  215.  
  216.     #Add the labels to the plot
  217.     if label
  218.         vertexnames = map((f)-> f.label, g.vertices)
  219.         push!(traceel, [
  220.             "x" => x,
  221.             "y" => y,
  222.             "name" => "Text",
  223.             "text" => vertexnames,
  224.             "type" => "scatter",
  225.             "mode" => "text",
  226.             "textposition" => labelpos,
  227.             "textfont" => [
  228.                 "color" => labelcol,
  229.                 "opacity" => labelopac,
  230.                 "size" => labelsize,
  231.                 "fanily" => labelfamily
  232.                 ]
  233.             ])
  234.     end
  235.    
  236.     response = Plotly.plot(traceel, ["layout" => layout])
  237.     return response
  238. end
  239.  
  240. ###Sample code
  241.  
  242. # download("http://pastebin.com/raw.php?i=Z2t7XRd3", "GraphsPopularDataSets.jl")
  243. # include("GraphsPopularDataSets.jl")
  244. # rm("GraphsPopularDataSets.jl")
  245.  
  246. # yourplotlyname = "Not this string"
  247. # yourplotlyAPIkey = "Not this string, either"
  248.  
  249. # floplot = graph_plotly(flograph, yourplotlyname, yourplotlyAPIkey, vertexsize = 0.75, label = true)
  250. # floplot["url"] #Find the plot at this URL
  251. # colemanplot = graph_plotly(colemangraph, yourplotlyname, yourplotlyAPIkey, vertexsize = 0.33, vertexopacity = .95, vertexborderopacity = 1, gradient = 150)
  252. # colemanplot["url"] #Find the plot at this URL
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top