Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
Supply Chain Visualization Node
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Lars Valentin
Supply Chain Visualization Node
Commits
1ece0eb9
Commit
1ece0eb9
authored
1 year ago
by
Octavio Mesa-Varona
Browse files
Options
Downloads
Patches
Plain Diff
Neue Datei hochladen
parent
591b7009
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
main.py
+199
-0
199 additions, 0 deletions
main.py
with
199 additions
and
0 deletions
main.py
0 → 100644
+
199
−
0
View file @
1ece0eb9
import
time
import
pandas
as
pd
import
knime.extension
as
knext
import
numpy
as
np
import
logging
import
plotly.graph_objects
as
go
import
pycountry
from
geopy.geocoders
import
Nominatim
LOGGER
=
logging
.
getLogger
(
__name__
)
category
=
knext
.
category
(
"
/community
"
,
"
Supply_chain_visualization_node
"
,
"
Supplychain visualization node
"
,
"
Supplychain visualization node for KNIME
"
,
icon
=
"
icons/icon.png
"
)
@knext.node
(
name
=
"
Supplychain visualization node
"
,
node_type
=
knext
.
NodeType
.
LEARNER
,
category
=
category
,
icon_path
=
"
icons/icon.png
"
)
@knext.input_table
(
name
=
"
Input Data 1
"
,
description
=
"
Input data
"
)
@knext.output_table
(
name
=
"
Output Data
"
,
description
=
"
Output data
"
)
@knext.output_view
(
name
=
"
Output view
"
,
description
=
"
Output view
"
)
class
TemplateNode
:
def
configure
(
self
,
configure_context
,
input_schema_1
):
return
input_schema_1
def
execute
(
self
,
exec_context
,
input_1
):
df
=
input_1
.
to_pandas
()
# Transform the input table to some processable format (pandas or pyarrow)
if
df
.
empty
:
LOGGER
.
warning
(
"
Input table is empty.
"
)
return
None
,
None
df
=
df
.
rename
(
columns
=
{
'
Country (from)
'
:
'
C_From
'
,
'
Country (to)
'
:
'
C_To
'
,
'
Value (thousands of €)
'
:
'
Value
'
})
countries
=
pd
.
concat
([
df
[
'
C_From
'
],
df
[
'
C_To
'
]],
axis
=
0
,
ignore_index
=
True
)
countries
=
pd
.
DataFrame
(
countries
)
countries
.
columns
=
[
'
Name
'
]
countries
.
drop_duplicates
(
inplace
=
True
)
# Apply function to DataFrame to get latitude and longitude for each country
countries
[
'
Latitude
'
],
countries
[
'
Longitude
'
]
=
zip
(
*
countries
[
'
Name
'
].
apply
(
get_lat_long
))
countries
[
'
Country_Code
'
]
=
countries
[
'
Name
'
].
apply
(
get_country_code
)
country_code_array
=
np
.
array
(
countries
[
'
Country_Code
'
])
country_name_array
=
np
.
array
(
countries
[
'
Name
'
])
country_colour
=
[]
broj_drzava
=
len
(
country_code_array
)
for
i
in
range
(
0
,
broj_drzava
):
country_colour
.
append
(
i
)
countries
=
countries
.
set_index
(
'
Name
'
)
df
[
'
Value_Normalized
'
]
=
round
(
df
[
'
Value
'
]
*
10
/
max
(
df
[
'
Value
'
]))
+
1
import
plotly.graph_objects
as
go
# Define your data for the choropleth map
data
=
[
go
.
Choropleth
(
locations
=
country_code_array
,
# Country codes or names
z
=
country_colour
,
# Values for coloring the map
text
=
country_name_array
,
# Country names
# colorscale='Blues', # Color scale for the map
autocolorscale
=
False
,
# Disable automatic scaling of colors
showscale
=
False
,
# Hide the color scale legend
# geojson='https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/world-countries.json' # GeoJSON file URL
)
]
# Define the layout of the figure
layout
=
go
.
Layout
(
title
=
'
Supplychain visualization
'
,
geo
=
dict
(
showframe
=
True
,
# Show the frame around the map
showcoastlines
=
True
,
# Show coastlines
projection_type
=
'
natural earth
'
# Set the projection type
)
)
# Create the figure
fig
=
go
.
Figure
(
data
=
data
,
layout
=
layout
)
# Display the figure
# fig.show()
for
index
,
row
in
df
.
iterrows
():
c_from
=
row
[
'
C_From
'
]
c_to
=
row
[
'
C_To
'
]
c_th
=
row
[
'
Value_Normalized
'
]
# Introduce a delay between geocoding requests
time
.
sleep
(
0.2
)
# Wait for a second before each geocoding request
nacrtaj_arrow
(
fig
,
countries
,
c_from
,
c_to
,
c_th
)
fig
.
update_layout
(
# width=900, height=650,
showlegend
=
False
,
geo
=
dict
(
scope
=
'
world
'
,
# landcolor = 'rgb(217, 217, 217)'
)
)
# x = input_1_pandas.to_html()
x
=
countries
.
to_html
()
# return knext.Table.from_pandas(input_1_pandas), knext.view(input_1_pandas) ### Tutorial step 13: Uncomment
# return knext.Table.from_pandas(df), knext.view_html(x) ### Tutorial step 13: Uncomment
return
knext
.
Table
.
from_pandas
(
df
),
knext
.
view
(
fig
)
### Tutorial step 13: Uncomment
# Define function to get latitude and longitude for a country
def
_code
(
country_name
):
country
=
pycountry
.
countries
.
get
(
name
=
country_name
.
upper
())
if
country
:
return
country
.
alpha_3
else
:
LOGGER
.
warning
(
f
"
Country code not found for
{
country_name
}
. Skipping this country.
"
)
return
None
# Define function to get latitude and longitude for a country
# Modify get_lat_long function
def
get_lat_long
(
country
):
geolocator
=
Nominatim
(
user_agent
=
"
my_app
"
)
try
:
location
=
geolocator
.
geocode
(
country
,
timeout
=
10
)
if
location
:
return
(
location
.
latitude
,
location
.
longitude
)
else
:
LOGGER
.
warning
(
f
"
Location not found for country:
{
country
}
"
)
return
(
None
,
None
)
except
GeocoderTimedOut
:
LOGGER
.
warning
(
f
"
Geocoding request timed out for country:
{
country
}
"
)
return
(
None
,
None
)
# Modify get_country_code function
def
get_country_code
(
country_name
):
country
=
pycountry
.
countries
.
get
(
name
=
country_name
.
upper
())
if
country
:
return
country
.
alpha_3
else
:
LOGGER
.
warning
(
f
"
Country code not found for:
{
country_name
}
. Skipping this country.
"
)
return
None
def
nacrtaj_arrow
(
fig
,
countries
,
c1
,
c2
,
thickness
):
fig
.
add_trace
(
go
.
Scattergeo
(
lat
=
[
countries
.
loc
[
c1
][
0
],
countries
.
loc
[
c2
][
0
]],
lon
=
[
countries
.
loc
[
c1
][
1
],
countries
.
loc
[
c2
][
1
]],
mode
=
'
lines
'
,
line
=
dict
(
width
=
thickness
,
color
=
'
blue
'
),
))
#Workaround to get the arrow at the end of an edge AB
l
=
1.1
# the arrow length
widh
=
0.035
#2*widh is the width of the arrow base as triangle
B
=
np
.
array
([
countries
.
loc
[
c2
][
1
],
countries
.
loc
[
c2
][
0
]])
A
=
np
.
array
([
countries
.
loc
[
c1
][
1
],
countries
.
loc
[
c1
][
0
]])
# A = np.array([locations['lon'][4], locations['lat'][4]])
# B = np.array([locations['lon'][0], locations['lat'][0]])
v
=
B
-
A
w
=
v
/
np
.
linalg
.
norm
(
v
)
# u = np.array([-v[1], v[0]]) #u orthogonal on w
u
=
np
.
array
([
-
w
[
1
],
w
[
0
]])
*
10
P
=
B
-
l
*
w
S
=
P
-
widh
*
u
T
=
P
+
widh
*
u
fig
.
add_trace
(
go
.
Scattergeo
(
lon
=
[
S
[
0
],
T
[
0
],
B
[
0
],
S
[
0
]],
lat
=
[
S
[
1
],
T
[
1
],
B
[
1
],
S
[
1
]],
mode
=
'
lines
'
,
fill
=
'
toself
'
,
fillcolor
=
'
blue
'
,
line_color
=
'
blue
'
))
# #------Display your text at the middle of the segment AB
# fig.add_trace(go.Scattergeo(lon =[0.5*(A+B)[0]], lat = [0.5*(A+B)[1]], mode='text', text='Your text'))
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment