简体   繁体   English

将Matplotlib(线图)与Pandas数据帧中的数据一起使用时,沿x轴缺少文本标签

[英]Missing textual labels along x-axis when using Matplotlib (line-plot) with data from a Pandas dataframe

I am trying to plot data from a Pandas dataframe that is created by importing data from a CSV. 我正在尝试从通过从CSV导入数据而创建的Pandas数据框中绘制数据。 However in the plot not every label is displayed along the x-axis, the plot only shows 5 labels along the x-axis. 但是,在绘图中,并非每个标签都沿x轴显示,该绘图仅沿x轴显示5个标签。

I have a total of 22 textbased labels, which are all supposed to be shown along the x-axis as tickmarks/labels. 我总共有22个基于文本的标签,这些标签都应该沿x轴显示为刻度线/标签。 These labels correspond to the entries in the column in the dataframe with the name Category. 这些标签对应于数据框名称为Category的列中的条目。

For each Line in the Line column of the dataframe a separate line in the plot is created. 对于数据框“线”列中的每条线,都会在图中创建一条单独的线。 And the Amount columns in the dataframe contains the y-values. 数据框中的Amount列包含y值。

I am sure there is a easy tweak for this, trying ax.set_xticks(np.arange(len(21)) and plt.xticks( arange(21) ) did not function, maybe because the labels are textbased, not numbers? 我确信对此有一个简单的调整,尝试使用ax.set_xticks(np.arange(len(21))plt.xticks( arange(21) )不能正常工作,也许是因为标签基于文本,而不是数字吗?

EDIT 2 编辑2

I had some trouble with the initial code after changing computer with another software setup. 使用其他软件设置更换计算机后,初始代码出现了一些麻烦。 Now I got another version of the code and CSV that I got to run without problems that actually plots a graph. 现在,我得到了另一个版本的代码和CSV,可以运行而没有实际绘制图形的问题。 Now back to the initial problem, as can be seen from the attached picture only a few of the categories (gts, jma, yja, lre, fgg) are displayed as labels along the x-axis (I want all 22 categories to be displayed along the x-axis in full text): 现在回到最初的问题,从所附图片可以看出,只有少数几个类别(gts,jma,yja,lre,fgg)沿x轴显示为标签(我希望显示所有22个类别)沿x轴显示为全文): 沿x轴未将所有类别显示为x标签的图的图像

Here is the code that I used for plotting that doesn't display all x-labels: 这是我用于绘制的代码,它不显示所有x标签:

import pandas as pd
import matplotlib.pyplot as plt

df=pd.read_csv("import.csv", 
                   names=["Category", "Line", "Amount"], encoding="iso-8859-1")

fig, ax = plt.subplots(1,1);
df.groupby("Category").plot(x="Line", y="Amount", ax=ax)

plt.legend([v[0] for v in df.groupby('Category')['Category']], bbox_to_anchor=(1.1, 0.5)) 
plt.xlabel('Category')
plt.ylabel('Amount')

for line in ax.lines:
    line.set_linewidth(0.5)

The CSV contents look as follows, I didn't post the whole file as there are many lines. CSV内容如下所示,由于行很多,因此我没有发布整个文件。 I believe this should be enough to reproduce the problem (of course I can put more if the plot doesn't work without). 我相信这足以重现问题(当然,如果密谋不可行,我可以提出更多建议)。 The first column is the Line-column, the second column corresponds to the Category-column and the third column corresponds to the Amount-column: 第一列是“行”列,第二列是“类别”列,第三列是“金额”列:

jabber,gts,1
jabber,aed,6
jabber,ame,2
jabber,asy,8
jabber,fxk,1
jabber,jma,6
jabber,oaw,2
jabber,ejt,8
jabber,qat,1
jabber,dzj,6
jabber,yja,2
jabber,ajz,8
jabber,jbp,1
jabber,bvi,6
jabber,pec,2
jabber,lre,8
jabber,wlx,1
jabber,hpw,6
jabber,spg,2
jabber,bdg,8
jabber,fgg,1
jabber,fgz,5
soshy,gts,6
soshy,aed,2
soshy,ame,8
soshy,asy,1
soshy,fxk,6
soshy,jma,2
soshy,oaw,8
soshy,ejt,1
soshy,qat,6
soshy,dzj,2
soshy,yja,8
soshy,ajz,1
soshy,jbp,6
soshy,bvi,2
soshy,pec,8
soshy,lre,1
soshy,wlx,6
soshy,hpw,2
soshy,spg,8
soshy,bdg,1
soshy,fgg,6
soshy,fgz,2

You are looking for xticks, Matplotlib automagicly picks the xticks that will be displayed to keep things simple and nice looking. 您正在寻找xticks,Matplotlib自动选择将显示的xticks,以使事情保持简单美观。 This works fine when you are dealing with time series or numeric x axis's. 当您处理时间序列或数字x轴时,这可以很好地工作。 But not so well in your case. 但您的情况不太好。

What you need to do is find out what the co-ordinates at the begining and end of the plot are and use those numbers to manually position your x-ticks. 您需要做的是找出绘图开始和结束处的坐标,然后使用这些数字手动定位x点。 You can get this info by calling plt.xticks(). 您可以通过调用plt.xticks()获得此信息。 Which gives you a numpy array of (cordinates, xtick labels) 这给了你一个(坐标,xtick标签)的numpy数组

>>> plt.xticks()
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
         17, 18, 19, 20, 21]), <a list of 22 Text xticklabel objects>)

Here is a link to the matplotlib docs. 这是matplotlib文档的链接。 matplotlib.pyplot.xticks matplotlib.pyplot.xticks 在此处输入图片说明

Here is the code 这是代码

import pandas as pd
import matplotlib.pyplot as plt
plt.ion() # turn on interactive plotting for ipython
# I stuck your data in a list
data = [
    ['jabber', 'gts', 1], ['jabber', 'aed', 6], ['jabber', 'ame', 2], ['jabber', 'asy', 8],
    ['jabber', 'fxk', 1], ['jabber', 'jma', 6], ['jabber', 'oaw', 2], ['jabber', 'ejt', 8],
    ['jabber', 'qat', 1], ['jabber', 'dzj', 6], ['jabber', 'yja', 2], ['jabber', 'ajz', 8],
    ['jabber', 'jbp', 1], ['jabber', 'bvi', 6], ['jabber', 'pec', 2], ['jabber', 'lre', 8],
    ['jabber', 'wlx', 1], ['jabber', 'hpw', 6], ['jabber', 'spg', 2], ['jabber', 'bdg', 8],
    ['jabber', 'fgg', 1], ['jabber', 'fgz', 5], ['soshy', 'gts', 6], ['soshy', 'aed', 2],
    ['soshy', 'ame', 8], ['soshy', 'asy', 1], ['soshy', 'fxk', 6], ['soshy', 'jma', 2],
    ['soshy', 'oaw', 8], ['soshy', 'ejt', 1], ['soshy', 'qat', 6], ['soshy', 'dzj', 2],
    ['soshy', 'yja', 8], ['soshy', 'ajz', 1], ['soshy', 'jbp', 6], ['soshy', 'bvi', 2],
    ['soshy', 'pec', 8], ['soshy', 'lre', 1], ['soshy', 'wlx', 6], ['soshy', 'hpw', 2],
    ['soshy', 'spg', 8], ['soshy', 'bdg', 1], ['soshy', 'fgg', 6], ['soshy', 'fgz', 2]]

df = pd.DataFrame(data, columns=["Category", "Line", "Amount"])
fig, ax = plt.subplots(1, 1)
df.groupby("Category").plot(x="Line", y="Amount", ax=ax)
plt.legend([v[0] for v in df.groupby('Category')['Category']], bbox_to_anchor=(1.1, 0.5))

# get the values we want displayed as tick labels
tick_labels = tuple(df['Line'])
# get the positions for the maximum xtick label
x_max = int(max(plt.xticks()[0]))  # int() to convert numpy.int32 => int
# manually set you xtick labels
plt.xticks(range(0, x_max + 1), tick_labels, rotation=45) 

plt.xlabel('Category')
plt.ylabel('Amount')
# change the limits and padding of the figure
plt.figure(1).subplots_adjust(
    **dict(left=0.1, right=.8, bottom=.15, top=.9, wspace=.1, hspace=.1))
for line in ax.lines:
    line.set_linewidth(0.5)

plt.plot()    # might need this without ipython

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM