is it possible to colour a rectangle in folium python - python

I have a map:
map_osm = folium.Map(location=[51.366975, 0.039039],zoom_start=12)
map_osm
I want to be able to add a rectangle marker that I can colour according to some statistic. I found a polygon_marker (http://bl.ocks.org/wrobstory/5609786) but receive the error 'Map' object has no attribute 'polygon_marker' when I try:
map_osm.polygon_marker(location=[45.5132, -122.6708], popup='Hawthorne Bridge',
fill_color='#45647d', num_sides=4, radius=10)
In the final product, I would like to have lots of rectangles colour coded.
Any suggestions

After little digging into the the docs and source code and quick experimentation, you can just input parameter fill_color='blue' when you initialize Rectangle object.
Example code:
m = folium.Map(
location=[-6.237933179178703, 106.81783770824106],
zoom_start=13,
tiles='Stamen Toner'
)
folium.Rectangle(bounds=points, color='#ff7800', fill=True, fill_color='#ffff00', fill_opacity=0.2).add_to(m)
Result

A little more research, I found:
grid_pt=(51.4,0.05)
W=grid_pt[1]-0.005
E=grid_pt[1]+0.005
N=grid_pt[0]+0.005
S=grid_pt[0]-0.005
upper_left=(N,W)
upper_right=(N,E)
lower_right=(S,E)
lower_left=(S,W)
line_color='red'
fill_color='red'
weight=2
text='text'
edges = [upper_left, upper_right, lower_right, lower_left]
map_osm = folium.Map(location=[latty, longy],zoom_start=14)
map_osm.add_child(folium.vector_layers.Polygon(locations=edges, color=line_color, fill_color=fill_color,
weight=weight, popup=(folium.Popup(text))))
this works to add a single rectangle, then loop to get more

Related

Why Gmsh create more surfaces than expected when I use "gmhs.model.occ.cut()" command?

I am trying to create a volume in Gmsh (using Python API) by cutting some small cylinders from a bigger one.
When I do that, I expect to have one surface for each cutted region, instead, I get the result in the figure. I have highlighted in red the surfaces that give me the problem (some cutted regions behave as expected), as you can see, instead of one surface I get two, that sometimes aren't even equal.
gmsh creates more surfaces than expected:
So, my questions are:
Why gmsh behaves like that?
How can I fix this as I need predictable behavior?
Below is the code I used to generate the geometry.
The code to work requires some parameters such as core_height, core_inner_radius and core_outer_radius, the number of small cylinders and their radius.
gmsh.initialize(sys.argv)
#gmsh.initialize()
gmsh.clear()
gmsh.model.add("circle_extrusion")
inner_cyl_tag = 1
outer_cyl_tag = 2
inner_cyl = gmsh.model.occ.addCylinder(0,0,0, 0, 0, core_height, core_inner_radius, tag = inner_cyl_tag)
outer_cyl = gmsh.model.occ.addCylinder(0,0,0, 0, 0, core_height, core_outer_radius, tag = outer_cyl_tag)
core_tag = 3
cut1 = gmsh.model.occ.cut([(3,outer_cyl)],[(3,inner_cyl)], tag = core_tag)
#create a set of filled cylinders
#set position
angle_vector = np.linspace(0,2*np.pi,number_of_hp+1)
pos_x = hp_radial_position*np.cos(angle_vector)
pos_y = hp_radial_position*np.sin(angle_vector)
pos_z = 0.0
#cut one cylinder at the time and assign the new core tag
for ii in range(0,len(angle_vector)):
old_core_tag = core_tag
heat_pipe = gmsh.model.occ.addCylinder(pos_x[ii], pos_y[ii], pos_z, 0, 0, core_height,hp_outer_radius, tag =-1)
core_tag = heat_pipe+1
core = gmsh.model.occ.cut([(3,old_core_tag)],[(3,heat_pipe)], tag = core_tag)
gmsh.model.occ.synchronize()
#get volume entities and assign physical groups
volumes = gmsh.model.getEntities(dim=3)
solid_marker = 1
gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]],solid_marker)
gmsh.model.setPhysicalName(volumes[0][0],solid_marker, "solid_volume")
#get surfaces entities and apply physical groups
surfaces = gmsh.model.getEntities(dim=2)
surface_markers= np.arange(1,len(surfaces)+1,1)
for ii in range(0,len(surfaces)):
gmsh.model.addPhysicalGroup(2,[surfaces[ii][1]],tag = surface_markers[ii])
#We finally generate and save the mesh:
gmsh.model.mesh.generate(3)
gmsh.model.mesh.refine()
gmsh.model.mesh.refine()
gmsh.option.setNumber("Mesh.MshFileVersion", 2.2) #save in ASCII 2 format
gmsh.write(mesh_name+".msh")
# Launch the GUI to see the results:
#if '-nopopup' not in sys.argv:
# gmsh.fltk.run()
gmsh.finalize()
I do not think that you have additional surfaces in the sense of gmsh.model.occ surfaces. To me this looks like your volume mesh is sticking out of your surface mesh, i.e. volume and surface mesh do not fit together.
Here is what I did to check your case:
First I added the following lines at the beginning of our code to get a minimum working example:
import gmsh
import sys
import numpy as np
inner_cyl_tag = 1
outer_cyl_tag = 2
core_height = 1
core_inner_radius = 0.1
core_outer_radius = 0.2
number_of_hp = 5
hp_radial_position = 0.1
hp_outer_radius = 0.05
What I get with this code is the following:
To visualize it like this go to "Tools"-->"Options"-->"Mesh" and check "2D element faces", "3D element edges" and "3D element faces".
You can see that there are some purple triangles sticking out of the green/yellowish surfaces triangles of the inner surfaces.
You could try to visualize your case the same way and check <--> uncheck the "3D element faces" a few times.
So here is the solution for this behaviour, I did not know that gmsh behaves like this myself. It seems that when you create your mesh and refine it the refinement will be applied on the 2D surface mesh and the 3D volume mesh seperately, which means that those two meshes are not connected after the refinement anymore. What I did next was to try what happens if you create the 2D mesh only, refine it, and then create the 3D mesh, i.e.:
replace:
gmsh.model.mesh.generate(3)
gmsh.model.mesh.refine()
gmsh.model.mesh.refine()
by:
gmsh.model.mesh.generate(2)
gmsh.model.mesh.refine()
gmsh.model.mesh.refine()
gmsh.model.mesh.generate(3)
The result then looks like this:
I hope that this was actually your problem. But in future it would be good if you could provide us a minimum working example of code that we can copy-paste and get the same visualization you showed us in your image.

ipyleaflet layer not scaled/positioned correctly

I'm trying to overlay an esri bathymetry map on my south polar stereographic map using the 'url' function in ipyleaflet. Doing this results with {z}/{y}/{x} in the url inserts the layer, but at a smaller size in the right-hand corner of the basemap. I tried to give the tilelayer the same crs, but that did not change the output. My code is as such:
from ipyleaflet import (
Map,
basemaps,
TileLayer,
basemap_to_tiles,
projections)
from ipywidgets import (Layout,
widgets as w
tile_layer = TileLayer(url='https://tiles.arcgis.com/tiles/C8EMgrsFcRFL6LrL/arcgis/rest/services/Antarctic_Basemap/MapServer/tile/{z}/{y}/{x}')
spsLayout = Layout(width='800px', height='800px')
m = Map(center=(-90, 0),
zoom=0,
layout=spsLayout,
basemap= basemaps.NASAGIBS.BlueMarble3031,
crs=projections.EPSG3031)
m.add_layer(tile_layer)
m
Here's where I got the url for the tiles In the bottom right. Thanks for your help!
I think the issue here is that this bathymetry base map use a different tilegrid(metatiles 3x3) from the one used with ipyleaflet(4x4). Unfortunately I don't think there is currently a way for Leaflet(hence ipyleaflet) to understand multiple tilegrids in the same map. A workaround would be to use ArcGIS in your notebook instead of ipyleaflet but that would require a paid subscription.
If you don't mind defining your own projection and resolutions you can use the ArcGIS layers and avoid completely thedefault polar projection and basemaps from ipyleaflet. i.e.
from ipyleaflet import (
Map,
basemaps,
TileLayer,
basemap_to_tiles,
projections)
ESRI_3031 = dict(
name='EPSG:3031',
custom=True,
proj4def="""+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=0 +k=1
+x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs""",
origin=[-3.06361E7, 3.0636099999999993E7],
resolutions=[
67733.46880027094,
33866.73440013547,
16933.367200067736,
8466.683600033868,
4233.341800016934,
2116.670900008467,
1058.3354500042335,
529.1677250021168,
264.5838625010584,
],
bounds=[
[-4524583.19363305,-4524449.487765655],
[4524449.4877656475,4524583.193633042]
]
)
tile_layer = TileLayer(url='https://tiles.arcgis.com/tiles/C8EMgrsFcRFL6LrL/arcgis/rest/services/Antarctic_Basemap/MapServer/tile/{z}/{y}/{x}')
spsLayout = Layout(width='800px', height='800px')
m = Map(center=(-90, 0),
zoom=0,
layout=spsLayout,
basemap= tile_layer,
crs=ESRI_3031)
m

Polygon overlay in leaflet map

I am creating an interactive map using ipyleaflet using the following code:
from ipyleaflet import Map, Polygon
polygon = Polygon(
locations=[[(38.844185,-4.804621),(39.241299,-1.899833),(40.74308,-2.205491),(40.34742,-5.17429),(38.844185,-4.804621)],[(39.365192,-1.941078),(40.867912,-1.567062),(41.276688,-4.670904),(39.775406,-4.976737),(39.365192,-1.941078)],[(39.706161,-1.849863),(41.207623,-1.465817),(41.617561,-4.594476),(40.117233,-4.908839),(39.706161,-1.849863)],[(39.702591,-5.033657),(40.101254,-2.077048),(41.602196,-2.389729),(41.204681,-5.413605),(39.702591,-5.033657)]],
color="green",
fill_opacity= 0.5,
fill_color="green"
)
m = Map(center=(38.5531, -4.6914), zoom=6)
m.add_layer(polygon);
m
The ouptut looks like this:
I am wondering how can I make the intersection of the polygons not be fully transparent. Looking at the attributes https://ipyleaflet.readthedocs.io/en/latest/api_reference/polygon.html in the documentation, I don't see any option?
An example of the desired output can be seen in the image below:
You've got bad results because ipyleaflet subtracts ovellaped polygons (you can see it in second example in the documentation link you posted, "Polygon with hole")
You need to add each polygon separately, I changed your code a bit, now it creates and applies polygons in loop:
from ipyleaflet import Map, Polygon
poligons = [[(38.844185,-4.804621),(39.241299,-1.899833),(40.74308,-2.205491),(40.34742,-5.17429),(38.844185,-4.804621)],
[(39.365192,-1.941078),(40.867912,-1.567062),(41.276688,-4.670904),(39.775406,-4.976737),(39.365192,-1.941078)],
[(39.706161,-1.849863),(41.207623,-1.465817),(41.617561,-4.594476),(40.117233,-4.908839),(39.706161,-1.849863)],
[(39.702591,-5.033657),(40.101254,-2.077048),(41.602196,-2.389729),(41.204681,-5.413605),(39.702591,-5.033657)]]
m = Map(center=(38.5531, -4.6914), zoom=6)
for poly in poligons:
polygon = Polygon(
locations= poly,
color="green",
fill_opacity= 0.5,
fill_color="green"
)
m.add_layer(polygon);
m
Result:

Is it possible to change the default colors used in a folium marker cluster map?

I am using folium to generate some maps and one of the features I am including is the markercluster overlay - as I am frequently plotting thousands of points on a map. The clustering groups GPS points of varying quantities together and overlays a number on top of the map icon, which represents how many points have been grouped together into that cluster. By default, the fewer points grouped together in a cluster will result in a green color for the map icon and the more points grouped together will be more towards the red spectrum. Ideally, I would like to reverse this, so that when there are a lot of consolidated points in one location, the icon will be green. Whereas when there are only a few consolidated points, the color will be red. I'm thinking this needs to be edited in the branca module somewhere, but I'm not sure and generally pretty unfamiliar with how branca works. Any help is much appreciated.
Here's an example of how marker clusters are typically created:
import folium
from folium.plugins import MarkerCluster
#Create the map image and establish the center point
mapImage = folium.Map(location=[40.165505, -99.788130],
zoom_start=12,
tiles='OpenStreetMap')
#Create the marker cluster group, which organizes all the gps points put into it
marker_cluster_group = MarkerCluster(name='Cluster Icons')
#This is just a reference to a default google mapping icon, purely optional
pointIcon_url = "http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png"
#Create the icon object
icon = folium.features.CustomIcon(pointIcon_url, icon_size=(15, 15))
#Create the marker/gps point and add it to the cluster group
folium.Marker([40.058377, -99.939192], icon=icon).add_to(marker_cluster_group)
#Adding the cluster group to the map image
marker_cluster_group.add_to(mapImage)
You can provide the MarkerCluster class with an argument icon_create_function which will style the cluster icons:
https://github.com/python-visualization/folium/blob/8595240517135d1637ca4cf7cc624045f1d911b3/folium/plugins/marker_cluster.py#L31
Here you can see an example of how that function should look like:
https://github.com/Leaflet/Leaflet.markercluster#customising-the-clustered-markers
So it's a Javascript function, that you provide to folium as a string.
With the help of #Conengmo 's response, I was able to get the info I needed and modify it as needed to create the below.
import folium
from folium.plugins import MarkerCluster
#Create the map image and establish the center point
mapImage = folium.Map(location=[40.165505, -99.788130],
zoom_start=12,
tiles='OpenStreetMap')
#Create a variable to store your javascript function (written as a string), which adjusts the default css functionality
#The below are the attributes that I needed for my project, but they can be whatever is needed for you
icon_create_function = """
function(cluster) {
var childCount = cluster.getChildCount();
var c = ' marker-cluster-';
if (childCount < 50) {
c += 'large';
} else if (childCount < 300) {
c += 'medium';
} else {
c += 'small';
}
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
}
"""
#Create the marker cluster group, which organizes all the gps points put into it
marker_cluster_group = MarkerCluster(name='Cluster Icons', icon_create_function=icon_create_function)
#This is just a reference to a default google mapping icon, purely optional
pointIcon_url = "http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png"
#Create the icon object
icon = folium.features.CustomIcon(pointIcon_url, icon_size=(15, 15))
#Create the marker/gps point and add it to the cluster group
folium.Marker([40.058377, -99.939192], icon=icon).add_to(marker_cluster_group)
#Adding the cluster group to the map image
marker_cluster_group.add_to(mapImage)

Different colours edges in graphviz in Python

I am trying to draw graph with different colours edges by using graphviz in Python. I am creating colour list and using in edge colour. However, it looks like it does not support in graphviz. I am not sure how to set different colour of edges. Here is my code:
import graphviz as gv
d = gv.Digraph()
colors = ['green','red']
d.attr('edge', color = colors)
d.edge('hello','world')
d.edge('world','hello')
d.view()
Looking for valuable comments. Thanks
import graphviz as gv
colors = ['green','red']
def create_graph(colors, d):
d.edge('hello','world', color=colors[0])
d.edge('world','hello', color=colors[1])
d.view()
if __name__ == '__main__':
d = gv.Digraph()
create_graph(colors, d)
I don't really know the python wrapper for graphviz,but if by different colour of edges you mean multiple colors (?), you may try the following:
d.attr('edge', color = 'green:red')
Otherwise, if you'd like to have a green and a red edge, the following may work:
d.edge('hello','world', color='green' )
d.edge('world','hello', color='red' )

Categories

Resources