Я нахожу, что для таких случаев, как правило, проще быть понятным в отношении столбцов, чем позволять пандам делать все автоматически. Э.Г.
ax1.scatter(data['runtime'], data['pixels'])
и
ax2.scatter(data['runtime'], data['segments'])
Для полного примера, демонстрирующего это:
import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel
data = pd.DataFrame({'runtime': [0.079277, 0.045553, 0.002466, 0.016046, 0.009114,
0.000799, 0.007617],
'pixels': [1756374, 1221211, 8134, 339786, 214936, 506, 192800],
'segments':[12960, 5129, 1247, 6854, 1930, 218, 2949]})
## create the general figure
fig1 = figure()
ax1 = fig1.add_subplot(111)
ax1.scatter(data['runtime'], data['pixels'], label="Pixels", marker='.', color='k')
ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')
ax2 = ax1.twinx()
ax2.scatter(data['runtime'], data['segments'], label="Segments", marker='.', color='r')
ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
tl.set_color('r')
fig1.legend(bbox_to_anchor=(0.225,0.845))
plt.show()
Вы также можете отметить легенду, вы можете изменить местоположение по своему усмотрению, изменив кортеж bbox_to_anchor
, документов
Редактировать
[ 1116] Если вам нужно покрасить в зависимости от состояния, вы можете сделать что-то вроде этого
import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel
import matplotlib.lines as mlines
data = pd.DataFrame({'state': ["Texas", "California", "Rhode Island", "Washington",
"Alabama", "District of Columbia", "Ohio"],
'runtime': [0.079277, 0.045553, 0.002466, 0.016046,
0.009114, 0.000799, 0.007617],
'pixels': [1756374, 1221211, 8134, 339786, 214936, 506, 192800],
'segments':[12960, 5129, 1247, 6854, 1930, 218, 2949]})
## create the general figure
fig1 = figure()
ax1 = fig1.add_subplot(111)
ax2 = ax1.twinx()
for ii in range(len(data['state'])):
ax1.scatter(data['runtime'][ii], data['pixels'][ii],
label=data['state'][ii], marker='.')
ax2.scatter(data['runtime'][ii], data['segments'][ii], marker='+')
ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')
legend = fig1.legend(bbox_to_anchor=(0.3,0.845))
m1 = mlines.Line2D([], [], color='black', linewidth = 0, marker='.', label='Pixels')
m2 = mlines.Line2D([], [], color='black', linewidth = 0, marker='+', label='Segments')
plt.legend(handles=[m1,m2], loc='lower right')
ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
tl.set_color('r')
plt.show()
Где 39938 количество дней с 01.01.1900?
В этом случае используйте библиотечную функцию платформы DateTime.FromOADate()
.
Эта функция инкапсулирует все специфические особенности и делает проверку границ.
Для его исторической ценности вот возможная реализация:
(C#)
public static DateTime FromExcelSerialDate(int SerialDate)
{
if (SerialDate > 59) SerialDate -= 1; //Excel/Lotus 2/29/1900 bug
return new DateTime(1899, 12, 31).AddDays(SerialDate);
}
VB
Public Shared Function FromExcelSerialDate(ByVal SerialDate As Integer) As DateTime
If SerialDate > 59 Then SerialDate -= 1 ''// Excel/Lotus 2/29/1900 bug
Return New DateTime(1899, 12, 31).AddDays(SerialDate)
End Function
[Обновление]:
Хм... Быстрый тест этого показывает, что это - на самом деле два выходных. Не уверенный, где различие.
Хорошо: проблема решена теперь. См. комментарии для деталей.
Мне проще использовать Метод FromOADate , например:
DateTime dt = DateTime.FromOADate(39938);
Использование этого кода dt - «05.05.2009».
void ExcelSerialDateToDMY(int nSerialDate, int &nDay,
int &nMonth, int &nYear)
{
// Excel/Lotus 123 have a bug with 29-02-1900. 1900 is not a
// leap year, but Excel/Lotus 123 think it is...
if (nSerialDate == 60)
{
nDay = 29;
nMonth = 2;
nYear = 1900;
return;
}
else if (nSerialDate < 60)
{
// Because of the 29-02-1900 bug, any serial date
// under 60 is one off... Compensate.
nSerialDate++;
}
// Modified Julian to DMY calculation with an addition of 2415019
int l = nSerialDate + 68569 + 2415019;
int n = int(( 4 * l ) / 146097);
l = l - int(( 146097 * n + 3 ) / 4);
int i = int(( 4000 * ( l + 1 ) ) / 1461001);
l = l - int(( 1461 * i ) / 4) + 31;
int j = int(( 80 * l ) / 2447);
nDay = l - int(( 2447 * j ) / 80);
l = int(j / 11);
nMonth = j + 2 - ( 12 * l );
nYear = 100 * ( n - 49 ) + i + l;
}
Вырезать и вставить чужие таланты ...