Closed gmhhope closed 1 year ago
The bypass is standalone properties which are isolated from style.
p4c.get_node_property(visual_property='NODE_LABEL_ROTATION')
can retrieve all label rotations. And I can apply back by p4c.set_node_property_bypass()
However, I did get a warning by doing the following:
p4c.set_node_property_bypass(list(PID2rot.keys()),
list(PID2rot.values()),
visual_property='NODE_LABEL_ROTATION',
network = 'networkOfInterest')
Warning: setting unknown node bypass property "NODE_LABEL_ROTATION"
This is consistent with here:
p4c.clear_network_property_bypass(visual_property='NODE_LABEL_POSITION')
p4c.clear_network_property_bypass(visual_property='NODE_LABEL_ROTATION')
CyError: In cyrest_delete(): Bypass Visual Property does not exist: NODE_LABEL_POSITION
But the guideline said: look at the visual_property (str) – Name of a visual property. See get_visual_property_names
, which I check the property and it does have "NODE_LABEL_ROTATION", "NODE_LABEL_POSITION". This becomes very confusing.
The error seems to come from source
# If the property is verifiable, verify the values and adjust as appropriate
if visual_property in NODE_COLOR_PROPERTIES:
new_values = verify_hex_colors(new_values)
elif visual_property in NODE_DIMENSION_PROPERTIES.keys():
new_values = verify_dimensions(NODE_DIMENSION_PROPERTIES[visual_property], new_values)
elif visual_property in NODE_OPACITY_PROPERTIES:
new_values = verify_opacities(new_values)
elif visual_property in NODE_SHAPE_PROPERTIES:
new_values = verify_node_shapes(new_values, styles.get_node_shapes(base_url=base_url))
elif visual_property in NODE_VISIBLE_PROPERTIES:
new_values = verify_bools(new_values)
elif visual_property in NODE_LABEL_PROPERTIES | NODE_TOOLTIP_PROPERTIES | NODE_FONT_FACE_PROPERTIES:
new_values = verify_strs(new_values)
else:
show_error(f'Warning: setting unknown node bypass property "{visual_property}"')
The property somehow cannot verified? It doesn't make sense for bypass as it can be set in the GUI
NODE_FONT_FACE_PROPERTIES = {'NODE_LABEL_FONT_FACE'}
NODE_LABEL_PROPERTIES = {'NODE_LABEL'}
Does it mean this feature (NODE_LABEL_POSITION
and NODE_LABEL_ROTATION
) not yet supported in py4cytoscape?
Hi --
Getting the warning you're asking about doesn't mean that a property isn't supported ... it just means that there isn't a validation for the argument. So, the argument you supply will be used without checking it first.
Regarding the grouping of style values, bypasses and defaults, it's not so arbitrary as it might seem. Taking a look at the py4cytoscape documentation, see the grouping of all of the style-related functions:
This roughly tracks what the GUI Style Mapping panels are doing:
The Default setting is the style value if there is no mapping or default style value.
The Mapping setting determines the style value based on a node or edge property.
The Bypass is pretty important to you because it applies a property to a particular node or edge instead of all nodes or edges, regardless of the Default or Mapping settings. You've been using it to set the node location, which is appropriate because each node has its own location.
Good to review the Styles documentation for the GUI, especially the How Mappings Section.
For reusing style Default or Mapping settings, you can define a style and name it (e.g., Test1) using either the GUI ("Create New Style" under the settings menu in the Style panel or via py4cytoscape's Style Management functions ... and apply an existing style to a new network.
For reusing the bypass values, it's a little tricker. You're already using set_node_property_bypass() (or a variation) on a node-by-node basis. So, how to perform the equivalent of get_node_property_bypass(), which isn't provided in py4cytoscape?
To know this, you might understand that py4cytoscape is a front end to Cytoscape's CyREST interface. set_node_property_bypass() resolves to the CyREST PUT /v1/networks/{networkId}/views/{viewId}/{objectType}/{objectId}
function. You can see this by visiting the Help | Automation | CyREST API menu, which puts up a Swagger page. This function is in the Network View section.
If you get that far, you might notice a corresponding GET
function. So, you can build your own get_node_property_bypass() by using the set_node_property_bypass() function to inform how you might call the corresponding GET
function. You can learn more about this in the Concepts documentation section.
Feel free to ask questions. Frankly, I think get_node_property_bypass() might be a good addition to the py4cytoscape/RCy3 API, but that won't happen quickly.
@AlexanderPico @yihangx
I have been working around this issue by just not going for circular visualization. Now I just would like to change all the default node label postion. But figure out there isn't such function? The closest one is set_node_custom_position
, which seems not changing the labeling position but probably the customized graph position relative to the node.
Could you help with that? I think I am closed to finish using this tool for my figure : ) Thanks always for all the help @bdemchak
Best, MG
Hi --
Please note that py4cytoscape 1.8 was released today, and it addresses some of the points you've raised. For new functions, I'm talking with the RCy3 people ... they're not in 1.8.
For information on 1.8, please see https://py4cytoscape.readthedocs.io/en/latest/release_log.html#py4cytoscape-1-8-0
Regarding the default node label position, can you send me a screenshot showing a poorly positioned label and indicating where you'd like the label to be instead?? Thanks!
Sorry for the late comment.
Just position like this. I meant I can easily do it in GUI. But I just cannot figure out how to do it in the python pkg.
Thanks, Minghao
No problem... happy for the reply ... how would you do this with the GUI?
On Sun, Jul 23, 2023, 11:38 AM Minghao Gong @.***> wrote:
Sorry for the late comment. [image: Screenshot 2023-07-23 at 2 37 37 PM] https://urldefense.com/v3/__https://user-images.githubusercontent.com/12982817/255425461-ec0a4b05-c0f8-4093-a0b0-9f6e1f2e19b8.png__;!!Mih3wA!B6sA6xDxnGSigQtq3eWPQhWmH7kpw-vbKBtNZ-9Ssoa8jzpHxKvB6qqIyhBGKQV1-WRHneJ6jEtGfrPncrLD-EviMQ$
Just position like this. I meant I can easily do it in GUI. But I just cannot figure out how to do it in the python pkg.
Thanks, Minghao
— Reply to this email directly, view it on GitHub https://urldefense.com/v3/__https://github.com/cytoscape/py4cytoscape/issues/111*issuecomment-1646927038__;Iw!!Mih3wA!B6sA6xDxnGSigQtq3eWPQhWmH7kpw-vbKBtNZ-9Ssoa8jzpHxKvB6qqIyhBGKQV1-WRHneJ6jEtGfrPncrIKQcuetw$, or unsubscribe https://urldefense.com/v3/__https://github.com/notifications/unsubscribe-auth/AA4GLXXKNFQONBBNGYY3E3DXRVVTFANCNFSM6AAAAAA2NBZEFM__;!!Mih3wA!B6sA6xDxnGSigQtq3eWPQhWmH7kpw-vbKBtNZ-9Ssoa8jzpHxKvB6qqIyhBGKQV1-WRHneJ6jEtGfrPncrLk4iudrg$ . You are receiving this because you were mentioned.Message ID: @.***>
Here it is: see the label position screenshot:
Hi --
This was a wonderful question, and it caused me to do a little work because property values aren't documented anywhere.
The short answer:
p4c.set_visual_property_default({'visualProperty': 'NODE_LABEL_POSITION', 'value':'N,S,c,10.00,20.00'}, 'default')
So, the NODE_LABEL_POSITION property is a list of values that correspond to the dialog box fields. The field values appear to be Node Anchor Points, Label Anchor Points, Text Justification, X Offset, Y Offset.
So, 'N,S,c,10.00,20.00' would be North, South, Center Justified, X Offset 10, Y Offset 20.
How did I figure this out?? I used the Cytoscape GUI to dump the visual style to styles.xml ... the menu item is File | Export | Styles to File..., and I chose the name of the style being used for my network.
From there, I looked into styles.xml and found the NODE_LABEL_POSITION property:
<visualProperty default="N,S,c,10.00,20.00" name="NODE_LABEL_POSITION"/>
From there, the format of the property can be deduced.
Does this make sense to you, or should I go into more depth?
Note that you can set the default value (and other style information) by using the GUI and the dialog you showed me. Once you do that, you can save the whole style to styles.xml. You can use py4cytoscape to load the style:
p4c.import_visual_styles()
Note that set_visual_property_default() generates the same warning message as I fixed for the bypass properties. I didn't realize this check was also made for default properties. I have removed the warning and checked the fix into the 1.9.0 branch in case you'd like to use it.
@AlexanderPico @yihangx
Hey Barry,
I don't mean to reply late. I was in a conference for a talk and then so many works afterwards.
Thanks very much for this wonderful answer. I am coming back to this project and I just have another question that I will post in a separate issue.
Thanks again for the detailed answer!
Best, Minghao Gong
Hi Barry,
I have to reopen this as I still want to figure out how to clear the bypass of node label...
Trying to reset the wrongly assigned rotation/label. See the following screenshot:
Here is my command:
node_names = list(p4c.get_table_columns(columns='name')['name'])
p4c.clear_node_property_bypass(node_names = node_names,visual_property='NODE_LABEL_POSITION')
But this gives me an error:
In cyrest_delete(): Bypass Visual Property does not exist: NODE_LABEL_POSITION
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/commands.py:109, in cyrest_delete(operation, parameters, base_url, require_json)
108 r = _do_request('DELETE', url, params=parameters, base_url=base_url)
--> 109 r.raise_for_status()
110 try:
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/requests/models.py:1021, in Response.raise_for_status(self)
1020 if http_error_msg:
-> 1021 raise HTTPError(http_error_msg, response=self)
HTTPError: 404 Client Error: Not Found for url: http://127.0.0.1:1234/v1/networks/2221/views/2673/nodes/2306/NODE_LABEL_POSITION/bypass
During handling of the above exception, another exception occurred:
CyError Traceback (most recent call last)
Cell In[299], line 2
1 node_names = list(p4c.get_table_columns(columns='name')['name'])
----> 2 p4c.clear_node_property_bypass(node_names = node_names,visual_property='NODE_LABEL_POSITION')
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/py4cytoscape_logger.py:133, in cy_log.<locals>.wrapper_log(*args, **kwargs)
131 return log_return(func, value)
132 except Exception as e:
--> 133 log_exception(func, e)
134 finally:
135 log_finally()
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/py4cytoscape_logger.py:130, in cy_log.<locals>.wrapper_log(*args, **kwargs)
128 log_incoming(func, *args, **kwargs)
129 try:
--> 130 value = func(*args, **kwargs) # Call function being logged
131 return log_return(func, value)
132 except Exception as e:
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/style_bypasses.py:219, in clear_node_property_bypass(node_names, visual_property, network, base_url)
217 else:
218 for suid in node_suids:
--> 219 res = commands.cyrest_delete(f'networks/{net_suid}/views/{view_suid}/nodes/{suid}/{visual_property}/bypass',
220 base_url=base_url)
222 return res
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/py4cytoscape_logger.py:133, in cy_log.<locals>.wrapper_log(*args, **kwargs)
131 return log_return(func, value)
132 except Exception as e:
--> 133 log_exception(func, e)
134 finally:
135 log_finally()
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/py4cytoscape_logger.py:130, in cy_log.<locals>.wrapper_log(*args, **kwargs)
128 log_incoming(func, *args, **kwargs)
129 try:
--> 130 value = func(*args, **kwargs) # Call function being logged
131 return log_return(func, value)
132 except Exception as e:
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/commands.py:118, in cyrest_delete(operation, parameters, base_url, require_json)
116 return r.text
117 except requests.exceptions.RequestException as e:
--> 118 _handle_error(e)
File ~/mambaforge/envs/yoda/lib/python3.11/site-packages/py4cytoscape/commands.py:683, in _handle_error(e, force_cy_error)
681 else:
682 show_error(f'In {caller}: {e}\n{content}')
--> 683 raise e
CyError: In cyrest_delete(): Bypass Visual Property does not exist: NODE_LABEL_POSITION
I just have some crunching time and cannot plunge myself to look for answers from what you told me about all the other alternatives.
Hope you can help!
Best, Minghao
Hi Barry,
Sorry for bothering you these days. Could you provide me solutions to set the label rotation bypass? Additionally, if I have premade the rotation bypass, is there a way I can retrieve them using py4cytoscape and then copied those properties (the rotation levels) to another network?
For example, I created a new network and used
layout_copycat
and set the style with the older one but it cannot inherit the node position (possibly any bypass properties)? In other words, I definitely had hard time to understand how the bypass properties related to the style. Will they get documented in the particular style or they remained separate properties isolated from a particular style?I looked forward to any of your suggestions! Thanks for being so helpful these couples of days/weeks.
Thanks, Minghao Gong