I want to change the color of my nodes based on their properties:
Say I have many "Person" nodes. And I want those who live in New York to be red and those who live in Los Angeles to be blue. How would I write that. In cypher or in py2neo?
The styling of nodes and relationships in Neo4j Browser is controlled by a graph style sheet (GRASS), a cousin of CSS. You can view the current style by typing :style in the browser. To edit it, you can click on nodes and relationships and pick colors and sizes, or you can view the style sheet (:style), download it, make changes, and drag-n-drop it back into the view window.
Unfortunately for your case, color can only be controlled a) for all nodes and all relationships or b) for nodes by label and relationships by type. Properties can only be used for the text displayed on the node/rel.
It is not possible to interact with neo4j browser pro-grammatically. But the end goal could be achieved through a hack.
Even though I am a bit late here want to help others who might be finding a way. It is not possible to change the color of the nodes based on the property but there is a way it can be achieved by creating nodes based on the property. Keep in mind that after applying these queries your data wont be the same. So it is always a good idea to keep a backup of your data.
This is how labels are colored by default (Before):
Color based on the property
Suppose there is a label called Case with a property nationality and you want to color the nodes based on nationality. So following query could be used to create labels out of nationality property. For this you will need to install apoc library. check here for installation.
// BY NATIONALITY
MATCH (n:Case)
WITH DISTINCT n.nationality AS nationality, collect(DISTINCT n) AS persons
CALL apoc.create.addLabels(persons, [apoc.text.upperCamelCase(nationality)]) YIELD node
RETURN *
This will return all the people by nationality. Now you can color by country of nationality. Below shows an example.
Color based on the property and load with other labels
Lets say you also have a label called Cluster.The cases are attached to clusters via relationships. Just change the query to following to get the clusters with their relationships to cases.
//BY NATIONALITY WITH CLUSTERS
MATCH (n:Case),(c:Cluster)
WITH DISTINCT n.nationality AS nationality,
collect(DISTINCT n) AS persons,
collect(DISTINCT c) AS clusters
CALL apoc.create.addLabels(persons, [apoc.text.upperCamelCase(nationality)]) YIELD node
RETURN *
It will return cases and clusters with all the relationships. Below shows example.
Please leave an up vote if this was helpful and want to let others know that this is an acceptable answer. Thank you.
You cannot include formatting of the output in Cypher queries in the neo4j browser. Currently, the only way is to change the graph view manually or load a graph style file.
See tutorial here: http://neo4j.com/developer/guide-neo4j-browser/
Also, you cannot interact with the neo4j browser from py2neo.
If you are happy setting the color through a graphical user interface rather than programatically, Neo4j also supplies a data exploration addon named bloom. When using this addon (now automatically installed when using neo4j desktop), it is possible to set node color based on its properties.
In the example below, movies released after 2002 are colored green.
Related
I am completely new to NEO4j and using it for the first time ever now for my masters program. Ive read the documentation and watched tutorials online but can’t seem to figure out how I can represent my nodes in the way I want.
I have a dataframe with 3 columns, the first represents a page name, the second also represents a page name, and the third represents a similarity score between those two pages. How can I create a graph in NEO4J where the nodes are my unique page names and the relationships between nodes are drawn if there is a similarity score between them (so if the sim-score is 0 they don’t draw a relationship)? I want to show the similarity score as the text of the relationship.
Furthermore, I want to know if there is an easy way to figure out which node had the most relationships to other nodes?
I’ve added a screenshot of the header of my DF for clarity https://imgur.com/a/pg0knh6. I hope anyone can help me, thanks in advance!
Edit: What I have tried
LOAD CSV WITH HEADERS FROM 'file:///wiki-small.csv' AS line
MERGE (p:Page {name: line.First})
MERGE (p2:Page {name: line.Second})
MERGE (p)-[r:SIMILAR]->(p2)
ON CREATE SET r.similarity = toFloat(line.Sim)
Next block to remove the similarities relationships which are 0
MATCH ()-[r:SIMILAR]->() WHERE r.Sim=0
DELETE r
This works partially. As in it gives me the correct structure of the nodes but doesn't give me the similarity scores as relationship labels. I also still need to figure out how I can find the node with the most connections.
For the first question:
How can I create a graph in NEO4J where the nodes are my unique page names and the relationships between nodes are drawn if there is a similarity score between them (so if the sim-score is 0 they don’t draw a relationship)?
I think a better approach is to remove in advance the rows with similarity = 0.0 before ingesting them into Neo4j. Could it be something feasible? If your dataset is not so big, I think it is very fast to do in Python. Otherwise the solution you provide of deleting after inserting the data is an option.
In case of a big dataset, maybe it's better if you load the data using apoc.periodic.iterate or USING PERIODIC COMMIT.
Second question
I want to know if there is an easy way to figure out which node had the most relationships to other nodes?
This is an easy query. Again, you can do it with play Cypher or using APOC library:
# Plain Cypher
MATCH (n:Page)-[r:SIMILAR]->()
RETURN n.name, count(*) as cat
ORDER BY cnt DESC
# APOC
MATCH (n:Page)
RETURN apoc.node.degree(n, "SIMILAR>") AS output;
EDIT
To display the similarity scores, in Neo4j Desktop or in the others web interfaces, you can simply: click on a SIMILARITY arrow --> on the top of the running cell the labels are shown, click on the SIMILAR label marker --> on the bottom of the running cell, at the right of Caption, select the property that you want to show (similarity in your case)
Then all the arrows are displayed with the similarity score
To the second question: I think you should keep a clear separation between the way you store data and the way you visualize it. Having the similarity score (a property of the SIMILARITY edge) as a "label" is something that is best dealt with by using an adequate viz library or platform. Ours (Graphileon) could be such a platform, although there are also others.
We offer the possibility to "style" the edges with so-called selectors like
"label":"(%).property.simScore" that would use the simScore as a label. On top of that you could do thing like
"width":"evaluate((%).properties.simScore < 0.500 ? 3 : 10)"
or
"fillColor":"evaluate((%).properties.simScore < 0.500 ? grey : red)"
to distinguish visually high simScores.
Full disclosure : I work for Graphileon.
I have 565 articles in Neo4j and I ran LPA to obtain clusters.
I have the following result: 69 communities.
I would like to display all the communities at the same time in Neo4j.
I tried several Cypher queries with the property key 'community' but it didn't work.
My data looks like this:
How can I do it ?
Presumably, you are using the neo4j Browser to visualize your results.
When your Cypher query returns any nodes, relationships, or paths, the browser will automatically show you the Graph view (on the left side of the result panel, you should see icons with captions that may include Graph, Table, Text, etc.). The Graph view only shows nodes and relationships, and not anything else that was returned.
However, if you click on the other icons (say, Table or Text), you should see more results -- like the communities, presented in different formats.
By the way, specifying the node label would make your query more efficient (and adding an index would make it even more efficient if you have a lot of ARTICLE nodes):
MATCH (n:ARTICLE) WHERE EXISTS(n.community)
RETURN n, n.community
I'm building a Neo4J system just do to visualization in the Neo4J browser. I build the various nodes and relationships and I can visualize the database by running match (n) return n. The problem is that the resulting display shows the relationship names but not their associated properties. Can anyone tell me the cypher query to show the entire database including relationship properties? Thanks.
The neo4j browser does not support visualizing all properties (for nodes or relationships) at the same time. Such a capability would generally result in a very congested and unusable visualization, especially since the browser would also have to display the property names.
You can, however, opt to show the value of a single property per node label or or relationship type as its caption. You can do that manually, or you can edit the GRASS file to set all of the captions at once. As an example of how to set relationship captions in the GRASS file, the following entry in that file would specify that all BAR relationships should show their foo property:
relationship.BAR {
caption: '{foo}';
}
I need to set specific property of a node as display name for that node.Till now, I am doing the same through the neo4j UI.
I am selecting the specify property from the list below, where arrow is pointing, as a display on nodes and relationships.
I want to do the same through the Cypher.
Ex: MATCH (n:SERVER) RETURN n
To this n, I want to set ip as the display name.
Cypher is only for reading and writing to a neo4j DB. It provides no support for controlling DB visualization; nor should it, since there is no standardized way to visualize a neo4j DB. I am afraid you will have to continue to use the neo4j browser to control how it displays your data.
I'm using ne04j 2.1.2 community edition.
I have a nodes with a label called Company and I created these nodes and label by loading CSV file along with the MERGE and CREATE commands.
So in future if my label names changes,say Company to Organization, I wanted to maintain the createddate, UpdatedDate, NewLabelName, OldLabelName values somewhere.
So in order to achieve that I thought of maintaining one master node which holds the label information i.e., it should have the properties like NewLabelName, OldLabelName, CreatedDate, UpdatedDate. So the label name should come from the Master Node to other nodes. Whenever we made any changes to label ,then the corresponding UpdatedDate property value should be updated in the master node and NewLabelName should come from the master node to other nodes (nodes for which that label belongs to) .
Hope you understand the scenario here.
But how can i achieve this ? is it possible to achieve ? if yes, then how can i define the relationship between master and other nodes?
(Here my other nodes are Name of the Companies like Google, Yahoo, Samsung etc.. and those will be having some other child nodes like location)
Please suggest the solution. (I wanted to achieve these using cypher not using java)
Thanks
Although labels can be changed, you should do that rarely (e.g., to recover from a mistake). Changing a large number of labels is very expensive and should never be done as a part of normal processing.
Also, like a Java class name, a label name is not something you'd normally show to end users. So, there is really no reason to ever change them. Just try to pick reasonable label names to start with, and don't plan to change them.