Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
876 views
in Technique[技术] by (71.8m points)

python - Measurement length for X and Y-axis

I wonder if it's possible to change the measurement milestones for graphs created by pandas. In my code the X-axis stands for time and is measured by month, but the measurement milestones are all over the place.

In the image below, the milestones for the X-axis are 2012M01, 2012M06, 2012M11, 2013M04 and 2013M09.

Is there any way I can choose how long the distance should be between every milestone? For example, to make it so it shows every year or every half year?

This is the code I used for the function making the graph:

def graph(dataframe):
    graph = dataframe[["Profit"]].plot() 
    graph.set_title('Statistics')
    graph.set_ylabel('Thousand $')
    graph.set_xlabel('Time')
    plt.grid(True)          
    plt.show()

The actual dataframe is just an excel-file with a bunch of months and monetary values in it.

the plot

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think the most straight forward is to use matplotlib.dates to format the axis:

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

def graph(dataframe):
    fig, ax = plt.subplots()
    xfmt = mdates.DateFormatter('%YM%m')            #see https://strftime.org/
    major = mdates.MonthLocator([1,7])              #label only Jan and Jul

    graph = dataframe[["Profit"]].plot(ax=ax)       #link plot to the existing axes
    graph.set_title('Statistics')
    graph.set_ylabel('Thousand $')
    graph.set_xlabel('Time')
    graph.xaxis.set_major_locator(major)            #set major locator tick on x-axis
    graph.xaxis.set_major_formatter(xfmt)           #format xtick label
    plt.grid(True)          
    plt.show()

But a key point is you need to have your dates as Python's built-in datetime.date (not datetime.datetime); thanks to this answer. If your dates are str or a different type of datetime, you will need to convert, but there are many resources on SO and elsewhere for doing this like this or this:

In[0]:

dr = pd.date_range('01-01-2012', '01-01-2014', freq='1MS')
dr = [pd.to_datetime(date).date() for date in df.index]    #explicitly converting to datetime with .date()

df = pd.DataFrame(index=dr, data={'Profit':np.random.rand(25)})
type(df.index.[0])

Out[0]:
datetime.date

Calling graph(df) using the example above gets this plot: enter image description here


Just to expand on this, here's what happens when the index is pandas.Timestamp instead of datetime.date:

In[0]:
dr = pd.date_range('01-01-2012', '01-01-2014', freq='1MS')
# dr = [pd.to_datetime(date).date() for date in df.index]       #skipping date conversion
df = pd.DataFrame(index=dr, data={'Profit':np.random.rand(25)})

graph(df)

Out[0]:

The x-axis is improperly formatted:

enter image description here

However, if you are willing to just create the plot directly through matplotlib, rather than pandas (pandas is using matplotlib anyway), this can handle more types of dates:

In[0]:
dr = pd.date_range('01-01-2012', '01-01-2014', freq='1MS')
# dr = [pd.to_datetime(date).date() for date in df.index]         #skipping date conversion
df = pd.DataFrame(index=dr, data={'Profit':np.random.rand(25)})

def graph_2(dataframe):
    fig, ax = plt.subplots()
    xfmt = mdates.DateFormatter('%YM%m')
    major = mdates.MonthLocator([1,7])

    ax.plot(dataframe.index,dataframe['Profit'], label='Profit')
    ax.set_title('Statistics')
    ax.set_ylabel('Thousand $')
    ax.set_xlabel('Time')
    ax.xaxis.set_major_locator(major)
    ax.xaxis.set_major_formatter(xfmt)
    ax.legend()                          #legend needs to be added
    plt.grid(True)          
    plt.show()

graph_2(df)
type(df.index[0])

Out[0]:

pandas._libs.tslibs.timestamps.Timestamp

And here is the working graph:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...