Если вы не установите даты в качестве оси Y, ax.set_yticks(range(len(df)))
с последующим ax.set_yticklabels(df['city'])
будет работать очень хорошо.
Но более рекомендуемый способ - использовать города непосредственно для y- ось. Тиковые метки могут быть сделаны с нулевой длиной, поэтому они продолжают сигнализировать положение меток тиков без видимых меток.
Если вы хотите, чтобы даты были в качестве оси Y, и поместили метки внутри столбцов, вы мог бы просто разместить текст через al oop. Но не имеет особого смысла использовать дату в качестве оси Y, не показывая их.
Чтобы инвертировать ось Y с наименьшими (или первыми) значениями вверху, используйте ax.invert_yaxis()
.
Поскольку сообщение не содержало тестовых данных, приведенный ниже пример начинается с создания случайных данных.
import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np
import pandas as pd
df = pd.DataFrame({'date': pd.date_range('2020-01-01', periods=10),
'cases': np.random.randint(80, 200, 10),
'city': [f'City {i}' for i in range(1, 11)]})
fig, ax = plt.subplots()
ax.barh(df['date'], df['cases'], color='#49cff3')
ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
ax.xaxis.set_ticks_position('top')
ax.tick_params(axis='x', colors='#777777', labelsize=12)
ax.tick_params(axis='y', length=0)
# ax.set_yticks([]) # this would make the both the tick marks and their labels disappear
ax.grid(which='major', axis='x', linestyle='-')
for row in df.itertuples(index=False):
ax.text(0, row.date, ' '+row.city, ha='left', va='center', color='crimson')
ax.invert_yaxis()
plt.box(False)
plt.tight_layout()
plt.show()