微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我如何根据 12 个数组12 个月制作颜色图?

如何解决我如何根据 12 个数组12 个月制作颜色图?

我的目标是创建一个基于月份的颜色图。 我有两个月度数据数据集(相同长度等)。 但是我想绘制两个数据集的散点图,但颜色图要根据月份着色。希望在我浏览示例时这更有意义:

这是我绘制的两个数据集作为散点图:

data1 = np.random.rand(360)

data2 = np.random.rand(360)

然后我用这个函数(split_months)把data1和data2变成一个大小为12、30的二维数组。这就像按月重组一样,12代表所有月份,30代表所有年份那个特定的月份:

def split_months(monthly_data):
    month_split = []
    for month in range(12):
        month_split.append(monthly_data[month::12])
    month_split = np.array(month_split)
    return month_split


split_data1 = split_months(data1)

split_data2 = split_months(data2)

print(split_data1.shape,split_data2.shape)

(12,30) (12,30)

然后我将拆分的月份数据重塑为一维数组,基本上是第一个月和所有年份,在第二个月和所有年份之前。所以制作一个一维数组,但按月和年数重新排序(如下例所示):

split_months_reshape_data1= split_data1.reshape(12*30) ## reshaping so organized by month Now (jan - dec for all years)

split_months_reshape_data2 = split_data2.reshape(12*30) 

print(split_data1[0])

print(split_months_reshape_data1[:30])

[0.70049451 0.24326443 0.29633189 0.35540148 0.68205274 0.15130453
 0.34046832 0.54975106 0.4502673  0.39086571 0.5610824  0.88443547
 0.85777702 0.39887896 0.82240821 0.31162978 0.23496537 0.68776803
 0.84677736 0.04060598 0.7735167  0.23317739 0.49447141 0.53932027
 0.62494628 0.19676697 0.41435389 0.22843223 0.22817976 0.09133836]

[0.70049451 0.24326443 0.29633189 0.35540148 0.68205274 0.15130453
 0.34046832 0.54975106 0.4502673  0.39086571 0.5610824  0.88443547
 0.85777702 0.39887896 0.82240821 0.31162978 0.23496537 0.68776803
 0.84677736 0.04060598 0.7735167  0.23317739 0.49447141 0.53932027
 0.62494628 0.19676697 0.41435389 0.22843223 0.22817976 0.09133836]

## data arrays are the same,split_months is showing all of the numbers for the first month,while split_months_reshape_data1 is showing the first 30 values which is the same as the `split_months[0]`

现在的问题是,有没有办法使用 split_months 中的 12 个数组中的每一个来创建颜色图(一月 - 十二月),但在每个数组中使用这些特定值? 例如,对于一月,使用 split_months[0] 中的值为颜色图制作一种颜色。然后对于二月,使用 split_months[1] 中的值为颜色图制作另一种颜色

这是我想要的想法,但颜色条不正确:

plt.scatter(split_months_reshape_data1,split_months_reshape_data2,c = split_data1)
plt.colorbar()
plt.show()
plt.show()

enter image description here

如果我的问题需要澄清,请告诉我,它有点具体,但主要目标是获得基于重构数据数组(split_data1split_data2)的颜色图。

>

解决方法

从颜色图中选择颜色非常简单,如 matplotlib colormap tutorial 所示。有两种类型的 colormap objects(LinearSegmentedColormap 和 ListedColormap),它们没有完全相同的颜色选择方法。以下是如何使用 pyplot interface 从 viridis 颜色图 (ListedColormap) 中选择颜色:

# Select colormap with a certain number of colors
cmap = plt.cm.get_cmap('viridis',12)

# Generate list of colors in these 3 equivalent ways for a ListeColormap
colors = cmap.colors  # this method is not applicable to LinearSegmentedColormaps
colors = cmap(range(12))
colors = cmap(np.linspace(0,1,12))

创建颜色条是比较棘手的部分。您正在绘制的数据集由 3 个变量组成:

  1. 月份(分类):绘制为色调
  2. data1(数值):绘制为 x 变量
  3. data2(数值):绘制为 y 变量

如您在示例中所见,传递给 c 的变量(即 split_data1,x 变量)映射到使用 plt.colorbar() 创建的颜色条。虽然可以将与月份相对应的值传递给 c 以创建颜色条(请参阅下图所示的替代解决方案),但我发现如果代替月份的颜色预先选择然后传递,则代码更容易理解到color。然后可以从绘图中单独创建颜色条,如 the second example of the Customized Colorbars Tutorial 中所示。

这是一个示例,其中使用多个 numpy 函数简化了数据整形部分,并使用 zip 创建散点图以循环遍历子数组以及相关的月份和颜色。月份的名称使用 datetime module 生成以节省一些输入。

from datetime import datetime as dt
import numpy as np                   # v 1.19.2
import matplotlib.pyplot as plt      # v 3.3.4

# Create sample dataset
rng = np.random.default_rng(seed=1)  # random number generator
data1 = rng.random(360)
data2 = rng.random(360)

# Reshape data
split_data1 = np.stack(np.split(data1,30)).transpose()
split_data2 = np.stack(np.split(data2,30)).transpose()

# Generate lists of months and colors
months = [dt.strptime(str(m),'%m').strftime('%B') for m in range(1,13)]
cmap = plt.cm.get_cmap('viridis')  # no need to preselect number of colors in this case
colors = cmap(np.linspace(0,len(months)))

# Draw scatter plot by looping over zipped sub-arrays,colors and months
for x,y,c,month in zip(split_data1,split_data2,colors,months):
    plt.scatter(x,color=c,label=month)

# Add colorbar
bounds = np.arange(len(months)+1)
norm = plt.matplotlib.colors.BoundaryNorm(bounds,cmap.N)
cbar = plt.colorbar(plt.cm.ScalarMappable(norm=norm,cmap=cmap),ticks=bounds+0.5)
cbar.set_ticklabels(months)

# Optional extra formatting
cbar.ax.tick_params(length=0,pad=7)
cbar.ax.invert_yaxis()

plt.show()

custom_colorbar



为了完整起见,这里有一个替代解决方案,它使用 c 中的 plt.scatter 参数(而不是 color)直接从绘图生成颜色条:

# Prepare data...

# months and cmap are the same as before
months = [dt.strptime(str(m),13)]
cmap = plt.cm.get_cmap('viridis')

# Create objects needed to map the months to colors and create a colorbar
bounds = np.arange(13)
norm = plt.matplotlib.colors.BoundaryNorm(bounds,cmap.N)

# Draw scatter plot,notice how there is no need for colors
for x,month,bound in zip(split_data1,months,bounds):
    plt.scatter(x,c=np.repeat(bound,len(x)),norm=norm,cmap=cmap,label=month)
cbar = plt.colorbar()

# Format colorbar
cbar.set_ticklabels(months)
cbar.set_ticks(bounds+0.5)
cbar.ax.tick_params(length=0,pad=7)
cbar.ax.invert_yaxis()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。