Работа с фиксированным индексом (диапазон значений cmc
) упрощает работу. Таким образом, color_dict_values
из color_id
дает счетчик для каждого из возможных значений cmc
(остается равным нулю, когда их нет).
color_dict_index
больше не требуется. Чтобы заполнить color_dict_values
, мы перебираем временный фрейм данных с value_counts
.
. Чтобы построить столбцы, ось x теперь является диапазоном возможных значений cmc
. Я добавил [1:] к каждому массиву, чтобы пропустить ноль в начале, который выглядел бы некрасиво на графике.
Дно начинается с нуля и увеличивается на color_dict_values
цвета, который имеет только был построен (Благодаря numpy, константа 0, добавленная в массив, будет этим массивом.)
В коде я сгенерировал несколько случайных чисел, похожих на формат в вопросе.
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
N = 50
df = pd.DataFrame({'cmc': np.random.randint(1, 10, N), 'coloridentity': np.random.choice(['R', 'G'], N)})
# get all unique values of coloridentity
unique_values = df['coloridentity'].unique()
# find the range of all cmc indices
max_cmc = df['cmc'].max()
cmc_range = range(max_cmc + 1)
# dictionary for each coloridentity: array of values of each possible cmc
color_dict_values = {}
for u in unique_values:
value_counts_df = df['cmc'].loc[df['coloridentity'] == u].value_counts()
color_dict_values[u] = np.zeros(max_cmc + 1, dtype=int)
for ind, cnt in value_counts_df.iteritems():
color_dict_values[u][ind] = cnt
width = 0.4
bottom = 0
for col_id, col in zip(['G', 'R'], ['limegreen', 'crimson']):
plt.bar(cmc_range[1:], color_dict_values[col_id][1:], bottom=bottom, width=width, color=col)
bottom += color_dict_values[col_id][1:]
plt.xticks(cmc_range[1:]) # make sure every cmc gets a tick label
plt.tick_params(axis='x', length=0) # hide the tick marks
plt.xlabel('cmc')
plt.ylabel('count')
plt.show()