对于分布不均的数据,几乎所有点的颜色都太相似了。例如。下图表示与value < 12000
对应的浅色。
因此,我考虑使用 Pysal 将数据范围分成几个类,并将色彩图均匀地分配给这些类。
这是我的尝试
Lat
是每个点的纬度Lon
是每个点的经度Value
是与每个点对应的属性,我想用不同的标记颜色和大小绘制它from pysal.esda.mapclassify import Natural_Breaks as nb
import pysal.esda.mapclassify as mpc
from matplotlib.colors import Normalize
my_bins = [ 20,200,600,1600, 4000, 36000]
breaks =mpc.User_Defined(value,my_bins)
bin_labels = ["%0.0f" % b for b in breaks.bins]
bins = pd.DataFrame({'Class': breaks.yb},)
然后,每个点都有一个基于其值的数据范围的类。
fig = plt.figure()
ax =plt.subplot()
cmap = plt.get_cmap('coolwarm')
norm1 = Normalize(vmin=bins['Class'].min(), vmax=bins['Class'].max())
em_plot = plt.scatter(px[:],py[:], linewidth='0',c =
np.array(bins['Class']),s =(value**0.4)*10, cmap = cmap,\
norm = norm1,alpha = 0.7)
cbaxes = fig.add_axes([0.6625, 0.175, 0.175, 0.04])
cbar = plt.colorbar(em_plot,cax=cbaxes,orientation='horizontal')
value_list = np.array([1,3,5,]) ### THE CLASS
value_label = ['200', '1600','36000'] ### THE VALUE CORRESPONDING TO CLASS
cbar.set_ticks(value_list)
cbar.set_ticklabels(value_label)
cbar.ax.tick_params(labelsize=8)
我希望用离散圆圈标记散点图,而不是条形样式颜色图例:每个圆圈代表主图上特定值的大小和颜色。
我在互联网上找到的插图如下所示:
如上图所示,不同颜色的percentage
图例将是我理想的目标!
任何建议都会受到赞赏!
感谢您的回答。我试过你的方法。但似乎并不完全符合我的目标。
这是我的数字,以答案为参考。
从图例和颜色栏,我们发现由于不同的映射策略(颜色栏 - &gt;分类结果;图例 - &gt;真实值),颜色不一样
然后,我做了一些这样的调整:
cmap = plt.get_cmap('coolwarm')
colors=cmap(np.arange(6)/6.0)
ls = [Line2D(range(1), range(1), linewidth=0,
color=colors[np.where(np.array(my_bins) == v)[0]], \
marker='o', ms=(v**0.2)*2) for v in my_bins]
plt.legend(ls,my_bins)
但它出了问题:
ValueError:to_rgba:无效的rgba arg&#34; [[0.2298057 0.29871797 0.75368315 1.]]&#34; rgba序列的长度应为3或4
感谢Davis的回答,我想生成my_bins
元素的索引。所以,我试图通过使用np.where(my_bins == element)来获得指数
但它失败了。然后,我尝试使用:
..., color = colors[i], ms=(v**0.2)*2) for i,v in enumerate(my_bins)
有效!
答案 0 :(得分:1)
我认为“最简单”就是为你的传奇创建一个proxy artist。
以下是有效的,但需要根据您的需要进行调整,我不确定色彩图的标准化和点的大小是否正确。
from matplotlib.lines import Line2D
cmap = plt.get_cmap('coolwarm')
my_bins = [20,200,600,1600, 4000, 36000]
ls = [Line2D(range(1), range(1), linewidth=0, color=cmap(v), marker='o', ms=(v**0.2)) for v in my_bins]
plt.plot()
plt.legend(ls,my_bins)
<强>更新强>
关于您更新的问题:您的问题是color=colors[np.where(np.array(my_bins) == v)[0]]
。说实话,我不知道你在这里想做什么。您应该传递(6, 4)
数组,但是您传递了(1, 4)
数组。
如果我理解你的代码,你应该试试这个:
cmap = plt.get_cmap('coolwarm')
colors=cmap(np.arange(6)/6.0)
ls = [Line2D(range(1), range(1), linewidth=0,
color=colors[i], \
marker='o', ms=(v**0.2)*2) for i,v in enumerate(my_bins)]
plt.legend(ls,my_bins)