Major and minor grid lines and ticks using matplotlib - python

I have two big intergers
min=round(raw_min,-5) # a negative number
max=round(raw_max,-5)
from which I get a range of interesting ticks:
xticks=np.arange(min,max,500000)
On the x-axis, I want to have minor ticks (including labels) for the xticks range. Furthermore, I want to have a major tick and grid line at the value 0. I tried to add:
minorLocator = FixedLocator(xticks)
majorLocator = FixedLocator([0])
ax.xaxis.set_major_locator(majorLocator)
ax.xaxis.set_major_formatter(FormatStrFormatter('%d'))
ax.xaxis.set_minor_locator(minorLocator)
plt.tick_params(which='both', width=1)
plt.tick_params(which='major', length=7, color='b')
plt.tick_params(which='minor', length=4, color='r')
ax.yaxis.grid(True)
ax.xaxis.grid(b=True,which='major', color='b', linestyle='-')
but it doesn't work...
No ticks for the minors and no grid line for the major.
Any ideas?

Seems like I was missing the following line:
plt.grid(b=True,which='both')

Related

Matplotlib display grid line at bottom instead of spine

I'm trying to reproduce the following image using matplotlib
I figured I have two options to deal with the top and bottom grid lines: format the top/bottom spine to match the formatting of the grid lines, or turn off all spines and just display grid lines. I've gone with the latter, as it seems more straightforward:
ax.spines[:].set_visible(False)
ax.set_axisbelow(True)
ax.grid(True, axis='y', color='#9E9E9E')
This works for the top grid line, but the bottom of the plot displays the tick marks but not the bottom grid line:
Is it possible to make a grid line also appear at the bottom without changing the y-limits?
ax.grid() has a parameter clip_on= that can be set to False to avoid clipping by the axes borders.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
bars = ax.bar(['left', 'right'], [13160, 11569], color=['dimgrey', 'goldenrod'])
ax.bar_label(bars)
ax.spines[:].set_visible(False)
ax.set_axisbelow(True)
ax.grid(True, axis='y', color='#9E9E9E', clip_on=False)
ax.set_ylim(ymin=10000)
ax.tick_params(length=0) # hide tick marks
ax.axhline(10968, color='dodgerblue', lw=1.5)
ax.set_yticks([10000, 10968, 12000, 13000, 14000])
ax.get_yticklabels()[1].set_color('dodgerblue')
plt.show()

Plotting multiple horizontal lines for each distribution in strip plot subplots Matplotlib

I'm trying to plot the average calculated values as a line through the center of each plotted distribution for my data set.
My code looks like this:
for plot, var in zip(range(1, plot_num+1), var_list):
ax = fig.add_subplot(2, 2, plot)
# calculate averages
sns.stripplot(x=cluster_index_sample[cluster_type], y=cluster_index_sample[var],
jitter=jitter, linewidth=line_width, alpha=alpha, cmap=RS_colorwheel,
size=marker_size, ax=ax)
# create average lines
ax.axhline(y=cluster_index_sample['Average_'+(var)].iloc[0],
linewidth=3, xmin=0.2, xmax=0.5)
ax.set_ylabel(str(var), fontsize=y_lab)
ax.set_xlabel('')
ax.tick_params(axis='both', which='major', pad=10)
But when I plot this the horizontal lines only appear once per cluster_type (x-axis category).
How can I get it so that each set of numbered categorical values gets their own respective averages?
Since you did not provide a MCVE, I can't run your code. Nevertheless, you can try using a second for loop to iterate through all the variables for plotting the horizontal average line as follows. You will also have to modify the xmin and xmax for each line. I leave that up to you.
for plot, var in zip(range(1, plot_num+1), var_list):
ax = fig.add_subplot(2, 2, plot)
sns.stripplot(x=cluster_index_sample[cluster_type], y=cluster_index_sample[var],
jitter=jitter, linewidth=line_width, alpha=alpha, cmap=RS_colorwheel,
size=marker_size, ax=ax)
for v in var_list: # <--- Added here
ax.axhline(y=cluster_index_sample['Average_'+(v)].iloc[0],
linewidth=3, xmin=0.2, xmax=0.5) # <--- Added here
ax.set_ylabel(str(var), fontsize=y_lab)
ax.set_xlabel('')
ax.tick_params(axis='both', which='major', pad=10)

Overplot the mean line in Python

I'd like to get two lines (red and green) with the average of my data points in green and average of my data points in red. I'm using the following code, but it's not working. It's only showing the red and green data points, without the red average line
sns.set(rc={"figure.figsize": (16, 8)})
ax = events_all_metrics[["event_name","kambi_payback"]].plot(x="event_name", style='.',use_index=False, color ='green')
events_all_metrics[["event_name","pinny_payback"]].plot(x="event_name",style='.', color='red', ax=ax)
plt.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom='off', # ticks along the bottom edge are off
top='off', # ticks along the top edge are off
labelbottom='off')
plt.legend(loc=4, prop={'size': 15})
pinny_mean = events_all_metrics["pinny_payback"].mean()
ax.plot(pinny_mean, label='Pinny Mean', linestyle='--', color='red')
plt.show()
This is not working because your pinny_mean is a single value in y. plot needs points in y and x. In this case I recommend you use plt.axhline instead of plot. It plots a line of constant y that covers the whole range in x. For your example:
plt.axhline(y=pinny_mean, label='Pinny Mean', linestyle='--', color='red')

Setting the X Axes Limit in Matplotlib 1.4.3

I am trying to zoom in on a section of my plot. I used the following code to produce the high level plot below.
fig = poll_df.plot('Start Date', 'Difference',figsize=(12,4),marker='o',linestyle='-',color='purple')
# Now add the debate markers
plt.axvline(x=403+2, linewidth=4, color='grey')
plt.axvline(x=403+10, linewidth=4, color ='grey')
plt.axvline(x=403+21, linewidth=4, color='grey')
plt.show()
The vertical grey bars are in the right locations and I want to zoom in on the plot (basically to show the month of October). I modified the plot to add the xlim parameters as below.
fig = poll_df.plot('Start Date', 'Difference',figsize=(12,4), marker='o',linestyle='-',color='purple',xlim=(403,433))
# Now add the debate markers
plt.axvline(x=403+2, linewidth=4, color='grey')
plt.axvline(x=403+10, linewidth=4, color ='grey')
plt.axvline(x=403+21, linewidth=4, color='grey')
plt.show()
However, this gives me a totally different plot (see below). I have tried all sorts of variations and still can't seem to get it to work. It looks as if the vertical bars would be in the right places if the axis labels reflected the month of October.
Why did the plot not rescale the x labels?

How to rotate secondary y axis label so it doesn't overlap with y-ticks, matplotlib

I am trying to rotate my secondary y-label to 270 degrees, but when I do this passing the rotate=270 argument it overlaps my y-tick text. Any ideas how to fix this?
fig, ax = plt.subplots()
ax.plot(df.index,df.tripTime,label='Fishing Effort', marker='D')
ax2=ax.twinx()
ax2.plot(tr.index,tr.cost, 'g',label='Fuel Expenditure', marker='d')
lines = ax.get_lines() + ax2.get_lines()
ax.legend(lines,[line.get_label() for line in lines], loc='lower left')
ax.set_ylim((0, 18))
ax2.set_ylabel('Cost ($)',color='g', rotation=270)
for tl in ax2.get_yticklabels():
tl.set_color('g')
ax.set_ylabel('Fishing Effort (hrs)')
ax.set_xlabel('Time (days)')
plt.show()
UPDATE: This answer isn't very good, please look at the comments!
This looks like a bug and you should probably report it to matplotlib's issue tracker.
While it is getting fixed, a quick solution is to set the label padding to a higher value:
ax2.set_ylabel('Cost ($)', color='g', rotation=270, labelpad=15)
Moreover, negative labelpad values can be used to decrease the white-space as well.

Categories

Resources