Seaborn diverging_palette(): colours appear different than expected - seaborn

I'm trying to create a Seaborn heatmap() of a correlation matrix using a custom diverging_palette(). I'd like to have 100% red at the extremes, and 100% white at the center.
I used the code below, but I get pink at the extremes and light-grey at the center (see screenshot). I'd say hsl(0, 100%, 50%) should give red? What am I missing?
corr_matrix = ames_train_cleaned.select_dtypes(include=[np.number]).corr()
fig, ax = plt.subplots(figsize=(15,15))
my_palette = sns.diverging_palette(h_neg=0, h_pos=0, s=100, l=50, sep=100, as_cmap=True)
_ = sns.heatmap(data=corr_matrix,
ax=ax,
mask=np.triu(corr_matrix, k=1),
cmap=my_palette,
center=0)

Answering my own question... I found this Q&A on StackOverflow which pointed me in the right direction.
Seaborn diverging_palette with more than 2 color tones
Replaced the definition of my_palette in my code-snippet with this:
my_palette = LinearSegmentedColormap.from_list(name='dummy', colors=['blue','white','red'])
This works perfectly, but I'm still not sure why the red wasn't red in my initial solution...

Related

Add location marker on plotted Geopandas Dataframe using Folium

Context
I have an merged geodataframe of 1). Postalcode areas and 2). total amount of deliveries within that postalcode area in the city of Groningen called results. The geodataframe includes geometry that include Polygons and Multiploygons visualizing different Postal code areas within the city.
I am new to GeoPandas and therefore I've tried different tutorials including this one from the geopandas official website wherein I got introduced into interactive Folium maps, which I really like. I was able to plot my geodataframe using result.explore(), which resulted in the following map
The problem
So far so good, but now I want to simply place an marker using the folium libarty with the goal to calculate the distance between the marker and the postalcode areas. After some looking on the internet I found out in the quickstart guild that you need to create an folium.Map, then you need folium.Choropleth for my geodataframe and folium.Marker and add them to the folium.Map.
m = folium.Map(location=[53.21917, 6.56667], zoom_start=15)
folium.Marker(
[53.210903, 6.598276],
popup="My marker"
).add_to(m)
folium.Choropleth(results, data=results, columns="Postcode", fill_color='OrRd', name="Postalcode areas").add_to(m)
folium.LayerControl().add_to(m)
m
But when try to run the above code I get the following error:
What is the (possible) best way?
Besides my failing code (which would be great if someone could help me out). I am curious if this is the way to do it (Folium map + marker + choropleth). Is it not possible to call geodataframe.explore() which results into the map in second picture and then just add an marker on the same map? I have the feeling that I am making it too difficult, there must be an better solution using Geopandas.
you have not provided the geometry. Have found postal districts of Netherlands and used that
explore() supports will draw a point as a marker with appropriate parameters
hence two layers,
one is postal areas coloured using number of deliveries
second is point, with distance to each area calculated
import geopandas as gpd
import shapely.geometry
import pandas as pd
import numpy as np
geo_url = "https://geodata.nationaalgeoregister.nl/cbsgebiedsindelingen/wfs?request=GetFeature&service=WFS&version=2.0.0&typeName=cbs_provincie_2017_gegeneraliseerd&outputFormat=json"
gdf = gpd.read_file(geo_url).assign(
deliveries=lambda d: np.random.randint(10**4, 10**6, len(d))
)
p = gpd.GeoSeries(shapely.geometry.Point(6.598276, 53.210903), crs="epsg:4386")
# calc distances to point
gdf["distance"] = gdf.distance(p.to_crs(gdf.crs).values[0])
# dataframe of flattened distances
dfp = pd.DataFrame(
[
"<br>".join(
[f"{a} - {b:.2f}" for a, b in gdf.loc[:, ["statcode", "distance"]].values]
)
],
columns=["info"],
)
# generate colored choropleth
m = gdf.explore(
column="deliveries", categorical=True, legend=False, height=400, width=400
)
# add marker with distances
gpd.GeoDataFrame(
geometry=p,
data=dfp,
).explore(m=m, marker_type="marker")

PIL: Imageobject.save() after drawing completely corrupts images and smurfs the ouput

I have these two functions in my program:
def depict_ph_increase(x,y,color, imobject):
program_print(color)
draw = PIL.ImageDraw.Draw(imobject)
draw.text((x, y),color,(255,255,255))
imobject.save('tmp-out.gif')
im_temp = PIL.Image.open("tmp-out.gif")#.convert2byte()
im_temp = im_temp.resize((930, 340), PIL.Image.ANTIALIAS)
MAP_temp = ImageTk.PhotoImage(im_temp)
map_display_temp = Label(main, image=MAP_temp)
map_display_temp.image = MAP_temp # keep a reference!
map_display_temp.grid(row=4,column=2, columnspan=3)
def read_temp_pixels(temperature_file, rngup, rngdown):
temp_image_object = PIL.Image.open(temperature_file)
(length, width) = get_image_size(temp_image_object)
(rngxleft, rngxright) = rngup
(rngyup,rngydown) = rngdown
print 'the length and width is'
print length, width
hotspots = 5;
for hotspot in range(0,hotspots):
color = "#ffffff"
while color == "#ffffff" or color == "#000000" or color == "#505050" or color == "#969696":
yc = random.randint(rngxleft, rngxright)
xc = random.randint(rngyup,rngydown)
color = convert_RGB_HEX(get_pixel_color(temp_image_object, xc, yc))
depict_ph_increase(xc,yc,color, temp_image_object)
The bottom one calls the top one. Their job is to read in this image:
It then randomly selects a few pixels, grabs their colors, and writes the hex values of the colors on top. But, when it redisplays the image, it gives me this garbage:
Those white numbers up near the upper right corner are the hex values its drawing. Its somehow reading the values from the corrupted image, despite the fact that I don't collect the values until AFTER I actually call the ImageDraw() method. Can someone explain to me why it is corrupting the image?
Some background--the get_pixel_color() function is used several other times in the program and is highly accurate, its just reading the pixel data from the newly corrupted image somehow. Furthermore, I do similar image reading (but not writing) at other points in my code.
If there is anything I can clarify, or any other part of my code you want to see, please let me know. You can also view the program in its entirety at my github here: https://github.com/jrfarah/coral/blob/master/src/realtime.py It should be commit #29.
Other SO questions I have examined, to no avail: Corrupted image is being saved with PIL
Any help would be greatly appreciated!
I fixed the problem by editing this line:
temp_image_object = PIL.Image.open(temperature_file)
to be
temp_image_object = PIL.Image.open(temperature_file).convert('RGB')

Can't make image_url work in Bokeh (Python)

I tried to reproduce the solution from: How do I work with images in Bokeh (Python) , but it doesn't work. For that, I find an image on the net and put it in place of the 'url' field but the plot is just blank! From the original solution bokeh ask me to add up w and h params which I suppose are the width and height of the pic. Also I dropped x_range and y_range within figure() to wipe out the horizontal and vertical lines of the plot.
from bokeh.plotting import figure, show, output_notebook
output_notebook()
p = figure()
p.image_url( url=[ "http://pngimg.com/uploads/palm_tree/palm_tree_PNG2504.png"],
x=1, y=1, w=253, h=409)
show( p)
Anyone could tell me what's going on ?
Bokeh can't auto-range ImageURL it seems. So if there are no other glyphs, you need to provide explicit ranges. Additionlly, the default anchor is upper_left IIRC so it may be that our image is rendering off-canvas and you don't realize it. The code below works with Bokeh 0.12.5:
from bokeh.plotting import figure, show, output_file
output_file("foo.html")
p = figure(x_range=(0,500), y_range=(0,500))
p.image_url( url=[ "http://pngimg.com/uploads/palm_tree/palm_tree_PNG2504.png"],
x=1, y=1, w=253, h=409, anchor="bottom_left")
show(p)
Without the anchor set, the image plots blow the plot region (have to pan to see it)

Change water color in d3 orthographic transition map

I am new to D3 and this is my first question to stackoverflow.
I am trying to change the color of the water in this example that contains transitions:
http://bl.ocks.org/mbostock/4183330
I am able to change the color in this example, which is static: http://bl.ocks.org/mbostock/3757125
I found this thread: How can I color ocean with topojson in d3 when I have coordinate info for land? However, this changes the area outside of the globe as well.
This section of the code appears to be the styling, but I can't figure what to add to change the water color.
c.fillStyle = "#bbb", c.beginPath(), path(land), c.fill();
c.fillStyle = "#f00", c.beginPath(), path(countries[i]), c.fill();
c.strokeStyle = "#fff", c.lineWidth = .5, c.beginPath(), path(borders), c.stroke();
c.strokeStyle = "#000", c.lineWidth = 2, c.beginPath(), path(globe), c.stroke();
Also, seeing the line of code below, I searched online for a reference list of possible topojson features and/or objects that might indicate water, and maybe I could figure out how to style that, but couldn't find one:
land = topojson.feature(world, world.objects.land),
I'm wondering if maybe this has something to do with canvas (which I don't really grasp).
Hopefully, I'm overlooking something obvious and noob-like.
Thanks much!
Ha! Of course:
Modify this line:
c.strokeStyle = "#ccc", c.lineWidth = .5 * ratio, c.beginPath(), path(globe), c.stroke();
To this:
c.fillStyle = "#000", c.beginPath(), path(globe), c.fill();
I feel silly, but I guess sometimes it takes writing it all out for the brain cells to click. Thanks!

matlab: texture classification

I have a histology image like this:
From the image, we can observe there are two kinds of different cells.
and
Is there any way that I can separate these two types of cells into two groups?
How about using your raw image and previous code to achieve this?
% % % your old code
I=imread(file);
t1=graythresh(I);
k1=im2bw(I,t1);
k1=~k1;
se = strel('disk',1);
k0=imfill(~k1,'holes');
cc = conncomp(k0);
k0(cc.PixelIdxList{1})=0;
k1=imfill(k1,'holes');
mask=k0 | k1;
%%%%%%%%%%%%%%%%%%
This will give you:
I=rgb2hsv(I);
I=double(I);
I1=I(:,:,1); % again, the channel that can maximizing the margin between donut and full circle
Imask=(I1-0.2).*(I1-0.9)<0;
k2=mask-Imask;
k2=bwareaopen(k2,100);
This will give you:
k2=mask-Imask;
I2=zeros(size(I1,1),size(I1,2),3);
I2(:,:,1)=(k2==1)*255;
I2(:,:,3)=((I1-0.2).*(I1-0.9)<0)*255;
imshow(I2)
will finally give you (the two types are stored in two channels in the rgb image):
I would use regionprops
props=regionprops(YourBinaryImage, 'Solidity');
The objects with a high solidity will be the disks, those with a lower solidity will be the circles.
(Edit) More formally:
I=imread('yourimage.jpg');
Bw=~im2bw(I, 0.5);
BWnobord = imclearborder(Bw, 4); % clears the partial objects
Props=regionprops(BWnobord, 'All');
solidity=cell2mat({Props.Solidity});
Images={Props.Image};
Access the elements of Images where the value in solidity is higher than 0.9 and you get your disks. The circles are the other ones.
Hope it helps

Resources