построение гистограммы из вложенного словаря с использованием matplotlib

#python #matplotlib

#python #matplotlib

Вопрос:

У меня есть вложенный dict, который выглядит следующим образом.

 {A: {   'apples': 3,
        'bananas':5,
        'oranges':6,
        'kiwis':9},
B: {    'apples': 1,
        'bananas':9,
        'oranges':3,
        'kiwis':1},
C: {    'apples': 6,
        'bananas':9,
        'oranges':3,
        'kiwis':3}}
  

В моем случае A, B, C — это месяцы года в течение двух лет. ось x будет представлять собой месяцы, т.Е. A, B, C и т.д. Учитываются яблоки, бананы, киви и апельсины.
Я хотел бы построить сгруппированную вертикальную гистограмму с использованием matplotlib. У нее была бы легенда с тремя цветами для яблок, бананов и апельсинов.

Я могу строить график только с использованием метода dataframe.plot:

 pd.Dataframe(mydict).T.plot(kind=bar)
  

Я хочу иметь возможность отображать то же самое с помощью matplotlib, чтобы я мог управлять размером рисунка и изменять размер столбцов и т.д.

Приветствуется любая помощь.

Спасибо

Комментарии:

1. Использование matplotlib действительно дает вам больше контроля над элементами рисунка (можно было бы начать с этого примера ), но если это касается только размера рисунка и линейки, вы можете использовать figsize=(12,8) и width=0.6 непосредственно в функции pandas plot.

Ответ №1:

Во-первых, вы можете управлять figsize с помощью figsize аргумента или сохранять во фрейме данных значения, axes возвращаемые .plot методом, так что чистое matplotlib решение — не единственный выход.

Сказав это… Важным выводом для изучения сгруппированных столбцов в matplotlib является наличие смещения. Каждый набор сгруппированных столбцов (например, apple) должен быть смещен от xticks на функцию ширины (например, width * 2)

 d = {"A": {...}, ...}

import matplotlib.pyplot as plt
import numpy as np

# Get the ax object and hardcode a bar width
fig, ax = plt.subplots()

width = 0.05

# Each set of bars (e.g. "bananas") is offset from the xtick so they're grouped
# For example np.arange(3) - width*2 for an offset of negative two bar widths 
ax.bar(np.arange(3) - width*2, [d[j]["apples"] for j in d], width)
ax.bar(np.arange(3) - width, [d[j]["bananas"] for j in d], width)
ax.bar(np.arange(3), [d[j]["oranges"] for j in d], width)
ax.bar(np.arange(3)   width, [d[j]["kiwis"] for j in d], width)

# Labels
ax.set_xticks(np.arange(3))
ax.set_xticklabels(["A", "B", "C"])
  

Ответ №2:

В документации pandas говорится, что pandas.DataFrame.plot() возвращает matplotlib.axes.Объект Axes. Итак, в принципе, вы можете обрабатывать это таким же образом, как вы будете обрабатывать аспекты построения с помощью matplotlib.

Итак, используя ваш пример:

 # Import libraries 
import pandas as pd
import matplotlib.pyplot as plt

# Create dictionary
plot_dict = {'A': {'Apples': 3,'Bananas':5,'Oranges':6,'Kiwis':9}, 'B': {'Apples': 1,'Bananas':9,'Oranges':3,'Kiwis':1}, 'C': {'Apples': 6,'Bananas':9,'Oranges':3,'Kiwis':3}}

# Plot using pandas built-in function plot()
ax = pd.DataFrame(plot_dict).T.plot.bar(zorder=5)

# Define aspects of the plot using matplotlib
ax.set_ylabel("Quantity")
ax.set_xlabel("Category")
ax.grid(axis='y', color='black', linestyle='-', linewidth=0.3)
ax.legend(loc='lower center', bbox_to_anchor=(0.5, -0.25), ncol=4, edgecolor='1', fontsize=10)
ax.locator_params(axis='y', nbins=12)

plt.savefig(f'./plot_from_nested_dict.svg', bbox_inches='tight')
  

Ответ №3:

Ниже приведен пример кода. Пожалуйста, дайте мне знать, если у вас возникнут какие-либо вопросы, я был бы очень рад вам помочь.

 # libraries
import numpy as np
import matplotlib.pyplot as plt

# set width of bar
barWidth = 0.25

# set height of bar
bars1 = [12, 30, 1, 8, 22]
bars2 = [28, 6, 16, 5, 10]
bars3 = [29, 3, 24, 25, 17]

# Set position of bar on X axis
r1 = np.arange(len(bars1))
r2 = [x   barWidth for x in r1]
r3 = [x   barWidth for x in r2]

# Make the plot
plt.bar(r1, bars1, color='#ff0000', width=barWidth, edgecolor='red', label='Apples')
plt.bar(r2, bars2, color='#FFFF00', width=barWidth, edgecolor='yellow', label='bananas')
plt.bar(r3, bars3, color='#FFA500', width=barWidth, edgecolor='orange', label='oranges')

# Add xticks on the middle of the group bars
plt.xlabel('group', fontweight='bold')
plt.xticks([r   barWidth for r in range(len(bars1))], ['04/01/2019', '04/02/2019', '04/03/2019', '04/04/2019', '04/05/2019'])

# Create legend amp; Show graphic
plt.legend()
plt.show()
  

Комментарии:

1. Это не генерирует график из вложенного dict, как просил op.