Basemap: Get all data points on colorbar which each point refelecting the ploted color
Question:
I have a dataset, containing different types of trees in numerical i.e
Types = 4,8,9,10,13,15,19,33
I am plotting these types on a scatter plot, each type being represented by a different color. I can’t figure out a way for the color bar to represent the data correctly. So that it looks like this.
The color bar ticks should only represent the data plotted with each color representing a type. i.e
Green = 4
Orange = 8
etc
The plot below is my failed attempt at doing this. The colorbar ticks do not represent the vegetation plotted but a range.
fig = plt.figure()
plt.figure(figsize=(25,10))
m=Basemap(projection='mill',llcrnrlat=25,llcrnrlon=-130,urcrnrlat=49,urcrnrlon=-104.5,resolution='l')
m.drawcoastlines()
m.drawcountries()
m.drawstates()
x,y=m(list(Y60['col']),list(Y60['row']))
m.scatter(x,y,c=Y60['potveg'],s=Y60['potveg']*5,cmap='Dark2')
cbar=plt.color bar()
Thanks
Answers:
My answer focuses on the steps to create the legend. Read the comments in the code for explanation.
import matplotlib.pyplot as plt
# Each item of legends requires 3 propereties: color/label_text/marker_shape
colors = ["green", "orange", "purple", "red", "lightgreen", "gray"]
texts = ["4", "9", "13", "15", "19", "33"]
markers = ["o", "o", "o", "o", "o", "o"]
len0 = len(colors)
# Points' locations and attributes
xs = [3,2,4,5,4,2,7,3]
ys = [41,12,32,15,35,21,23,43]
colors1 = ["green", "orange", "purple", "red", "lightgreen", "gray", "green", "orange"]
texts1 = ["4", "9", "13", "15", "19", "33", "4", "9"]
markers1 = ["o", "o", "o", "o", "o", "o", "o", "o"]
sizes1 = [8,16,9,12,7,4,10,6]
len1 = len(xs)
# Plot `none` data point and
# save the output patches objects for legend making
patches0 = [ plt.plot([],[], marker=markers[i], ms=8, ls="", mec=None, color=colors[i],
label="{:s}".format(texts[i]) )[0]
for i in range(len0) ]
# Plot point data
# Demo data is used here
for i in range(len1):
plt.plot(xs[i], ys[i], marker=markers1[i], ms=sizes1[i], color=colors1[i])
# Plot legend in the upper-right corner
plt.legend(handles=patches0, bbox_to_anchor=(1, 1), title="Potveg",
loc='upper right', ncol=1, facecolor="lightgray", numpoints=1 )
plt.show()
Edit1
Since the data has categories and quantities information to render on the plot, my answer is not complete without handling both of them.
The code to produce 2 legends on a single plot is not straight forward as one may think.
import matplotlib.pyplot as plt
# For `Categories` symbol
# ----------------
# Each item of legends requires 3 propereties: color/label_text/marker_shape
color_V = ["green", "orange", "purple", "red", "lightgreen", "gray"]
text_V = ["4", "9", "13", "15", "19", "33"]
marker_V = ["o", "o", "o", "o", "o", "o"]
len_V = len(color_V)
# For `Size/quantities` symbol
# --------------------
color_S = ["gray", "gray", "gray", "gray"]
sizes_S = [4, 8, 12, 16] #increasing values ...
text_S = ["4", "8", "12", "16"] # cover `sizes1` below
marker_S = ["o", "o", "o", "o"] #use disk shape
len_S = len(color_S)
# Data locations and attributes
xs = [3,2,4,5,4,2,7,3]
ys = [41,12,32,15,35,21,23,43]
colors1 = ["green", "orange", "purple", "red", "lightgreen", "gray", "green", "orange"]
texts1 = ["4", "9", "13", "15", "19", "33", "4", "9"]
markers1 = ["o", "o", "o", "o", "o", "o", "o", "o"]
sizes1 = [8,16,9,12,7,4,10,6]
len1 = len(xs)
# Plot `none` data point and
# save the output patches objects for legend making
patches_V = [ plt.plot([],[], marker=marker_V[i], ms=8, ls="", color=color_V[i],
label="{:s}".format(text_V[i]) )[0]
for i in range(len_V) ]
# Do it again for another legend
patches_S = [ plt.plot([],[], marker=marker_S[i], ms=sizes_S[i], ls="",
color=color_S[i],
label="{:s}".format(text_S[i]) )[0] for i in range(len_S) ]
# Plot point data
# Demo data is used here
for i in range(len1):
plt.plot(xs[i], ys[i], marker=markers1[i], ms=sizes1[i], color=colors1[i])
# Plot 1st legend in the upper-right corner
first_legend = plt.legend(handles=patches_V, bbox_to_anchor=(1, 1), title="Categories",
loc='upper right', ncol=1, facecolor="lightgray", numpoints=1 )
# Need to freeze first legend to enable addition of the second legend by ...
# Add the legend manually to the current Axes
plt.gca().add_artist(first_legend)
# Then we can add the second legend normally
plt.legend(handles=patches_S, bbox_to_anchor=(0, 1), title="Sizes",
loc='upper left', ncol=1, facecolor="lightgray", numpoints=1 )
plt.show()
I have a dataset, containing different types of trees in numerical i.e
Types = 4,8,9,10,13,15,19,33
I am plotting these types on a scatter plot, each type being represented by a different color. I can’t figure out a way for the color bar to represent the data correctly. So that it looks like this.
The color bar ticks should only represent the data plotted with each color representing a type. i.e
Green = 4
Orange = 8
etc
The plot below is my failed attempt at doing this. The colorbar ticks do not represent the vegetation plotted but a range.
fig = plt.figure()
plt.figure(figsize=(25,10))
m=Basemap(projection='mill',llcrnrlat=25,llcrnrlon=-130,urcrnrlat=49,urcrnrlon=-104.5,resolution='l')
m.drawcoastlines()
m.drawcountries()
m.drawstates()
x,y=m(list(Y60['col']),list(Y60['row']))
m.scatter(x,y,c=Y60['potveg'],s=Y60['potveg']*5,cmap='Dark2')
cbar=plt.color bar()
Thanks
My answer focuses on the steps to create the legend. Read the comments in the code for explanation.
import matplotlib.pyplot as plt
# Each item of legends requires 3 propereties: color/label_text/marker_shape
colors = ["green", "orange", "purple", "red", "lightgreen", "gray"]
texts = ["4", "9", "13", "15", "19", "33"]
markers = ["o", "o", "o", "o", "o", "o"]
len0 = len(colors)
# Points' locations and attributes
xs = [3,2,4,5,4,2,7,3]
ys = [41,12,32,15,35,21,23,43]
colors1 = ["green", "orange", "purple", "red", "lightgreen", "gray", "green", "orange"]
texts1 = ["4", "9", "13", "15", "19", "33", "4", "9"]
markers1 = ["o", "o", "o", "o", "o", "o", "o", "o"]
sizes1 = [8,16,9,12,7,4,10,6]
len1 = len(xs)
# Plot `none` data point and
# save the output patches objects for legend making
patches0 = [ plt.plot([],[], marker=markers[i], ms=8, ls="", mec=None, color=colors[i],
label="{:s}".format(texts[i]) )[0]
for i in range(len0) ]
# Plot point data
# Demo data is used here
for i in range(len1):
plt.plot(xs[i], ys[i], marker=markers1[i], ms=sizes1[i], color=colors1[i])
# Plot legend in the upper-right corner
plt.legend(handles=patches0, bbox_to_anchor=(1, 1), title="Potveg",
loc='upper right', ncol=1, facecolor="lightgray", numpoints=1 )
plt.show()
Edit1
Since the data has categories and quantities information to render on the plot, my answer is not complete without handling both of them.
The code to produce 2 legends on a single plot is not straight forward as one may think.
import matplotlib.pyplot as plt
# For `Categories` symbol
# ----------------
# Each item of legends requires 3 propereties: color/label_text/marker_shape
color_V = ["green", "orange", "purple", "red", "lightgreen", "gray"]
text_V = ["4", "9", "13", "15", "19", "33"]
marker_V = ["o", "o", "o", "o", "o", "o"]
len_V = len(color_V)
# For `Size/quantities` symbol
# --------------------
color_S = ["gray", "gray", "gray", "gray"]
sizes_S = [4, 8, 12, 16] #increasing values ...
text_S = ["4", "8", "12", "16"] # cover `sizes1` below
marker_S = ["o", "o", "o", "o"] #use disk shape
len_S = len(color_S)
# Data locations and attributes
xs = [3,2,4,5,4,2,7,3]
ys = [41,12,32,15,35,21,23,43]
colors1 = ["green", "orange", "purple", "red", "lightgreen", "gray", "green", "orange"]
texts1 = ["4", "9", "13", "15", "19", "33", "4", "9"]
markers1 = ["o", "o", "o", "o", "o", "o", "o", "o"]
sizes1 = [8,16,9,12,7,4,10,6]
len1 = len(xs)
# Plot `none` data point and
# save the output patches objects for legend making
patches_V = [ plt.plot([],[], marker=marker_V[i], ms=8, ls="", color=color_V[i],
label="{:s}".format(text_V[i]) )[0]
for i in range(len_V) ]
# Do it again for another legend
patches_S = [ plt.plot([],[], marker=marker_S[i], ms=sizes_S[i], ls="",
color=color_S[i],
label="{:s}".format(text_S[i]) )[0] for i in range(len_S) ]
# Plot point data
# Demo data is used here
for i in range(len1):
plt.plot(xs[i], ys[i], marker=markers1[i], ms=sizes1[i], color=colors1[i])
# Plot 1st legend in the upper-right corner
first_legend = plt.legend(handles=patches_V, bbox_to_anchor=(1, 1), title="Categories",
loc='upper right', ncol=1, facecolor="lightgray", numpoints=1 )
# Need to freeze first legend to enable addition of the second legend by ...
# Add the legend manually to the current Axes
plt.gca().add_artist(first_legend)
# Then we can add the second legend normally
plt.legend(handles=patches_S, bbox_to_anchor=(0, 1), title="Sizes",
loc='upper left', ncol=1, facecolor="lightgray", numpoints=1 )
plt.show()