OSMnx: Creating Custom Queries with Alternative Infrastructures - openstreetmap

I'm new to OSMnx and Overpass queries in general. I am trying to understand the correct way to write custom queries when working with non-street infrastructure types.
Specifically, I am trying to understand why this query works
import osmnx as ox
my_custom_filter = '["railway"~"disused"]'
G = ox.graph_from_point((51.5073509,-0.1277583),
distance = 10000,
distance_type = 'bbox',
infrastructure = 'way["railway]',
network_type = 'none',
custom_filter = my_custom_filter
)
But this one wields a bad request error:
import osmnx as ox
my_custom_filter = '["railway"~"disused"]'
G = ox.graph_from_point((51.5073509,-0.1277583),
distance = 10000,
distance_type = 'bbox',
infrastructure = 'way["railway~"rail"]',
network_type = 'none',
custom_filter = my_custom_filter
)
Notice the difference is simply that I specifying rail as the type of railway in the latter query.
See the OSM Railway Guide here.
If anyone can point me to any resources which would help me further understand how to construct custom filters - particularly custom filters with more than one filter, that would be excellent also. For example, what would be the correct syntax to add an additional customer filter.

You were just missing a " in your argument. This works:
import osmnx as ox
ox.config(log_console=True, use_cache=True)
point = (51.5073509,-0.1277583)
dist = 10000
dt = 'bbox'
cf = '["railway"~"disused"]'
G = ox.graph_from_point(point, dist=dist, dist_type=dt, custom_filter=cf)
But it produces an EmptyOverpassResponse error as there is nothing that matches your query in that search area. You will get a graph however if you change it to this for example:
cf = '["railway"!~"disused"]'
G = ox.graph_from_point(point, dist=dist, dist_type=dt, custom_filter=cf)

Related

'SequentialFeatureSelector' object has no attribute 'ranking_'

everyone,
I would like to sort the best features that I'm getting from SequentialFeatureSelector based on their ranks.
But I get this error:
'SequentialFeatureSelector' object has no attribute 'ranking_'
Can you help me to solve it and sort my features based on their importance?
`import pandas as pd
df=pd.read_csv('')
#Deviding X and Y
Y=df.iloc[:,-1:]
X = df[df.columns.drop(Y)]
#Selecting the K best features
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor()
sfs = SequentialFeatureSelector(model, n_features_to_select=5)
fit = sfs.fit(X, Y)
#Selecting them and showing them in a dataframe
names = X.columns.values
ranking = sfs.ranking_
names_scores = list(zip(names, ranking))
ns_df = pd.DataFrame(data = names_scores, columns=['Feature_names', 'ranks'])
L=ns_df.sort_values('ranks', ascending=False)
L`

A scalable Graph method for finding cliques for complete connected components PySpark

I'm trying to split GraphFrame connectedComponent output for each component to have a sub-group for each complete connected, meaning all vertices are connected to each other. the following sketch will help demonstrate what I'm trying to achieve
I'm using NetworkX method in order to achive it as following
def create_subgroups(edges,components, key_name = 'component'):
# joining the edges to enrich component id
sub_components = edges.join(components,[(edges.dst == components.id) | (edges.src == components.id)]).select('src','dst',key_name).drop_duplicates()
# caching the table using temp table
sub_components = save_temp_table(sub_components,f'inner_sub_{key_name}s', zorder = [key_name])
schema = StructType([ \
StructField("index",LongType(),True), \
StructField("id",StringType(),True), \
])
# applying pandas udf to enrich each vertices with the new component id
sub_components = sub_components.groupby(key_name).applyInPandas(pd_create_subgroups, schema).where('id != "not_connected"').drop_duplicates()
# joining the output and mulitplying each vertices by the time of sub-groups were found
components = components.join(sub_components,'id','left')
components = components.withColumn(key_name,when(col('index').isNull(),col(key_name)).otherwise(concat(col(key_name),lit('_'),concat('index')))).drop('index')
return components
import networkx as nx
from networkx.algorithms.clique import find_cliques
def pd_create_subgroups(pdf):
# building the graph
gnx = nx.from_pandas_edgelist(pdf,'src','dst')
# removing one degree nodes
outdeg = gnx.degree()
to_remove = [n[0] for n in outdeg if n[1] == 1]
gnx.remove_nodes_from(to_remove)
bic = list(find_cliques(gnx))
if len(bic)<=2:
return pd.DataFrame(data = {"index":[-1],"id":["not_connected"]})
res = {
"index":[],
"id":[]
}
ind = 0
for i in bic:
if len(i)<3:
continue
for id in i:
res['index'] = res['index'] + [ind]
res['id'] = res['id'] + [id]
ind += 1
return pd.DataFrame(res)
# creating sub-components if necessary
subgroups = create_subgroups(edges,components, key_name = 'component')
My problem is that there's a very large component containing 80% of the vertices causing very slow performance of the clusters. I've been trying to use labelPropagation to create smaller groups but it wouldn't do the trick. it has split it in a way that isn't suitable causing a split of vertices that should have been in the same groups.
Here's the cluster usage when it reaches the pandas_udf part
This issue was resolved by separating vertices into N groups, pulling all edges for each vertice in the group, and calculating the sub-group using the find_cliques method.

Can I draw a bipartite graph from every dataset?

I am trying to draw a bipartite graph for my data set, which is like below:
source target weight
reduce energy 25
reduce consumption 25
energy pennsylvania 4
energy natural 4
consumption balancing 4
the code That I am trying to plot the graph is as below:
C_2021 = nx.Graph()
C_2021.add_nodes_from(df_final_2014['source'], bipartite=0)
C_2021.add_nodes_from(df_final_2014['target'], bipartite=1)
edges = df_final_2014[['source', 'target','weight']].apply(tuple, axis=1)
C_2021.add_weighted_edges_from(edges)
But when I check with the below code whether it is bipartite or not, I get the "False" feedback.
nx.is_bipartite(C_2021)
Could you please advise what the issue is?
The previous issue is resolved, but when I want to plot the bipartite graph with the below steps, I do not get a proper result. If someone could help me, I will be appreciated it:
top_nodes_2021 = set(n for n,d in C_2021.nodes(data=True) if d['bipartite']==0)
top_nodes_2021
the output of the above is:
{'reduce'}
bottom_nodes_2021 = set(C_2021) - top_nodes_2021
bottom_nodes_2021
the output of the above is:
{'balancing', 'consumption', 'energy', 'natural', 'pennsylvania '}
then plot it by:
pos = nx.bipartite_layout(C_2021,top_nodes_2021)
plt.figure(figsize=[8,6])
# Pass that layout to nx.draw
nx.draw(C_2021,pos,node_color='#A0CBE2',edge_color='black',width=0.2,
edge_cmap=plt.cm.Blues,with_labels=True)
and the result is:
It works for me using your code. nx.is_bipartite(C_2021) returns true. Check the example below:
import sys
if sys.version_info[0] < 3:
from StringIO import StringIO
else:
from io import StringIO
import pandas as pd
data = StringIO('''source;target;weight
reduce;energy;25
reduce;consumption;25
energy;pennsylvania ;4
energy;natural;4
consumption;balancing;4
''')
df_final_2014 = pd.read_csv(data, sep=";")
C_2021 = nx.Graph()
C_2021.add_nodes_from(df_final_2014['source'], bipartite=0)
C_2021.add_nodes_from(df_final_2014['target'], bipartite=1)
edges = df_final_2014[['source', 'target','weight']].apply(tuple, axis=1)
C_2021.add_weighted_edges_from(edges)
nx.is_bipartite(C_2021)
Finally to draw them get the bipartite sets. The data you passed during the creation is false (i.g. bipartite=0 and bipartite=1).
Use the following commands:
from networkx.algorithms import bipartite
top_nodes_2021, bottom_nodes_2021 = bipartite.sets(C_2021)
pos = nx.bipartite_layout(C_2021, top_nodes_2021)
plt.figure(figsize=[8,6])
# Pass that layout to nx.draw
nx.draw(C_2021,pos,node_color='#A0CBE2',edge_color='black',width=0.2,
edge_cmap=plt.cm.Blues,with_labels=True)
With the following result:

Ironpython script in Ansys Customization tool

I'm a beginner in Python and I'm working with the Ansys Customization Tool (ACT) to add my own extension.
Is there a direct way to fill a file with every node's coordinates after deformation?
hopefully in 3 lines or columns: x , y , z
So far I only found the GetNodeValue object but it only gives me the displacement and I need the deformed coordinates for the entire model.
My first idea was to add the displacements to the initial coordinates but I didn't manage to do it.
Many thanks for your help
Lara
APDL Snippet
Add an APDL Snippet in the solution part of the tree:
/prep7
UPGEOM,1,1,1,file,rst ! adds the displacements to the nodal coordinates.
cdwrite,geom,nodesAndelements,geom ! Writes node and element data to nodesAndelement.geom
I'm not sure if you can work with the output format from cdwrite, but this is the quickest solution i can think of.
If you want to automate you have to insert the command snippet via
solution = ExtAPI.DataModel.Project.Model.Analyses[0].Solution
fullPath = "path//to//snippet"
snippet = solution.AddCommandSnippet()
snippet.ImportTextFile(fullPath)
ACT
If you want to stay in ACT it could be done like this:
global nodeResults
import units
analysis = ExtAPI.DataModel.Project.Model.Analyses[0]
mesh = analysis.MeshData
# Get nodes
allNodes = mesh.Nodes
# get the result data
reader = analysis.GetResultsData()
# get the deformation result
myDeformation = reader.GetResult("U")
nodeResultsTemp = []
result_unit = myDeformation.GetComponentInfo("X").Unit
for node in allNodes:
# get node deformation and convert values in meter
deformationNode1 = myDeformation.GetNodeValues(node.Id)
deformationNode1[0] = units.ConvertUnit(deformationNode1[0],result_unit,"m","Length")
deformationNode1[1] = units.ConvertUnit(deformationNode1[1],result_unit,"m","Length")
deformationNode1[2] = units.ConvertUnit(deformationNode1[2],result_unit,"m","Length")
# add node coordinates (in meter) to the displacement
mesh_unit = mesh.Unit
node1 = mesh.NodeById(node.Id)
node1CoorX = units.ConvertUnit(node1.X,mesh_unit,"m","Length")
node1CoorY = units.ConvertUnit(node1.Y,mesh_unit,"m","Length")
node1CoorZ = units.ConvertUnit(node1.Z,mesh_unit,"m","Length")
deformationNode1[0] = deformationNode1[0]+node1CoorX
deformationNode1[1] = deformationNode1[1]+node1CoorY
deformationNode1[2] = deformationNode1[2]+node1CoorZ
nodeResultsTemp.append([node1.X,node1.Y,node1.Z,deformationNode1[0],deformationNode1[1],deformationNode1[2]])
nodeResults = nodeResultsTemp

Bokeh server plot does not update

LS,
All the answers about the same topic did not help me solve my update problem. I think it has to do with the dfs = df.sort_values(by=['E']). I use all the latest versions of the libraries. The examples on the bokeh website work fine on my configuration. Via an update button I want to allow the user to select the prefered sort order. The two other sort buttons will be added when this part works.
Here is my code:
import pandas as pd
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource
from bokeh.layouts import gridplot
from bokeh.models import Button
df = pd.DataFrame(dict(A=["AMS", "LHR", "FRA", "PTY", "CGD"], S=[7,-5,-3,3,2], E=[8,3,-2,5,8], C=[5,2,7,-3,-4]))
source = ColumnDataSource(df)
options = dict(plot_width=300, plot_height=200,
tools="pan,wheel_zoom,box_zoom,box_select,lasso_select")
button = Button(label="Change Sort to E")
p1 = figure(y_range=source.data['A'].tolist(), title="S", **options)
p1.hbar(y='A', right="S", height=0.2, source=source)
p2 = figure(y_range=source.data['A'].tolist(), title="E", **options)
p2.hbar(y="A", right="E", height=0.2, source=source)
p3 = figure(y_range=source.data['A'].tolist(), title="C", **options)
p3.hbar(y="A", right="C", height=0.2, source=source)
def update():
dfs = df.sort_values(by=['E'])
source.data = ColumnDataSource.from_df(dfs)
button.on_click(update)
p = gridplot([[button], [p1, p2, p3]], toolbar_location="right")
curdoc().add_root(p)
I run the server via: bokeh serve --show app.py --port 5009
Thank you very much for making the update work.
If you want to change the order of things on a categorical axis, you have to update the range. The order of the factors on the axis is specified exactly by the order of factors you configure for the range, so you will need to re-order the factors to match the sort order you want. So, something like:
p1.y_range.factors = new_sorted_factors
See
https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html#sorted
for a complete (standalone) example.