GeoPandas and Bokeh extract xs and ys from data - WorldMap - python

I found this post on Geopandas and bokeh extract xs and ys from data
What I need is basically the same thing but for the map of the whole world (extract XS and ys from GeoPandas and convert into bokeh readable format). I am struggling with the fact the world data has both polygons and multi polygons.
If anyone can help, that would be much appreciated.
Thanks!

This is how you can run a GeoJSON using pandas GeoJSONDataSource like I mentioned in my comment.
from bokeh.models import GeoJSONDataSource
from bokeh.plotting import figure, show, output_notebook
import geopandas as gp
output_notebook()
world = gp.read_file(gp.datasets.get_path('naturalearth_lowres'))
geo_source = GeoJSONDataSource(geojson=world.to_json())
p = figure(title='World', tooltips=[('Country', '#name')],
x_range=(-180, 180), y_range=(-90, 90),
x_axis_location=None, y_axis_location=None,
plot_width=1000, plot_height=500
)
p.patches('xs', 'ys', fill_alpha=0.4, fill_color='grey',
line_color='black', line_width=0.5, source=geo_source
)
show(p)
Output

Ok, so I solved it but it needs polishing. If you have any ideas how to improve, let me know. I am also running into a runtime error and that is either solved by uncommenting certain parts of code (marked in the code) or by downgrading bokeh. I have not tried downgrading bokeh, I just saw that answer somewhere.
(Also, I have never posted on SO before so I am not really sure how this whole thing works so be gentle).
https://github.com/nikosarcevic/GeoMapping

Related

Could Google Colab display Traditional Chinese fonts except "TaipeiSansTCBeta" in Matplotlib plots?

To whom it may concern:
Thank you for your time.
Here are some codes about drawing a matplotlib plot with Traditional-Chinese labels and legends which can work well in Colab.
import matplotlib as mpl,matplotlib.font_manager as mf,matplotlib.pyplot as plt
!wget -O TaipeiSansTCBeta-Regular.ttf https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download
mf.fontManager.addfont('TaipeiSansTCBeta-Regular.ttf')
mpl.rc('font',family='Taipei Sans TC Beta')
lg=("明度高","\n亮度高","頻率高","\n摩擦力小","密度大")
xt=("純墨條","高筋麵粉","在來米粉","鹽","洗碗精","小蘇打粉","酵母")
a=(-1.06166376,-2.56410256,-15.21126761,-19.04761905,35.2941176470)
b=(0,0,-9.15492958,-42.85714285714285714,29.4117647058)
c=(-6.67539267,-15.38461538,-45.49295775,-47.61904762,17.6470588235)
d=(-9.08958697,-20.5128205,15.21126761,9.52380952,11.7647058823)
e=(-7.86794648,-17.94871795,0,-17.94871795,11.7647058823)
f=(-3.25770797,-7.69230769,-6.05633803,-52.38095238,-5.882352941176)
x=(0,0,0,0,0)
yd=(x,a,b,c,d,e,f)
fig,ax=plt.subplots(figsize=(4,5),dpi=300)
for i in range(0,len(xt)):
ax.plot(lg,yd[i],label=xt[i],marker="o")
ptxk=["x-large","k"]
ax.tick_params(axis="x",labelsize=ptxk[0],colors=ptxk[1])
ax.tick_params(axis="y",labelsize="small")
ptt=["『定期定額』vs『定期定額逢低加碼』","x-large","k"]
ptlyl=["各\n變\n因\n較\n無\n添\n加\n墨\n百\n分\n比\n變\n化\n率\n(%)","x-large","darkcyan"]
plt.title(ptt[0],fontsize=ptt[1],color=ptt[2],y=-0.25)
ax.set_ylabel(ptlyl[0],fontsize=ptlyl[1],color=ptlyl[2],rotation=0)
ax.set_yticks([*range(-50,71,10)])
ax.yaxis.set_label_coords(-0.17,0.05)
ax.legend(fontsize="large")
ax.set_axisbelow(True)
plt.grid()
plt.show()
The words in labels and legends only work well with the font called "TaipeiSansTCBeta" like the following picture.
(https://i.stack.imgur.com/CJfas.png)
Could the font be changed to another one like "DFKai-SB", or it only supports "TaipeiSansTCBeta"?
Some information on the internet about this is to add the codes below to line 2, and delete the codes about !wget, font_manager, and mpl.rc. But it doesn't work at all by displaying blank blocks.
mpl.rcParams['font.family'] = 'DFKai-SB'
(https://i.stack.imgur.com/EmMdL.png)
Would you please inform some demonstrations about the problem, or giving some clues to figure out how it works?
So far haven't found any answer to change to another Chinese font in Colab with matplotlib. It's highly appreciate for your guidance.
Best wishes and great thanks,
wish you have a happy new year.

Is there a way to plot lines over a datashader plot in Bokeh (Python)?

I am working with relatively large datasets (approximately 10x20.000.000 data point), for which Datashader is a useful visualisation tool. To give more information in these visualisations, I would like to add lines showing averages/standarddeviations on top of this datashade figure. Does anyone know how this would be possible?
My current code:
from bokeh.plotting import figure
from bokeh.io import show
x = 'xcol'
y= 'ycol'
data = dataframe
fig = figure(x_axis_label=x, y_axis_label=y)
points = hv.Points(data[[x, y]], label=('Title'))
hd.datashade(points, cmap='crest')
What I would like to do is for example add the following line to the figure generated with the code above:
fig.line([1,10,20], [0, 1000,2000], line_width=4)
Thanks in advance.

How to plot addresses (Lat/Long) from a csv on JSON map.?

So I am trying to do something which seems relatively simple but is proving incredibly difficult. I have a .csv file with addresses and their correspondent latitude/longitude, I just want to plot those on a California JSON map like this one in python:
https://github.com/deldersveld/topojson/blob/master/countries/us-states/CA-06-california-counties.json
I've tried bubble maps, scatter maps, etc. but to no luck I keep getting all kind of errors :(. This is the closest I've got, but that uses a world map and can't zoom in effectively like that json map up there. I am still learning python so please go easy on me ><
import plotly.express as px
import pandas as pd
df = pd.read_csv(r"C:\Users\FT4\Desktop\FT Imported Data\Calimapdata.csv")
fig = px.scatter_geo(df,lat='Latitude',lon='Longitude', hover_name="lic_type", scope="usa")
fig.update_layout(title = 'World map', title_x=0.5)
fig.show()
If anyone could help me with this I would appreciate it. Thank you
your example link is just a GeoJSON geometry definition. Are you talking about a Choropleth?
If so, check out geopandas - you should be able to link your data to the polygons in the shape definition you linked to by reading it in with geojson and then joining on the shapes with sjoin. Once you have data tied to each geometry, you can plot with geopandas's .plot method. Check out the user guide for more info.
Something along these lines should work:
import geopandas as gpd, pandas as pd
geojson_raw_url = (
"https://raw.githubusercontent.com/deldersveld/topojson/"
"master/countries/us-states/CA-06-california-counties.json"
)
gdf = gpd.read_file(geojson_raw_url, engine="GeoJSON")
df = pd.read_csv(r"C:\Users\FT4\Desktop\FT Imported Data\Calimapdata.csv")
merged = gpd.sjoin(gdf, df, how='right')
# you could plot this directly with geopandas
merged.plot("lic_type")
alternatively, using #r-beginners' excellent answer to another question, we can plot with express:
fig = px.choropleth(merged, geojson=merged.geometry, locations=merged.index, color="lic_type")
fig.update_geos(fitbounds="locations", visible=False)
fig.show()

(Matplotlib, python) long subplots, scrolling

I would like to create a pdf file [by using plt.savefig("~~~.pdf")]
containing lots of (about 20) subplots
each of which is drawing timeseries data.
I am using a matplotlib library with python language.
Each subplot may be long, and I want to put the subplots
horizontally.
Therefore, the figure should be very long (horizontally), so the horizontal scroll bar should be needed!
Is there any way to do this?
some example code will be appreciated!
The following is my sample code.
I just wanted to draw 10 sine graphs arranged horizontally
and save it as pdf file.
(but I'm not pretty good at this. so the code may looks to be weird to you.. :( )
from matplotlib import pyplot as plt
import numpy as np
x=np.linspace(0,100,1000)
y=np.sin(x)
numplots=10
nr=1
nc=numplots
size_x=nc*50
size_y=size_x*3/4
fig=plt.figure(1,figsize=(size_x,size_y))
for i in range(nc):
ctr=i+1
ax=fig.add_subplot(nr,nc,ctr)
ax.plot(x,y)
plt.savefig("longplot.pdf")
plt.clf()
Thank you!
You should do that using the backend "matplotlib.backends.backend_pdf". This enables you to save matplotlib graphs in pdf format.
I have simplified your code a bit, here is a working example:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
x = np.linspace(0,100,1000)
y = np.sin(x)
nr = 10
nc = 1
for i in range(nr):
plt.subplot(nr, nc, i + 1)
plt.plot(x, y)
pdf = PdfPages('longplot.pdf')
pdf.savefig()
pdf.close()
I hope this helps.
In the link below there is a solution, which can help you, since it was helpful to me either.
Scrollbar on Matplotlib showing page
But if you have many subplots, I am afraid your problem won't be solved. Since it will shrink each graph anyway. In that case it will be better to break your graphs into smaller and separate parts.

Bokeh hover tooltip not displaying all data - Ipython notebook

I am experimenting with Bokeh and mixing pieces of code. I created the graph below from a Pandas DataFrame, which displays the graph correctly with all the tool elements I want. However, the tooltip is partially displaying the data.
Here is the graph:
Here is my code:
from bokeh.plotting import figure, show
from bokeh.io import output_notebook
from bokeh.models import HoverTool
from collections import OrderedDict
x = yearly_DF.index
y0 = yearly_DF.weight.values
y1 = yearly_DF.muscle_weight.values
y2 = yearly_DF.bodyfat_p.values
#output_notebook()
p = figure(plot_width=1000, plot_height=600,
tools="pan,box_zoom,reset,resize,save,crosshair,hover",
title="Annual Weight Change",
x_axis_label='Year',
y_axis_label='Weight',
toolbar_location="left"
)
hover = p.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([('Year', '#x'),('Total Weight', '#y0'), ('Muscle Mass', '$y1'), ('BodyFat','$y2')])
output_notebook()
p.line(x, y0, legend="Weight")
p.line(x, y1, legend="Muscle Mass", line_color="red")
show(p)
I have tested with Firefox 39.0, Chrome 43.0.2357.130 (64-bit) and Safari Version 8.0.7. I have cleared the cache and I get the same error in all browsers. Also I did pip install bokeh --upgrade to make sure I have the latest version running.
Try using ColumnDataSource.
Hover tool needs to have access to the data source so that it can display info.
#x, #y are the x-y values in data unit. (# prefix is special, can only followed by a limited set of variable, #y2 is not one of them)., Normally I would use $+ column_name to display the value of my interest, such as $weight. See here for more info.
Besides, I am surprised that the hover would appear at all. As I thought hoverTool doesn't work with line glyph, as noted here
Try the following : (I haven't tested, might have typos).
df = yearly_DF.reset_index() # move index to column.
source = ColumnDataSource(ColumnDataSource.from_df(df)
hover.tooltips = OrderedDict([('x', '#x'),('y', '#y'), ('year', '$index'), ('weight','$weight'), ('muscle_weight','$muscle_weight'), ('body_fat','$bodyfat_p')])
p.line(x='index', y='weight', source=source, legend="Weight")
p.line(x='index', y='muscle_weight', source=source, legend="Muscle Mass", line_color="red")
Are you using Firefox? This was a reported issue with some older versions of FF:
https://github.com/bokeh/bokeh/issues/1981
https://github.com/bokeh/bokeh/issues/2122
Upgrading FF resolved the issue.

Categories

Resources