2017-01-16 1 views
2

Я создал некоторые данные и попытаюсь представить их как два графика в одном и том же сюжете. Один в виде бара, другой - как линия.График Matplotlib с теми же данными не перекрывается

Однако по некоторым причинам графики, похоже, не перекрываются.

Вот мой код:

# roll two 6-sided dices 500 times 
dice_1 = pd.Series(np.random.randint(1, 7, 500)) 
dice_2 = pd.Series(np.random.randint(1, 7, 500)) 

dices = dice_1 + dice_2 

# plotting the requency of a 2 times 6 sided dice role 
fc = collections.Counter(dices) 
freq = pd.Series(fc) 
freq.plot(kind='line', alpha=0.6, linestyle='-', marker='o') 
freq.plot(kind='bar', color='k', alpha=0.6) 

А вот граф.

enter image description here

Набор данных является тем же самым, однако линейный график перемещают точки два данных вправо (начинается на 4 вместо 2). Если я рисую их отдельно, они отображаются правильно (оба начинаются с 2). Так что же изменилось, если я построю их на одном графике? И как это исправить?

+0

Вопрос, я думаю, описан в редакции в ответе Джо Кингтона [здесь] (http://stackoverflow.com/questions/7733693/matplotlib-overlay-plot с-с-разных масштабах). Тем не менее, сейчас 5 лет, и, поскольку я сомневаюсь в этом желательном поведении, мне интересно, есть ли хорошее решение. Все еще смотрящий. – roganjosh

ответ

1

Я не смог найти более простой способ сделать это, чем переложить данные по оси x. Если это отражает гораздо более широкий подход, который вы используете, то, возможно, вам нужно построить эти данные из pd.Series(), а не использовать списки, но этот код, по крайней мере, даст вам сюжет, который вы желаете. Измените iteritems() на items(), если вы используете Python 3.

Похоже, что некоторое автомасштабирование оси x происходит после графика линии, что приводит к тому, что два графика не синхронизируются на две точки (самая низкая значение возможно). Возможно, можно отключить эту автомасштабирование по оси x до тех пор, пока не будут сделаны обе графики, но это кажется более сложным.

import collections 
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 

# roll two 6-sided dices 500 times 
dice_1 = pd.Series(np.random.randint(1, 7, 500)) 
dice_2 = pd.Series(np.random.randint(1, 7, 500)) 

dices = dice_1 + dice_2 

# plotting the requency of a 2 times 6 sided dice role 
fc = collections.Counter(dices) 

x_axis = [key for key, value in fc.iteritems()] 
y_axis = [value for key, value in fc.iteritems()] 

plt.plot(x_axis, y_axis, alpha=0.6, linestyle='-', marker='o') 
plt.bar(x_axis, y_axis, color='k', alpha=0.6, align='center') 
plt.show() 
1

Это происходит потому, что индекс использования участка серии, установив use_index в False будет решить проблему, я также предлагаю использовать groupby и len для подсчета частоты каждой комбинации

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 

# roll two 6-sided dices 500 times 
dice_1 = pd.Series(np.random.randint(1, 7, 500)) 
dice_2 = pd.Series(np.random.randint(1, 7, 500)) 
dices = dice_1 + dice_2 

# returns the corresponding value of each index from dices 
func = lambda x: dices.loc[x] 

fc = dices.groupby(func).agg({'count': len}) 

ax = fc.plot(kind='line', alpha=0.6, linestyle='-', 
      marker='o', use_index=False) 
fc.plot(ax=ax, kind='bar', alpha=0.6, color='k') 

plt.show() 

Результат показан ниже plot