Reverse vertical one of the subplots in python - python

I have two data frames to plot. One of bar chart, another one is a line chart.
I want to plot the barchart upside to down. (vertically reversed.)
How can i handle this?
fig, ax1 = plt.subplots(figsize=(10, 5))
tidy = results.melt(id_vars='Day').rename(columns=str.title)
ax1 = sns.lineplot(x='Day', y='Value', hue='Variable', data=tidy, ax=ax1)
tidy2 = drugs.melt(id_vars='Day').rename(columns=str.title)
ax1 = sns.barplot(x='Day', y='Value', hue='Variable', data=tidy2, ax=ax1)
ax1.xaxis.set_major_locator(ticker.MultipleLocator(10))
ax1.legend(loc=1)
ax1.tick_params(axis='x', labelrotation=45)

Related

Adding a line to a bar chart

I want to create a bar line chart with matplotlib based on happiness index database.
I would like to indicate the generosity indexes of each of the countries on the secondary y-axis with a line chart. df1['Generosity']
fig, ax = plt.subplots()
ax.bar(df1['Country name'], df1['Ladder score'])
plt.xticks(rotation=30, ha='right')
fig.set_size_inches(18, 10, forward=True)
This solved my problem.
x=df1['Country name']
y=df1['Generosity']
ax2 = ax.twinx()
ax2 = plt.plot(x, y,color ='r')
plt.ylabel('Generosity')
plt.show()

Plotting: How to space xticks?

After aggregation, i plotted the numbers but iam struggling to space the xticks
Aggregation
tweet['Retweets']=pd.to_numeric(tweet['Retweets'])
tweet['Favorites']=pd.to_numeric(tweet['Favorites'])
sum_df = tweet.groupby(['Realdate'], as_index=False).agg({'Retweets': 'sum', 'Favorites': 'sum'})
sum_df=sum_df.reset_index()
Plotting
fig, ax1 = plt.subplots(figsize=(15, 10))
ax2 = ax1.twinx()
ax1.set_xlabel('Dates')
ax1.set_ylabel('Favorites', color='b')
ax2.set_ylabel('Retweets', color='b')
ax1.yaxis.tick_right()
ax2.yaxis.tick_left()
sum_df['Favorites'].plot( kind='bar', color='y', ax=ax1)
sum_df['Retweets'].plot( kind='line', marker='d', ax=ax2)
ax1.legend(loc=2) # is this the right thing to do to place legends?
ax2.legend(loc=1) # is this the right thing to do to place legends?
ax1.set_xticklabels(sum_df.Realdate.values, rotation=90)
plt.title('Sum of Daily "Likes" and Retweets Time Series')
plt.show()
The resulting output
Can you please help me with the xticks spacing please? I tried several methods but no results.
Thanks very much

Trying to plot 2 charts side-by-side, but one of them always comes out empty

I have two plots that I generated from my data:
Here the second plot shows the distribution of results from the first one.
What I want is to plot them side-by-side so you could see both the data and the distribution on the same plot. And I want plots to share y-axis as well.
I tried to do the following:
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(40, 15), sharey=True)
ax1 = sns.lineplot(plotting_df.index, plotting_df.error, color=('#e65400'), lw=2, label='random forest residual error')
ax1 = sns.lineplot(plotting_df.index, plotting_df.val, color=('#9b9b9b'), lw=1, label='current model residual error')
ax1 = sns.lineplot(plotting_df.index, 0, color=('#2293e3'), lw=1)
ax1.xaxis.set_visible(False)
ax1.set_ylabel('Residual Fe bias', fontsize=16)
ax1.set_title('Models residual error comparison', fontsize=20, fontweight='bold')
sns.despine(ax=ax1, top=True, bottom=True, right=True)
ax2 = sns.distplot(results_df.error, hist=True, color=('#e65400'), bins=81,
label='Random forest model', vertical=True)
ax2 = sns.distplot(plotting_df.val, hist=True, color=('#9b9b9b'),
bins=81, label='Rolling averages model', vertical=True)
ax2.set_title('Error distribution comparison between models', fontsize=20, fontweight='bold')
sns.despine(ax=ax2, top=True, right=True)
fig.savefig("blabla.png", format='png')
But when I do run it I get strange results - the first chart is in the second column, whereas I wanted it on the left and the second chart is completely blank. Not sure what I did wrong here.
Both lineplot and distplot accept a matplotlib axes object as an argument, which tells it which axes to plot onto. If no axes is passed into it, then the plot is placed onto the current axes.
You create a figure and 2 axes using :
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(40, 15), sharey=True)
Therefore, ax2 will be the current axes. So your distplot is being plotted on top of your lineplot, both in ax2.
You need to pass the axes into the seaborn plotting functions.
sns.lineplot(..., ax=ax1)
sns.distplot(..., ax=ax2)

How to plot multiple figures in a row using seaborn

I have a dataframe df that looks like this:
df.head()
id feedback nlp_model similarity_score
0xijh4 1 tfidf 0.36
0sdnj7 -1 lda 0.89
kjh458 1 doc2vec 0.78
....
I want to plot similairty_score versus feedback in a boxplot form using seaborn for each of the unique values in the model column: tfidf, lda, doc2vec. My code for this is as follows:
fig, ax = plt.subplots(figsize=(10,8))
ax = sns.boxplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='tfidf'])
ax = sns.swarmplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='tfidf'], color="0.25")
fig, ax = plt.subplots(figsize=(10,8))
ax = sns.boxplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='lda'])
ax = sns.swarmplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='lda'], color="0.25")
fig, ax = plt.subplots(figsize=(10,8))
ax = sns.boxplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='doc2vec'])
ax = sns.swarmplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='doc2vec'], color="0.25")
plt.show()
The problem is this creates 3 plots one on top of the other.
How can I generate these same plots but all on a single line, with one axis marking "Similarity Score" on the left most plot only, and "Feedback" axis label directly below each plot?
You are creating new figures, each time you plot. So you can remove all but one of the calls to plt.subplots()
The seaborn swarmplot() and boxplot() accept ax arguments i.e. you can tell it which axes to plot to. Therefore, create your figure, subplots and axes using:
fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
Then you can do something like:
sns.boxplot(x="x_vals", y="y_vals", data=some_data, ax=ax1)
You can then manipulate the axes as you see fit. For example, removing the y axis labels only on certain subplots etc.
fig, (ax1, ax2, ax3) = plt.subplots(1,3,figsize=(10,8))
sns.boxplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='tfidf'], ax=ax1)
sns.swarmplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='tfidf'], color="0.25", ax=ax1)
sns.boxplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='lda'], ax=ax2)
sns.swarmplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='lda'], color="0.25", ax=ax2)
ax2.set_ylabel("") # remove y label, but keep ticks
sns.boxplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='doc2vec'], ax=ax3)
sns.swarmplot(x="feedback", y="similarity_score", data=df[df.nlp_model=='doc2vec'], color="0.25", ax=ax3)
ax3.set_ylabel("") # remove y label, but keep ticks
plt.show()

Matplotlib subplots: legend and axis-scale

I am plotting 4 subplots (i.e 2 rows 2 columns) in this way:
fig1= plt.figure(figsize=(8,6))
ax1 = fig1.add_subplot(221)
ax1.errorbar((r1),(xi1),fmt='',yerr=(low_err_1,upp_err_1),ls='none',color='black')
ax1.scatter((r1),(xi1),c='red',marker="o",s=30,label= r'$\xi(r)$ $0.0<z<0.5$')
ax1.plot((r1),(curve_y_1),'--',label='fit $0.0<z<0.5$')
ax1.set_xscale('log')
ax1.set_yscale('log')
ax2 = fig1.add_subplot(222)
ax2.errorbar((r2),(xi2),fmt='',yerr=(low_err_2,upp_err_2),ls='none',color='black')
ax2.scatter((r2),(xi2),c='blue',marker="o",s=30,label=r'$\xi(r)$ $0.5<z<1.0$')
ax2.plot((r2),(curve_y_2),'--',label='fit $0.5<z<1.0$')
ax2.set_xscale('log')
ax2.set_yscale('log')
ax3 = fig1.add_subplot(223)
ax3.errorbar((r3),(xi3),fmt='',yerr=(low_err_3,upp_err_3),ls='none',color='black')
ax3.scatter((r3),(xi3),c='yellow',marker="o",s=30,label=r'$\xi(r)$ $1.0<z<1.5$')
ax3.plot((r3),(curve_y_3),'--',label='fit $1.0<z<1.5$')
ax3.set_xscale('log')
ax3.set_yscale('log')
ax4 = fig1.add_subplot(224)
ax4.errorbar((r4),(xi4),fmt='',yerr=(low_err_4,upp_err_4),ls='none',color='black')
ax4.scatter((r4),(xi4),c='black',marker="o",s=30,label=r'$\xi(r)$ $1.5<z<2.0$')
ax4.plot((r4),(curve_y_4),'--',label='fit $1.5<z<2.0$')
ax4.set_xscale('log')
ax4.set_yscale('log')
My questions are:
Is there a way to add legends to all these subplots using a single (common) command, instead of typing ax1.legend(loc = 'best'), ax2.legend(loc = 'best') and so on separately for each subplot?
I would like to set log-scaling for each subplot using a single (common) command. As you can see, now I am setting the axis-scales separately to log for each subplot.
Just define a axes formatting function:
def style_ax(ax):
ax.legend(loc='best')
ax.set_yscale('log')
ax.set_xscale('log')
And than call it when finished:
for ax in [ax1, ax2, ax3, ax4]:
style_ax(ax)

Categories

Resources