Hi I have the following code. The code is in a for loop, and it makes over 300 plots.
sns.set(style='white', palette='cubehelix', font='sans-serif')
fig, axs = plt.subplots(2, 3, dpi =200);
fig.subplots_adjust(hspace=0.5, wspace=1)
plt.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False) # labels along the bottom edge are off
#tmppath = 'path/{0}'.format(key);
##
sns.countplot(y='Ethnicity', data=value, orient='h', ax=axs[0,0]);
sns.despine(top=True, right=True, left=True, bottom=True,offset=True)
sns.countplot(y='Program Ratio', data=value,orient='v',ax=axs[1,0]);
sns.despine(offset=True)
sns.countplot(y='Site', data = value, ax=axs[0,1]);
sns.despine(offset=True)
sns.countplot(y='HOUSING_STATUS', data = value, ax = axs[1,1])
sns.despine(offset=True)
sns.countplot(y='Alt. Assessment', data = value, ax = axs[0,2])
sns.despine(offset=True)
pth = os.path.join(tmppath, '{0}'.format(key))
for p in axs.patches:
ax.text(p.get_x() + p.get_width()/2., p.get_width(), '%d' %
int(p.get_width()),
fontsize=12, color='red', ha='center', va='bottom')
#plt.tight_layout(pad=2.0, w_pad=1.0, h_pad=2.0);
plt.set_title('{0}'.format(key)+'Summary')
sns.despine()
axs[0,0].set_xticklabels('','Ethnicity')
axs[1,0].set_axis_labels('','Program Ratio')
axs[0,1].set_axis_labels('','Students by Site')
axs[1,1].set_axis_labels('','Housing Status')
axs[0,2].set_axis_labels('','Alt Assessment')
fig.tight_layout()
fig.subplots_adjust(top=0.88)
fig.suptitle('{0}'.format(key)+' Summary')
plt.suptitle('{0}'.format(key)+' Summary')
plt.savefig("path/{0}/{1}.pdf".format(key,key), bbox_inches = 'tight');
plt.clf()
plt.suptitle('{0} Summary'.format(key))
plt.savefig("path/{0}/{1}.pdf".format(key,key), bbox_inches = 'tight');
plt.clf()
I've checked out the links below ( and more):
Remove xticks in a matplotlib plot?
https://datascience.stackexchange.com/questions/48035/how-to-show-percentage-text-next-to-the-horizontal-bars-in-matplotlib
When I try the method from the second link. I end up with graphs like so
Without that the graph looks something like so
I want to get rid of the words count and the ticks on each subplot xaxis.
#ImportanceOfBeingErnest
Thanks, I followed your advice and this post.
Here is what is a compact version of what I ended up with
sns.set(style='white', palette=sns.palplot(sns.color_palette(ui)), font='sans-serif')
plt.figure(figsize=(20,20))
fig, axs2 = plt.subplots(2, 3, dpi =300);
fig.subplots_adjust(top=.8)
fig.subplots_adjust(hspace=1, wspace=1.5)
plt.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False) # labels along the bottom edge are off
sns.countplot(y='column',palette = ui,order = df.value_counts().index, data=df,
orient='h', ax=axs2[0,0]);
axs2[0,0].set_xlabel('')
axs2[0,0].set_xticks([])
axs2[0,0].set_ylabel('')
axs2[0,0].set_title('label',size = 'small')
axs2[0,0].tick_params(axis='y', which='major', labelsize=8)
sns.despine(top=True, right=True, left=True, bottom=True,offset=True)
for p in axs2[0,0].patches:
axs2[0,0].annotate(int(p.get_width()),((p.get_x() + p.get_width()), p.get_y()), xytext=(15, -10), fontsize=8,color='#000000',textcoords='offset points'
,horizontalalignment='center')
fig.suptitle('{0}#{1}'.format(dur,key)+' Summary', va = 'top', ha= 'center') #size = 'small')
props = dict(boxstyle='square', facecolor='white', alpha=0.5)
fig.text(0.85, 0.925, dt.date.today().strftime("%b %d, %Y"), fontsize=9, verticalalignment='top', bbox=props)
fig.text(0.15, 0.925, 'No. of stuff'+ str(len(value['column'].unique())),fontsize = 10, va = 'top', ha = 'center')
plt.savefig("path/{0}/{1} # {2}.pdf".format(dur,dur,key), bbox_inches = 'tight');
plt.clf()
plt.close('all')
Excuse the black marks, didn't want to show the info
Related
I want to draw a barplot with 3 different y values which belong to RMSE, R2 and MAPE metrics.
My dataframe is;
DLscores = {"GRU":[293.7372606050454,0.961253983114077,86281.57826775634],
"LSTM":[285.9872902525968,0.9632715628933957,81788.73018602304],
"LSTM_Attention":[266.6285102384448,0.9680756432778241,71090.76247197246],
"TCN":[219.30770326715282,0.9784018398981137,48095.868712313546],
"Hybrid":[216.97781461699145,0.978858312741761,47079.372035965505]}
I am able to do this with linegraph. However when I change it to bar, they overlaps. My line plot code is;
# Create figure and axis #1
fig, ax1 = plt.subplots(figsize=(16,10))
# plot line chart on axis #1
p1, = ax1.plot(DLscores.columns, DLscores.iloc[1], color='blue')
ax1.set_ylabel('R2')
#ax1.set_ylim(0, 25)
#ax1.legend(['R2'], loc="upper left")
ax1.yaxis.label.set_color(p1.get_color())
ax1.yaxis.label.set_fontsize(14)
ax1.tick_params(axis='y', colors=p1.get_color(), labelsize=14)
# set up the 2nd axis
ax2 = ax1.twinx()
# plot bar chart on axis #2
p2, = ax2.plot(DLscores.columns, DLscores.iloc[0], color='green')
ax2.grid(False) # turn off grid #2
ax2.set_ylabel('RMSE')
#ax2.set_ylim(0, 90)
#ax2.legend(['RMSE'], loc="upper center")
ax2.yaxis.label.set_color(p2.get_color())
ax2.yaxis.label.set_fontsize(14)
ax2.tick_params(axis='y', colors=p2.get_color(), labelsize=14)
# set up the 3rd axis
ax3 = ax1.twinx()
# Offset the right spine of ax3. The ticks and label have already been placed on the right by twinx above.
ax3.spines.right.set_position(("axes", 1.2))
# Plot line chart on axis #3
p3, = ax3.plot(DLscores.columns, DLscores.iloc[2], color='red')
ax3.grid(False) # turn off grid #3
ax3.set_ylabel('MAPE')
#ax3.set_ylim(0, 8)
#ax3.legend(['MAPE'], loc="upper right")
ax3.yaxis.label.set_color(p3.get_color())
ax3.yaxis.label.set_fontsize(14)
ax3.tick_params(axis='y', colors=p3.get_color(), labelsize=14)
plt.show()
Output:
I also tried seaborn (I couldn't figure it out how can I merge it with "hue"), but code and result is in below:
# plot line chart on axis #1
ax1 = sns.barplot(
x=DLscores.index,
y=DLscores['RMSE'],
color='blue'
)
ax1.set_ylabel('RMSE')
#ax1.set_ylim(0, 8)
ax1.legend(['RMSE'], loc="upper left")
ax1.yaxis.label.set_color('blue')
ax1.yaxis.label.set_fontsize(14)
ax1.tick_params(axis='y', colors='blue', labelsize=14)
# set up the 2nd axis
ax2 = ax1.twinx()
# plot bar chart on axis #2
sns.barplot(
x=DLscores.index,
y=DLscores['R2'],
color='orange',
ax = ax2 # Pre-existing axes for the plot
)
ax2.grid(False) # turn off grid #2
ax2.set_ylabel('R2')
#ax2.set_ylim(0, 90)
ax2.legend(['R2'], loc="upper center")
ax2.yaxis.label.set_color('orange')
ax2.yaxis.label.set_fontsize(14)
ax2.tick_params(axis='y', colors='orange', labelsize=14)
# set up the 3rd axis
ax3 = ax1.twinx()
# Offset the right spine of ax3. The ticks and label have already been placed on the right by twinx above.
ax3.spines.right.set_position(("axes", 1.15))
# Plot line chart on axis #3
p3 = sns.barplot(
x=DLscores.index,
y=DLscores['MAPE'],
color='red',
ax = ax3 # Pre-existing axes for the plot
)
ax3.grid(False) # turn off grid #3
ax3.set_ylabel('MAPE')
#ax3.set_ylim(0, 8)
ax3.legend(['MAPE'], loc="upper right")
ax3.yaxis.label.set_color('red')
ax3.yaxis.label.set_fontsize(14)
ax3.tick_params(axis='y', colors='red', labelsize=14)
plt.show()
I assume the problem is clear.
I just specify the x and y axis limitations but the numbers' order is wrong. how can I fix this?
here is my code:
fig, ax = plt.subplots(figsize=(20,10))
ax.plot(df.finish_price, label="Stock Values", color = 'blue')
plt.ylabel("Price", color='b')
# Generate a new Axes instance, on the twin-X axes (same position)
ax2 = ax.twinx()
ax2.plot(df.sentiment, label= 'Sentiment', color='green')
ax2.tick_params(axis='y', labelcolor='green')
plt.ylim(bottom = -1)
plt.ylim(top=1)
plt.xlabel("Days")
plt.ylabel("Sentiment", color='g')
fig.legend()
plt.show()
and here is the result:
as you can see the numbers' order on the right y-axis is wrong.
I have long tick labels on the x axis, they are rotated, I would like the text to align to the bottom (it would be the left if they were not rotated) I have tried different combinations of ha, and va, but I can not get what I would like - Here is an image of the current plot, and the code:
title = data[0][1]
subtitle = data[0][2]
column_A = 0
column_B = 1
columns = [column_A, column_B]
df = pd.DataFrame(columns=columns)
for sub_data, col in zip(data, columns):
df[col] = sub_data[4:]
# converts str to int
df[column_B] = df[column_B].replace('[\\$,]', '', regex=True).astype(float)
asin_title = df[column_A]
revenue = df[column_B]
# deconstruct fig and ax - this needs to be done before creating the histogram
fig, ax = plt.subplots(figsize=(8, 4), linewidth=1, edgecolor=gray)
# format y ticks, insert comma
# fmtr = StrMethodFormatter(('${x:,g}'))
# ax.yaxis.set_major_formatter(fmtr)
# Removes the spines
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# set the x limit
ax.set_xlim(-1, 30)
# create histogram using asin_title and revenue
plt.bar(asin_title, height=revenue, color=bar_blue,)
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(asin_title)
labels = ['\n'.join(wrap(title[:30] + '..', 22)) for title in asin_title]
ax.set_xticklabels(labels, rotation='vertical', fontsize=6)
for label in ax.xaxis.get_ticklabels()[10:]:
label.set_visible(False)
# for tick in ax.xaxis.get_majorticklabels():
# tick.set_horizontalalignment("left")
# create space from top of chart
plt.subplots_adjust(top=0.13)
# title, subtitle
plt.title(title, fontsize=14, fontweight='bold', ha='left',
color=dark_gray, pad=30, x=-0.04, y=0.98)
# use text() for subtitle with transform=ax.transAxes so matching x offsets line up
plt.text(-0.04, 1.11, subtitle, fontsize=8, fontweight='bold',
ha='left', transform=ax.transAxes, color=gray)
# y ticks
plt.yticks(fontsize=8)
ax.tick_params(axis='y', length=0)
# show lines on the y ticks
plt.grid(b=None, which='major', axis='y')
# set tight_layout
plt.tight_layout()
plt.savefig('top_asins.png')
plt.show()
fig, axes = plt.subplots(ncols=2, sharey=True, figsize=(12,12))
axes[0].barh(bar_chart.index, bar_chart['% Vaccinated'], align='edge', height=0.3,
color='red', zorder=1)
axes[0].set(title='% Fully Vaccinated)')
axes[1].barh(bar_chart.index, bar_chart['Deaths_Per_Confirmed_Case'], align='edge',height=0.3,
color='pink', zorder=1)
axes[1].set(title='% Deaths Per New Confirmed Cases')
axes[0].invert_xaxis()
axes[0].set(yticks=bar_chart.index)
axes[0].yaxis.tick_right()
for ax in axes.flat:
ax.margins(0.09)
ax.grid(True)
fig.tight_layout()
fig.subplots_adjust(wspace=.06)
plt.show()
So basically I just want to move my yticks up or down a notch. The above code produces the following graph:
You can probably see my problem there. My y-axis values are getting lost behind the bars. I can widen the space between the bars with the subplots_adjust at the bottom, but that's less pretty. Is there any way I can move the yticks up (or down)?
Also it'd be really nice to get ride of the 0 and 0.0 on the xticks.
Any helps appreciated.
Cheers folks.
Since it is not possible to display the y-axis up across the graphs, I suggest merging the two graphs with zero spacing. How about annotating the country names and numbers in that state to ensure a good look? To deal with the starting point of the x-axis tick marks on the right, I got the current tick value and replaced the first tick value with zero as a string.
fig, axes = plt.subplots(ncols=2, sharey=True, figsize=(12,12))
axes[0].barh(bar_chart.index, bar_chart['% Vaccinated'], align='center', height=0.3, color='red', zorder=1)
axes[0].set(title='% Fully Vaccinated)')
axes[1].barh(bar_chart.index, bar_chart['Deaths_Per_Confirmed_Case'], align='center',height=0.3, color='pink', zorder=1)
axes[1].set(title='% Deaths Per New Confirmed Cases')
axes[0].invert_xaxis()
axes[0].set(yticks=bar_chart.index)
axes[0].yaxis.tick_right()
new_labels = bar_chart.index.tolist()
for ax in axes.flat:
ax.margins(0.09)
ax.grid(True)
new_labels = bar_chart.index.tolist()
for rect,rect2,lbl in zip(axes[0].patches, axes[1].patches,new_labels):
width = rect.get_width()
width2 = rect2.get_width()
ypos = rect.get_y()
axes[0].annotate(lbl, (width, ypos+0.1), xytext=(3, 0), textcoords='offset points', size=20, color='white')
axes[0].annotate(str(width), (12, ypos+0.1), xytext=(3, 0), textcoords='offset points', size=20, color='white')
axes[1].annotate(str(width2), (0.01, ypos+0.1), xytext=(3, 0), textcoords='offset points', size=20, color='red')
ax1_labels = [str(round(l,1)) for l in axes[1].get_xticks()]
ax1_labels[0] = '0'
axes[1].set_xticklabels(ax1_labels)
fig.tight_layout()
fig.subplots_adjust(wspace=0.0)
plt.show()
I want to keep the major tick labels, that matplotlib has automatically generated, in their default position under the figure. However, I myself added some minor ticks (with vertical lines) at specific x values, but their labels don't fit between the default major ticks. How can I move these labels to the top of the figure?
My code for reference:
meta = comparisons['meta']
lagsAnycast = np.array(meta['lagsAnycast'])
lagsPenultimate = np.array(meta['lagsPenultimate'])
avgLagAnycast = meta['avgLagAnycast']
avgLagPenultimate = meta['avgLagPenultimate']
plt.step(lagsAnycast, (np.arange(lagsAnycast.size) + 1)/lagsAnycast.size, color='k', label='to anycast IPs', linewidth=1.5)
plt.step(lagsPenultimate, (np.arange(lagsPenultimate.size) + 1)/lagsPenultimate.size, color='k', label='to penultimate IPs', linewidth=1)
plt.axvline(round(avgLagAnycast,1), ls="dashed", color="k", label="average lag to anycast IPs", linewidth=1.5)
plt.axvline(round(avgLagPenultimate,1), ls="dashed", label="average lag to penultimate IPs", color="k", linewidth=1)
plt.axis([-0.34,60,0.7,1])
plt.xlabel("Lag (ms)")
plt.ylabel("CDF")
existingTicks = (plt.xticks())[0][1:].tolist()
plt.gca().xaxis.grid(True, which='major')
plt.gca().xaxis.grid(False, which='minor')
plt.gca().tick_params(axis="x", which="minor", direction="out", top=True)
plt.gca().set_xticks([round(avgLagAnycast,1), round(avgLagPenultimate,1)], minor=True)
plt.legend(loc='right', fontsize=10)
plt.grid(True, ls="dotted")
majorFormatter = FormatStrFormatter('%g')
plt.gca().xaxis.set_major_formatter(majorFormatter)
plt.savefig(os.path.join(os.getcwd(), "datasets/plots/CDF1.png"))
You can use Locators and Formatters to set the ticks and ticklabels and turn them on or off using tick_params:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
x = np.linspace(-3,3)
plt.plot(x, np.sin(x))
ticks = [-np.pi/2,np.pi/2.]
labels = [r"$-\frac{\pi}{2}$",r"$\frac{\pi}{2}$"]
ax = plt.gca()
ax.xaxis.set_minor_locator(ticker.FixedLocator(ticks))
ax.xaxis.set_minor_formatter(ticker.FixedFormatter(labels))
# Set visibility of ticks & tick labels
ax.tick_params(axis="x", which="minor", direction="out",
top=True, labeltop=True, bottom=False, labelbottom=False)
plt.show()