Have a look at the graph below:
It's a subplot of this larger figure:
I see two problems with it. First, the x-axis labels overlap with one another (this is my major issue). Second. the location of the x-axis minor gridlines seems a bit wonky. On the left of the graph, they look properly spaced. But on the right, they seem to be crowding the major gridlines...as if the major gridline locations aren't proper multiples of the minor tick locations.
My setup is that I have a DataFrame called df
which has a DatetimeIndex
on the rows and a column called value
which contains floats. I can provide an example of the df
contents in a gist if necessary. A dozen or so lines of df
are at the bottom of this post for reference.
Here's the code that produces the figure:
now = dt.datetime.now() fig, axes = plt.subplots(2, 2, figsize=(15, 8), dpi=200) for i, d in enumerate([360, 30, 7, 1]): ax = axes.flatten()[i] earlycut = now - relativedelta(days=d) data = df.loc[df.index>=earlycut, :] ax.plot(data.index, data['value']) ax.xaxis_date() ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.grid(b=True, which='major', color='w', linewidth=1.5) ax.grid(b=True, which='minor', color='w', linewidth=0.75)
What is my best option here to get the x-axis labels to stop overlapping each other (in each of the four subplots)? Also, separately (but less urgently), what's up with the minor tick issue in the top-left subplot?
I am on Pandas 0.13.1, numpy 1.8.0, and matplotlib 1.4.x.
Here's a small snippet of df
for reference:
id scale tempseries_id value timestamp 2014-11-02 14:45:10.302204+00:00 7564 F 1 68.0000 2014-11-02 14:25:13.532391+00:00 7563 F 1 68.5616 2014-11-02 14:15:12.102229+00:00 7562 F 1 68.9000 2014-11-02 14:05:13.252371+00:00 7561 F 1 69.0116 2014-11-02 13:55:11.792191+00:00 7560 F 1 68.7866 2014-11-02 13:45:10.782227+00:00 7559 F 1 68.6750 2014-11-02 13:35:10.972248+00:00 7558 F 1 68.4500 2014-11-02 13:25:10.362213+00:00 7557 F 1 68.1116 2014-11-02 13:15:10.822247+00:00 7556 F 1 68.2250 2014-11-02 13:05:10.102200+00:00 7555 F 1 68.5616 2014-11-02 12:55:10.292217+00:00 7554 F 1 69.0116 2014-11-02 12:45:10.382226+00:00 7553 F 1 69.3500 2014-11-02 12:35:10.642245+00:00 7552 F 1 69.2366 2014-11-02 12:25:12.642255+00:00 7551 F 1 69.1250 2014-11-02 12:15:11.122382+00:00 7550 F 1 68.7866 2014-11-02 12:05:11.332224+00:00 7549 F 1 68.5616 2014-11-02 11:55:11.662311+00:00 7548 F 1 68.2250 2014-11-02 11:45:11.122193+00:00 7547 F 1 68.4500 2014-11-02 11:35:11.162271+00:00 7546 F 1 68.7866 2014-11-02 11:25:12.102211+00:00 7545 F 1 69.2366 2014-11-02 11:15:10.422226+00:00 7544 F 1 69.4616 2014-11-02 11:05:11.412216+00:00 7543 F 1 69.3500 2014-11-02 10:55:10.772212+00:00 7542 F 1 69.1250 2014-11-02 10:45:11.332220+00:00 7541 F 1 68.7866 2014-11-02 10:35:11.332232+00:00 7540 F 1 68.5616 2014-11-02 10:25:11.202411+00:00 7539 F 1 68.2250 2014-11-02 10:15:11.932326+00:00 7538 F 1 68.5616 2014-11-02 10:05:10.922229+00:00 7537 F 1 68.9000 2014-11-02 09:55:11.602357+00:00 7536 F 1 69.3500
Edit: Trying fig.autofmt_xdate()
: I don't think this going to do the trick. This seems to use the same x-tick labels for both graphs on the left and also for both graphs on the right. Which is not correct given my data. Please see the problematic output below:
Matplotlib x-axis label overlap In matplotlib, we have a method setp() that is used to set the rotation and alignment attributes of tick labels to avoid overlapping. To get ticklabels, we use the plt. setp() and get.
0 A common problem in making plots, say a barplot or boxplot with a number of groups is that, names of the groups on x-axis label often overlap with each other. Till now, one of the solutions to avoid overlapping text x-axis is to swap x and y axis with coord_flip() and make a horizontal barplot or boxplot.
Use legend() method to avoid overlapping of labels and autopct. To display the figure, use show() method.
Often you may use subplots to display multiple plots alongside each other in Matplotlib. Unfortunately, these subplots tend to overlap each other by default. The easiest way to resolve this issue is by using the Matplotlib tight_layout() function.
Ok, finally got it working. The trick was to use plt.setp
to manually rotate the tick labels. Using fig.autofmt_xdate()
did not work as it does some unexpected things when you have multiple subplots in your figure. Here's the working code with its output:
for i, d in enumerate([360, 30, 7, 1]): ax = axes.flatten()[i] earlycut = now - relativedelta(days=d) data = df.loc[df.index>=earlycut, :] ax.plot(data.index, data['value']) ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.grid(b=True, which='major', color='w', linewidth=1.5) ax.grid(b=True, which='minor', color='w', linewidth=0.75) plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right') fig.tight_layout()
By the way, the comment earlier about some matplotlib things taking forever is very interesting here. I'm using a raspberry pi to act as a weather station at a remote location. It's collecting the data and serving the results via the web. And boy oh boy, it's really wheezing trying to put out these graphics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With