更改Geopandas Choropleth地图图例的输入顺序

时间:2019-01-25 17:39:24

标签: python matplotlib legend geopandas choropleth

我正在城市地图上绘制某种分类值。我用来绘制的代码行如下:

fig = plt.figure(figsize=(12, 12))
ax = plt.gca()
urban_data.plot(column="category", cmap="viridis", ax=ax, categorical=True, /
                k=4, legend=True, linewidth=0.5, /
                legend_kwds={'fontsize':'19', 'loc':'lower left'}) 

其中城市数据是地理大熊猫的数据框,我正在使用matplotlib作为绘图库。自变量legend_kwds允许我控制图例上的次要内容,例如位置或字体大小,但我不能决定主要内容,例如图例框中条目的顺序。实际上,我的类别是排名,例如1-2-3-4,但是我总是以不同的顺序显示它们。

是否可以对图例进行更多控制?例如通过调用gdf.plot()函数 outside ?而且,如果是这样,我如何将图例中的颜色与地图中的颜色进行匹配,这些颜色是翠绿颜色图的离散值(我不清楚)?


编辑:这是一个可验证的示例。不幸的是,shapefile需要其他文件才能工作,这里需要geometry(区域,而不是点)列,因此我不得不请您下载美国的this shpfile。您需要的所有内容都在此文件夹中。这是重现该问题的代码。输出中的图很糟糕,因为我不在乎这里的坐标系,但重要的是图例。

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt 

gdf=gpd.read_file('.../USA_adm1.shp')
clusters=np.random.randint(0,4, size=52)
gdf['cluster']=clusters
clusdict={1: 'lower-middle', 2: 'upper-middle', 3: 'upper', 0: 'lower'}
gdf['cluster']=gdf['cluster'].map(clusdict)

fig = plt.figure(figsize=(12, 12))
ax = plt.gca()
gdf.plot(column='cluster',cmap='viridis', categorical=True, legend=True, ax=ax)

3 个答案:

答案 0 :(得分:1)

坏消息是,由大熊猫构成的传说中的类别已经过排序,并且经过了硬编码(see source-code here)。

因此,一种解决方案是拥有类别列,以便如果对其进行排序,它将与所需的顺序相对应。为此,使用整数似乎很好。一旦按照正确的顺序产生,就可以替换图例中的名称。

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt 

gdf=gpd.read_file('data/USA_adm/USA_adm1.shp')
clusters=np.random.randint(0,4, size=52)
gdf['cluster']=clusters
clusdict={1: 'lower-middle', 2: 'upper-middle', 3: 'upper', 0: 'lower'}

fig = plt.figure(figsize=(12, 12))
ax = plt.gca()
gdf.plot(column='cluster',cmap='viridis', categorical=True, legend=True, ax=ax)

def replace_legend_items(legend, mapping):
    for txt in legend.texts:
        for k,v in mapping.items():
            if txt.get_text() == str(k):
                txt.set_text(v)

replace_legend_items(ax.get_legend(), clusdict)

plt.show()

enter image description here

答案 1 :(得分:1)

我不得不稍微更改@ImportanceOfBeingErnest 接受的答案(函数中的第二行)才能使其正常工作(也许此后已经进行了更新),

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt 

gdf=gpd.read_file('data/USA_adm/USA_adm1.shp')
clusters=np.random.randint(0,4, size=52)
gdf['cluster']=clusters
clusdict={1: 'lower-middle', 2: 'upper-middle', 3: 'upper', 0: 'lower'}

fig = plt.figure(figsize=(12, 12))
ax = plt.gca()
gdf.plot(column='cluster',cmap='viridis', categorical=True, legend=True, ax=ax)

def replace_legend_items(legend, mapping):
    for txt in legend.get_texts():
        for k,v in mapping.items():
            if txt.get_text() == str(k):
                txt.set_text(v)

replace_legend_items(ax.get_legend(), clusdict)

plt.show()

答案 2 :(得分:0)

假设您有4个图例,则可以执行以下操作以任意顺序设置它们。以下代码显示如何按以下顺序(使用索引)放置它们:0、2、3、1。

ax是您使用ax = plt.gca()定义的轴对象

handles,labels = ax.get_legend_handles_labels()
handles = [handles[0], handles[2], handles[3], handles[1]]
labels = [labels[0], labels[2], labels[3], labels[1]]
ax.legend(handles, labels)

让我给你举个例子:

默认订单

fig, ax = plt.subplots()

x = np.arange(5)
plt.plot(x, x, label=r'$y=x$')
plt.plot(x, 2*x, label=r'$y=2x$')
plt.plot(x, 3*x, label=r'$y=3x$')
plt.plot(x, 4*x, label=r'$y=4x$')
plt.legend(fontsize=16)    

enter image description here

手动更改订单

fig, ax = plt.subplots()

x = np.arange(5)
plt.plot(x, x, label=r'$y=x$')
plt.plot(x, 2*x, label=r'$y=2x$')
plt.plot(x, 3*x, label=r'$y=3x$')
plt.plot(x, 4*x, label=r'$y=4x$')

handles,labels = ax.get_legend_handles_labels()
handles = [handles[0], handles[2],handles[3], handles[1]]
labels = [labels[0], labels[2], labels[3], labels[1]]
ax.legend(handles, labels, fontsize=16)

还可以使用预先指定的订单清单来使用清单理解功能

order = [0, 2, 3, 1]
handles,labels = ax.get_legend_handles_labels()
handles = [handles[i] for i in order]
labels = [labels[i] for i in order]
ax.legend(handles, labels, fontsize=16)

enter image description here