• Y
  • List All
  • Feedback
    • This Project
    • All Projects
Profile Account settings Log out
  • Favorite
  • Project
  • All
Loading...
  • Log in
  • Sign up
yjyoon / Choropleth_Chart_Function star
  • Project homeH
  • CodeC
  • IssueI
  • Pull requestP
  • Review R
  • MilestoneM
  • BoardB 1
  • Files
  • Commit
  • Branches
Choropleth_Chart_Functionchoropleth.py
Download as .zip file
File name
Commit message
Commit date
.idea
renamed and cleared unused codes
2023-06-14
algorithms
separated voronoi based algorithm that was used for text placement and size optimizer. However, since this same algorithm can be used for other applications like finding the optimal placement of say, any facilities, this function is separated.
2023-06-14
data
forget the example data
2023-06-14
map
missing files
2023-06-13
opensourcecode
moved opensource code into other folder. do not mix it.
2023-06-14
output
Added example output image
2023-06-14
README.md
Update README.md
2023-06-14
choropleth.py
fixed a bug
2023-06-14
example.py
font_names.py is from stack overflow, thus moved to seperate folder with license compliance. DO NOT MIX IT UP.
2023-06-14
juni 2023-06-14 10f7df9 fixed a bug UNIX
Raw Open in browser Change history
import os import io from PIL import Image import numpy as np import plotly.express as px import plotly.graph_objects as go import cv2 from algorithms.voronoi import get_lecc # import matplotlib.pyplot as plt # debugging sep = os.path.sep def extract(lst, i): return [item[i] for item in lst] def plotly_fig2array(fig, scale): # convert Plotly fig to an array fig_bytes = fig.to_image(format="png", width=2000, height=800, scale=scale) buf = io.BytesIO(fig_bytes) img = Image.open(buf) return np.asarray(img) def choropleth_chart(shp, df, title, save_dir, colorscheme="BuGn", show_legend=True, unit='', adaptive_legend_font_size=False, geo_annot_scale = 1500, font="Open Sans", scale=4, save=True): f""" shp : geopandas datastream from .shp, .shx and .dbf must exist in the same folder df : single column of pandas DataFrame or any other iterable, height must be the number of object of shp title : title of the chart save_dir : save directory from 'figure/save_dir.png' colorscheme : either string of predefined plotly colorscheme or your colorscheme that is iterate of colors show_legend : Boolean, self explainatory adaptive_legend_font_size : legend of regions become adaptive using voronoi algorithm, asserting the biggest annotation adaptive to the size of the region If false, there will be no annotation over region This, takes some time and could be improved if you could simplify polygons, which is not implemented. font : Defaults to the default plotly font(Open Sans) if None. Type font name string if you need. Execute font_names.py if you want to see the names of the font that python env recognizes. scale : the larger the better save : Boolean, default is True. To save or not to save. """ # TODO add more settings num_area = len(shp) cent_pnt = [None] * num_area for i, cent in enumerate(shp.centroid): cent_pnt[i] = [cent.x, cent.y] cent_map_x = sum(extract(cent_pnt, 0)) / num_area cent_map_y = sum(extract(cent_pnt, 1)) / num_area lecc = None lecc_dist = None if adaptive_legend_font_size: lecc, lecc_dist = get_lecc(shp) # draw the choropleth fig = px.choropleth( # draw shp map shp.set_index("EMD_KOR_NM"), locations=shp.index, # names geojson=shp.geometry, # geojson shape color=df, # a row vector of data color_continuous_scale=colorscheme, center=dict(lat=cent_map_y, lon=cent_map_x), range_color=[0, max(df)], ) fig.update_coloraxes( colorbar=dict( title=dict( text="", font=dict( size=30 ), ), xanchor="left", x=0.235, tickfont=dict( size=20 ), # tickformat=".0%" # put tickformat for later uses? ), ) if show_legend: if adaptive_legend_font_size: annotation_text_size = np.multiply(lecc_dist, geo_annot_scale) fig.add_trace( go.Scattergeo( # draw region names based on lat and lon lat=extract(lecc, 1), lon=extract(lecc, 0), # lat=cent_pnt_y, lon=cent_pnt_x, marker={ "size": [0] * num_area, }, mode="text", name="", text=shp["EMD_KOR_NM"].values, textposition=["middle center"] * num_area, textfont={ # "color": ["Black"] * num_area, "family": [f"{font}"] * num_area, "size": annotation_text_size, } ) ) else: annotation_text_size = [40] * num_area fig.add_trace( go.Scattergeo( # draw region names based on lat and lon lat=extract(cent_pnt, 1), lon=extract(cent_pnt, 0), # lat=cent_pnt_y, lon=cent_pnt_x, marker={ "size": [0] * num_area, }, mode="text", name="", text=shp["EMD_KOR_NM"].values, textposition=["middle center"] * num_area, textfont={ # "color": ["Black"] * num_area, "family": [f"{font}"] * num_area, "size": annotation_text_size, } ) ) # testing with more annotation, such as putting numbers. # fig.add_trace(go.Scattergeo( # # draw region names based on lat and lon # lat=extract(lecc, 1), lon=extract(lecc, 0), # # lat=cent_pnt_y, lon=cent_pnt_x, # marker={ # "size": [0] * num_area, # }, # mode="text", # name="", # text=df, # textposition=["bottom center"] * num_area, # textfont={ # "color": ["Black"] * num_area, # "family": ["Open Sans"] * num_area, # "size": annotation_text_size*0.6, # } # )) fig.update_traces(marker_line_width=3, marker_line_color='white') fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0}) fig.update_annotations(showarrow=False, visible=True) fig.update_geos(fitbounds="locations", visible=False) fig.update_layout( legend=dict( yanchor="top", y=0.99, xanchor="left", x=0.01 ) ) fig.update_layout( title_text=f"{title}", ) fig.update_layout( font=dict({'family': f'{font}'}) ) fig.update_layout( coloraxis_colorbar=dict( title=f"단위 : {unit}", ) ) # fig.show() # debug if save: # because plotly does not have any methods to adjust geojson object. fig.update_layout( title=dict( yanchor="top", y=0.98, xanchor="left", x=0.32, font_size=40, font_color="Black" ), ) # slicing static image because there is no way to adjust geojson object there. img = plotly_fig2array(fig, scale) img = img[:, 460*scale : 1500*scale] p = f"{save_dir}" cv2.imwrite(p, cv2.cvtColor(img, cv2.COLOR_RGB2BGR)) print(f"saved at : {p}") else: return fig

          
        
    
    
Copyright Yona authors & © NAVER Corp. & NAVER LABS Supported by NAVER CLOUD PLATFORM

or
Sign in with github login with Google Sign in with Google
Reset password | Sign up