寻找一个解决方案,以正确地注解一个子图与一对有序的笛卡尔坐标。
我的图是一个总产品数量的条形图和一个给定产品平均价格的线形图。要获得更多参考信息,请参阅本文末尾的图:https://medium.com/swlh/product-sales-analysis-using-python-863b29026957
请注意,我有两个垂直轴:
- y1 =给定产品的总量
- y2 =给定产品的平均价格
- y1和y2共享产品类别的x轴
我的目标不是绘制标签“(x,y)",而是绘制(y1,y2)的标签,即“(qty,price)"。
我遇到的当前错误是变量label中的列表元素没有被识别为“subscriptableobjects”。我的印象是解决方案是将列表中的每个元素转换为字符串,但我并不肯定。
df =
| 产品|数量|价格|
| - ------|- ------|- ------|
| 产品1|十个|一百元|
| 产品2|十五|二百元|
| 产品3|二十个|一百五十元|
| 产品2|三十|二百元|
| 产品3|五十|一百五十元|
尝试
quantity = df.groupby("Products")["Quantity"].sum()
price = df.groupby("Products")["Price"].mean()
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.bar(Products, quantity, color='.8', alpha =.8)
ax2.plot(Products, price, 'bo-')
ax1.set_xlabel('', fontweight='bold')
ax1.set_ylabel('Quantity', color = 'k', fontweight='bold')
ax2.set_ylabel('Price $', color = 'b', fontweight='bold')
ax1.set_xticklabels(Products, rotation=45, size = 8)
y1 = [i for i in quantity]
y2 = [j for j in price]
label = []
for x, y in zip(y1,y2):
label.append(f"({x:.2f},{y:.2f})")
for i, label in enumerate(labels):
plt.annotate(label, xy=(x[i], y[i]), xytext=(5, 5),
textcoords='offset points', ha='left', va='bottom')
plt.show()
故障区域
#can't find a method to convert my list elements from float to string values *inline* with label.append()
label = []
for x, y in zip(y1,y2):
label.append(f"({x:.2f},{y:.2f})")
我觉得我正在寻找一个类似的解决方案:
1条答案
按热度按时间pdkcd3nj1#
代码中存在一些误解:
ax1
和ax2
时,建议在任何地方都使用matplotlib的object-oriented interface。plt.annotate(...)
将在“当前轴”上绘图,而ax1.annotate(...)
将在ax1
上绘图。ax1
上绘图,x坐标可以作为字符串(产品的名称)给出,y坐标作为数值量给出。enumerate(...)
和索引,使用zip直接获取列表元素会使循环更清晰。ax.tick_params(...)
将保持现有标签不变。ax1.margins(y=...)
可以为标签腾出更多的可用空间。