установление расстояния между сгруппированными штриховыми графиками в matplotlib

Я пытаюсь сделать сгруппированный график в matplotlib, следуя примеру в галерее. Я использую следующее:

import matplotlib.pyplot as plt plt.figure(figsize=(7,7), dpi=300) xticks = [0.1, 1.1] groups = [[1.04, 0.96], [1.69, 4.02]] group_labels = ["G1", "G2"] num_items = len(group_labels) ind = arange(num_items) width = 0.1 s = plt.subplot(1,1,1) for num, vals in enumerate(groups): print "plotting: ", vals group_len = len(vals) gene_rects = plt.bar(ind, vals, width, align="center") ind = ind + width num_groups = len(group_labels) # Make label centered with respect to group of bars # Is there a less complicated way? offset = (num_groups / 2.) * width xticks = arange(num_groups) + offset s.set_xticks(xticks) print "xticks: ", xticks plt.xlim([0 - width, max(xticks) + (num_groups * width)]) s.set_xticklabels(group_labels) 

введите описание изображения здесь

Мои вопросы:

  1. Как я могу контролировать пространство между группами баров? Прямо сейчас расстояние огромно и выглядит глупо. Обратите внимание: я не хочу, чтобы шины были более широкими – я хочу, чтобы они имели одинаковую ширину, но были ближе друг к другу.

  2. Как я могу заставить метки быть центрированными ниже групп баров? Я попытался придумать некоторые арифметические вычисления, чтобы поместить xlabels в нужное место (см. Код выше), но он все еще немного выключен … он немного похож на запись библиотеки графиков, а не на использование. Как это можно зафиксировать? (Есть ли оболочка или встроенная утилита для matplotlib, где это поведение по умолчанию?)

EDIT: Ответ на @mlgill: Благодарю вас за ваш ответ. Ваш код, безусловно, намного более изящный, но по-прежнему имеет такую ​​же проблему, а именно, что ширина баров и расстояние между группами не контролируются отдельно. Ваш график выглядит корректно, но бары слишком широки – это выглядит как граф Excel, и я хотел бы сделать панель более тонкой.

Ширина и маржа теперь связаны, поэтому, если я попробую:

 margin = 0.60 width = (1.-2.*margin)/num_items 

Это делает панель более тонкой, но приносит группе далеко друг от друга, поэтому сюжет снова выглядит не так.

Как я могу создать функцию группового графика, которая принимает два параметра: ширину каждого бара и расстояние между группами баров и делает это правильно, как ваш код, т. Е. С помощью меток оси х, расположенных по центру ниже групп?

Я думаю, что, поскольку пользователю приходится вычислять конкретные значения макета низкого уровня, такие как маржа и ширина, мы по-прежнему в основном пишем библиотеку графиков 🙂

3 Solutions collect form web for “установление расстояния между сгруппированными штриховыми графиками в matplotlib”

Уловка для обоих ваших вопросов заключается в понимании того, что гистограммы в Matplotlib ожидают, что каждая серия (G1, G2) будет иметь общую ширину «1,0», считая поля с обеих сторон. Таким образом, проще всего установить поля, а затем рассчитать ширину каждого бара в зависимости от того, сколько из них существует для каждой серии. В вашем случае есть две полосы в каждой серии.

Предполагая, что вы выровняете каждую полосу, вместо того, чтобы выравнивать их по центру, как вы это сделали, эта настройка приведет к серии, которая охватывает от 0.0 до 1.0, 1.0 до 2.0 и т. Д. По оси x. Таким образом, точный центр каждой серии, где вы хотите, чтобы ваши ярлыки отображались, будет составлять 0,5, 1,5 и т. Д.

Я очистил ваш код, так как было много посторонних переменных. См. Комментарии внутри.

 import matplotlib.pyplot as plt import numpy as np plt.figure(figsize=(7,7), dpi=300) groups = [[1.04, 0.96], [1.69, 4.02]] group_labels = ["G1", "G2"] num_items = len(group_labels) # This needs to be a numpy range for xdata calculations # to work. ind = np.arange(num_items) # Bar graphs expect a total width of "1.0" per group # Thus, you should make the sum of the two margins # plus the sum of the width for each entry equal 1.0. # One way of doing that is shown below. You can make # The margins smaller if they're still too big. margin = 0.05 width = (1.-2.*margin)/num_items s = plt.subplot(1,1,1) for num, vals in enumerate(groups): print "plotting: ", vals # The position of the xdata must be calculated for each of the two data series xdata = ind+margin+(num*width) # Removing the "align=center" feature will left align graphs, which is what # this method of calculating positions assumes gene_rects = plt.bar(xdata, vals, width) # You should no longer need to manually set the plot limit since everything # is scaled to one. # Also the ticks should be much simpler now that each group of bars extends from # 0.0 to 1.0, 1.0 to 2.0, and so forth and, thus, are centered at 0.5, 1.5, etc. s.set_xticks(ind+0.5) s.set_xticklabels(group_labels) 

Вывод из моего кода.

На самом деле, я думаю, что эту проблему лучше всего решить путем настройки figsize и width ; вот мой вывод с figsize=(2,7) и width=0.3 :

введите описание изображения здесь

Кстати, этот тип вещей становится намного проще, если вы используете обертки pandas (я также импортировал seaborn , не необходимое для решения, но делает мой график более красивым и более современным, на мой взгляд):

 import pandas as pd import seaborn seaborn.set() df = pd.DataFrame(groups, index = group_labels) df.plot(kind='bar', legend = False, width = .8, figsize = (2,5)) plt.show() 

введите описание изображения здесь

Я прочитал ответ, который Павел Иванов опубликовал в Nabble, который может решить эту проблему с меньшей сложностью. Просто установите индекс, как показано ниже. Это увеличит расстояние между сгруппированными столбцами.

 ind = np.arange(0,12,2) 
  • Стандартная ошибка нелинейной регрессии
  • Как читать часть двоичного файла с numpy?
  • Как установить точность на str (numpy.float64)?
  • Эффективно создавать редкие сводные таблицы в пандах?
  • Изменение форм данных в пандах на основе меток столбцов
  • Установите кривую для данных, состоящих из двух разных режимов
  • Сглаживание данных в контурном графике с помощью Matplotlib
  • Вычислить расхождение векторного поля с помощью python
  • Как я могу использовать PCA / SVD в Python для выбора и идентификации функции?
  • Пользовательские цвета кластеров SciPy dendrogram в Python (link_color_func?)
  • аналогия scipy.interpolate.griddata?
  • Python - лучший язык программирования в мире.