2

I'm having with my xticks on my plot. I have an hh:mm:ss format data on my x vector, but the xticks label are just eating up space on my x vector. I'm trying to use only major xticks which would show the x vector label on 5 minutes basis.

but, the label not showing correctly.

right now this is the code that i wrote:

# -*- coding: utf-8 -*-

from os import listdir
from os.path import isfile, join
import pandas as pd
from Common import common as comm
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt

fp = FontProperties(fname="../templates/fonts/msgothic.ttc")


config = comm.configRead()


commonConf = comm.getCommonConfig(config)

peopleBhvConf = comm.getPeopleBhvConf(config)


files = [f for f in listdir(commonConf['resultFilePath']) if             isfile(join(commonConf['resultFilePath'], f))]
waitTimeGraphInput = [s for s in files if peopleBhvConf['resultFileName'] in s]
waitTimeGraphFile = commonConf['inputFilePath'] + waitTimeGraphInput[0]
waitTimeGraph = pd.read_csv(waitTimeGraphFile)

# Create data
N = len(waitTimeGraph.index)
x = waitTimeGraph['ホール入時間']
y = waitTimeGraph['滞留時間(出-入sec)']
xTicks = pd.date_range(min(x), max(x), freq="5min")

fig, ax = plt.subplots()
ax.scatter(x, y)
ax.set_xticklabels(xTicks, rotation='vertical')
plt.axhline(y=100, xmin=min(x), xmax=max(x), linewidth=2, color = 'red')
plt.setp(ax.get_xticklabels(), visible=True, rotation=30, ha='right')
plt.savefig(commonConf['resultFilePath'] + '1人1人の待ち時間分布.png')

plt.show()

and this is the result:

enter image description here

as you can see, the labels are still being printed only on the front of my plotting. I'm expecting it would being printed on my major xticks position only.

1 Answer 1

1

The problem

If I understand correctly what is going on, xTicks array is shorter than x, am I right? If so, this is the issue.

I don't see in your code where you set the tick position, but I guess you are showing all of them, one per each element of x. But since you set the tick labels manually with ax.set_xticklabels(xTicks, rotation='vertical'), matplotlib has no way to know at which ticks those labels should go, hence it fills the first available ticks, and if there are more ticks, they are left without labels.
If you were able to read the labes, you would see that the written dates do not correspond to the labelled positions on the axis.

How to fix it

The general rule, be sure when you set tick labels manually, that the array containing the label has the same length of the array of the ticks. Add empty strings for the ticks where you do not want to have a labels.

However, since you spoke of major ticks and minor ticks, I show you how to set them in your case, where you have dates on the x axis.

Drop the xTicks, is not needed. Don't set the tick labels manually, hence don't use ax.set_xticklabels(). Your code should be:

fig, ax = plt.subplots()
ax.scatter(x, y)
plt.axhline(y=100, xmin=min(x), xmax=max(x), linewidth=2, color = 'red')
ax.xaxis.set_major_locator(MinuteLocator(interval=5))
ax.xaxis.set_minor_locator(MinuteLocator(interval=1))
ax.xaxis.set_major_formatter(DateFormatter('%H:%M:%S'))
plt.setp(ax.get_xticklabels(), visible=True, rotation=30, ha='right')
plt.savefig(commonConf['resultFilePath'] + '1人1人の待ち時間分布.png')

Remember to import the locator and formatter:

from matplotlib.dates import MinuteLocator, DateFormatter

A brief explanation: MinuteLocator finds each minute interval in your x axis and place a tick. The parameter interval allows you to set a tick each N minutes. So in the above code a major tick is placed each 5 minutes, a minor tick each minute.
DateFormatter simply format the date accordingly to the string (here I choose the format hour, minute, second). Note that no formatter has been set for minor ticks, so by default matplotlib uses the null formatter (no labels for minor ticks).
Here the documentation on the dates module of matplotlib.

To give you an idea of the result, here is an image I created using the code above with random data (just look at the x axis).

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.