英文:
How to make the colorbar of a geopandas plot independent of vmax?
问题
我使用以下代码创建漂亮的世界地图,并添加了一些统计数据:
```python
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
from mpl_toolkits.axes_grid1 import make_axes_locatable
import geopandas as gpd
world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]
np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()
data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})
merged_data = world.merge(data, left_on='name', right_on="country", how="left")
fig, ax = plt.subplots(figsize=(10, 6))
cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="4%", pad=0, aspect=10)
merged_data.plot(column='count', ax=ax, cax=cax, cmap=cmap, linewidth=0.5, legend=True, edgecolors="k", missing_kwds={'color': 'lightgrey'}, legend_kwds={'label': "人数", 'orientation': "horizontal"}, vmin=0, vmax=3000)
fig = ax.figure
cb_ax = fig.axes[1]
cb_ax.tick_params(labelsize=8.5, size=2.5, direction="in")
ax.set_axis_off()
plt.show()
一切看起来都很好(图1),直到我用其他数据替换 vmax=3000
,然后突然间色条变得又长又窄(图2)。
有没有办法使色条独立于 vmax
,这样当我用其他值制作其他图表时它就不会改变?我希望它在报告中尽可能相似。
[![在这里输入图片描述][1]][1]
图1:色条外观良好 -- 我想要的所有图表的效果。
[![在这里输入图片描述][2]][2]
图2:色条又长又窄 -- 不是我想要的。
<details>
<summary>英文:</summary>
I use the following code to make nice world map with some statistics:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
from mpl_toolkits.axes_grid1 import make_axes_locatable
import geopandas as gpd
world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]
np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()
data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})
merged_data = world.merge(data, left_on='name', right_on="country", how="left")
fig, ax = plt.subplots(figsize=(10, 6))
cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="4%", pad=0, aspect=10)
merged_data.plot(column='count', ax=ax, cax=cax, cmap=cmap, linewidth=0.5, legend=True, edgecolors="k", missing_kwds={'color': 'lightgrey'}, legend_kwds={'label': "Number of people", 'orientation': "horizontal"}, vmin=0, vmax=3000)
fig = ax.figure
cb_ax = fig.axes[1]
cb_ax.tick_params(labelsize=8.5, size=2.5, direction="in")
ax.set_axis_off()
plt.show()
Everything looks good (Figure 1) untill I change `vmax=3000` with other data, and then suddenly the colorbar becomes long and narrow (Figure 2).
Is there a way to make the colorbar independent of `vmax` so that it does not change when I make other plots with other values? I want it to look as similar as possible in my report.
[![enter image description here][1]][1]
Figure 1: Good looking colobar -- what I want for all the figures.
[![enter image description here][2]][2]
Figure 2: Long and narrow colorbar -- not what I want.
---
Edit: Included a `MWE` as suggested by @JohanC.
[1]: https://i.stack.imgur.com/bO4Km.png
[2]: https://i.stack.imgur.com/Ztupm.png
</details>
# 答案1
**得分**: 0
我认为我通过计算`cb_width`和`cb_height`,然后将其传递给`aspect_ratio`,然后定义`cax.set_aspect(aspect_ratio)`来解决了这个问题:
```python
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
from mpl_toolkits.axes_grid1 import make_axes_locatable
import geopandas as gpd
world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]
np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()
data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})
merged_data = world.merge(data, left_on='name', right_on="country", how="left")
fig, ax = plt.subplots(figsize=(10, 6))
cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="5%", pad=0, aspect=40)
vmin = 0
vmax = 3000
merged_data.plot(column='count', ax=ax, cax=cax, cmap=cmap, linewidth=0.5, legend=True, edgecolors="k", missing_kwds={'color': 'lightgrey'}, legend_kwds={'label': "Number of people", 'orientation': "horizontal"}, vmin=vmin, vmax=vmax)
fig = ax.figure
cb_ax = fig.axes[1]
cb_width = cb_ax.get_window_extent().width / fig.dpi
cb_height = cb_ax.get_window_extent().height / fig.dpi
aspect_ratio = cb_width / cb_height
cax.set_aspect(aspect_ratio)
cb_ax.tick_params(labelsize=8.5, size=2.5, direction="in")
ax.set_axis_off()
plt.show()
英文:
I think I managed to solve it by calculating the cb_width
and cb_height
and then pass it to aspect_ratio
before defining the cax.set_aspect(aspect_ratio)
:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
from mpl_toolkits.axes_grid1 import make_axes_locatable
import geopandas as gpd
world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
world = world[world.name != "Antarctica"]
np.random.seed(123)
countries = world['name'].sample(75, replace=True).tolist()
data = pd.DataFrame({'country': countries, 'count': np.random.randint(0, 500, 75)})
merged_data = world.merge(data, left_on='name', right_on="country", how="left")
fig, ax = plt.subplots(figsize=(10, 6))
cmap = mplc.LinearSegmentedColormap.from_list("custom", ["r", "b"])
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="5%", pad=0, aspect=40)
vmin = 0
vmax = 3000
merged_data.plot(column='count', ax=ax, cax=cax, cmap=cmap, linewidth=0.5, legend=True, edgecolors="k", missing_kwds={'color': 'lightgrey'}, legend_kwds={'label': "Number of people", 'orientation': "horizontal"}, vmin=vmin, vmax=vmax)
fig = ax.figure
cb_ax = fig.axes[1]
cb_width = cb_ax.get_window_extent().width / fig.dpi
cb_height = cb_ax.get_window_extent().height / fig.dpi
aspect_ratio = cb_width / cb_height
cax.set_aspect(aspect_ratio)
cb_ax.tick_params(labelsize=8.5, size=2.5, direction="in")
ax.set_axis_off()
plt.show()
I am not sure how robust this solution is, so please do not hesitate to comment or make different answers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论