1

I have this very simple pandas dataframe here and i'm trying to plot the index column (Date, which is formatted as string) against 'Adj Close' Column.

            Adj Close
      Date                  
2010-01-01  1.438994
2010-01-04  1.442398
2010-01-05  1.436596
2010-01-06  1.440403
2010-01-07  1.431803
... a lot more rows

Here's my very simple code:

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(df['Adj Close'], label='Close Price History')
fig.autofmt_xdate()

however the graph is unpleasant in the sense that there are too many overlapping x ticks. enter image description here

I've tried out the solution here using the code

ax.locator_params(axis='x',nbins=10)

I thought this would give me 11 ticks with 10 equally spaced interval in between. However the I've gotten an error:

/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:4: UserWarning: 'set_params()' not defined for locator of type <class 'matplotlib.category.StrCategoryLocator'> after removing the cwd from sys.path.

I have no idea what the error means, guess it's because my x-axis is in string format (non-numeric)? Just to emphasis, i'm really seeking for simple solution to solve this problem, not interested to format the column as date and go though all the hardship in date manipulation. Just assuming my x ticks are strings and there's no way to apply numeric calculation on them, is it possible to just reduce the frequency of x ticks shown to get a more visually appealing plot?

Logica
  • 977
  • 4
  • 16
Jeremy
  • 379
  • 2
  • 11
  • Kindly post a sample (copy-able) data so that others can reproduce easily. Otherwise, you can refer to this [link](https://matplotlib.org/3.1.1/gallery/text_labels_and_annotations/date.html) on how to format date-ticks. – Toukenize Mar 04 '20 at 06:28
  • @Toukenize I need some advice on how to upload sample data? As for the second part. I'm not interested to format the column as date and go though all the hardship in date manipulation. Just assuming my x ticks are strings and there's no way to apply numeric calculation on them, is it possible to just reduce the frequency of x ticks shown to get a more visually appealing plot? – Jeremy Mar 04 '20 at 06:30
  • Seems like you are using `pandas`. Just call `df.to_clipboard()` on a portion of your dataframe, and paste it into your question. Once pasted, select the pasted content, and `Ctrl + K` to format it nicely. – Toukenize Mar 04 '20 at 06:32
  • @Toukenize thanks, and i've uploaded the sample data – Jeremy Mar 04 '20 at 06:37
  • @Toukenize seems like a simple problem, i couldn't find a workable solution after many research. what do you think ? – Jeremy Mar 04 '20 at 06:44
  • The answer @ilke444 posted seems like an easy hack. Try that out! – Toukenize Mar 04 '20 at 07:02

1 Answers1

0

You can sample your ticks and set the list as your new ticks.

# current x labels
current_ticks = ax.get_xticklabels()
# resampling every other label, change mod(2) to sample less
custom_ticks = [a.get_text() for a in current_ticks if current_ticks.index(a)%2] 
# set as new labels
ax.set_xticks(custom_ticks)
ax.set_xticklabels(custom_ticks)
ilke444
  • 2,641
  • 1
  • 17
  • 31
  • @like444, hi thanks, i'm getting the following error.. tbh i dont really understand the that line of code for sampling.. do u have any idea how to fix the error? --------------------------------------------------------------------------- NameError Traceback (most recent call last) in () 1 current_ticks = ax.get_xticklabels() ----> 2 custom_ticks = [a for a in names if names.index(a)%2] NameError: name 'names' is not defined – Jeremy Mar 04 '20 at 07:03
  • I fixed the code. `names` was `current_ticks` in my example. I am sampling the ticks based on their indices, for example `current_ticks.index(a)%2` means if the index is divisible by 2, sampling every other tick. If you want even sparser labels, you can increase 2. – ilke444 Mar 10 '20 at 00:27