Add grid and change size in barh python - python

I am using matplotlib to draw horizontal plots. I want to add grids and change size of the plot to avoid overleap of the label. My code looks like this:
baseline = [0.5745,0.5282,0.4923,0.5077,0.5487,0.5385,0.5231]
low = [0.2653,0.3878,0.3673,0.5510,0.2245,0.5714,0.3265]
high = [0.5102,0.5102,0.3673,0.3877,0.5306,0.4286,0.49]
index = ['Bagging','Decision tree','Gussian Naive Bayes','Logistic regression','Random forest','SVM','k-NN']
df = pd.DataFrame({'Baseline': baseline,'ttd lower than median': low,'ttd higher than median': high}, index=index)
plt.figure(figsize = (6,12))
ax.yaxis.grid(color='gray', linestyle='dashed')
ax = df.plot.barh()
and the resulting plot looks like this:
However, it didn't show the grid and "plt.figure(figsize = (6,12))" seems did not work. How can I fix this? Thanks in advance!

Specify the location of the legend by using plt.legend
Making the figure larger won't necessarily make the legend fit better
Show the grid by using plt.grid()
plt.figure(figsize = (6,12)) didn't work, because the dataframe plot wasn't using this axes.
fig, ax = plt.subplots(figsize=(7, 12))
ax.yaxis.grid(color='gray', linestyle='dashed')
df.plot.barh(ax=ax) # ax=ax lets the dataframe plot use the subplot axes
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # place the legend outside
plt.grid() # show the grid
Alternatively, use df.plot.barh(ax=ax, figsize=(7, 12))
p = df.plot.barh(figsize=(7, 8))
p.yaxis.grid(color='gray', linestyle='dashed')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

Related

Twinx makes labels disappear

I have an issue with setting the x labels while using twinx function. My original data is a pandas dataframe, namely, df, which has 3 attributes, "name"=product name, "sold"=number of items sold, and "revenue". the name is a pandas series (like "2 shampoo"), but I can't set it to be x tick label (see pic below). How could I set the x labels to display the product's names?
fig = plt.figure() # Create matplotlib figure
ax = fig.add_subplot(111) # Create matplotlib axes
ax2 = ax.twinx() # Create another axes that shares the same x-axis as ax.
width = 0.4
df.sold.plot(kind='bar', color='red', ax=ax, width=width, position=1, rot=90)
df.revenue.plot(kind='bar', color='blue', ax=ax2, width=width, position=0, rot=90)
# print(type(df['name']), "\n", df['name'])
ax.set_ylabel('Sold')
ax2.set_ylabel('Revenue')
ax.legend(['Sold'], loc='upper left')
ax2.legend(['Revenue'], loc='upper right')
plt.show()
You will need to set the labels for X-axis using the set_xticklabels() to show the fields. Add this line after plotting the graph.
ax.set_xticklabels(df.Name)
and you will get the below plot.

How to plot two series with very different scales in python

I'm a beginner in python. I have to plot two graphs in the same plot. One of my graphs is velocity, which ranges between (-1,1), and the other one is groundwater, which ranges between (10,12). When I use the following code, the graphs become very small.
ax1 = plt.subplot(111)
ax2 = ax1.twinx()
df=pd.read_excel ('final-all-filters-0.6.xlsx')
df['Date']=pd.to_datetime(df['Date'])
date = df['Date']
gwl = df['gwl']
v =df['v']
plt.plot(date,gwl, color='deepskyblue',linewidth=2)
plt.plot(date,v, color='black',linewidth=2)
ax1.grid(axis='y')
ax1.xaxis.set_major_locator(matplotlib.dates.YearLocator())
ax1.xaxis.set_minor_locator(matplotlib.dates.MonthLocator((1,3,5,7,9,11)))
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter("\n%Y"))
ax1.xaxis.set_minor_formatter(matplotlib.dates.DateFormatter("%b"))
ax1.grid(which='minor', alpha=0.3, linestyle='--')
ax1.grid(which='major', alpha=2)
for spine in ax1.spines.values():
spine.set_edgecolor('gray')
ax1.tick_params(axis='x', which='both', colors='gray')
ax1.tick_params(axis='y', colors='gray')
ax1.set_ylabel('v', color='g')
ax2.set_ylabel('GWL', color='b')
plt.show()
But when I add the ax1.set_ylim(-1, 1)and ax2.set_ylim(10, 12) to my code, one of the graph was disappered!
I think it does plot the black graph, but it's out of range. You can check that by adding 11 or something to the black plot value.
Maybe you can try using ax2.set_yticks(np.arange(-1, 1, 0.5)) instead of set_ylim and/or using ax2.autoscale(enable=True, axis=y)

Two subplots coming out too long (length)

I'm attempting to plot two bar charts using matplotlib.pyplot.subplots. I've created subplots within a function, but when I output the subplots they are too long in height and not long enough in width.
Here's the function that I wrote:
def corr_bar(data1, data2, method='pearson'):
# Basic configuration.
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(7, 7))
ax1, ax2 = axes
corr_matrix1 = data1.corr(method=method)
corr_matrix2 = data2.corr(method=method)
cmap = cm.get_cmap('coolwarm')
major_ticks = np.arange(0, 1.1, 0.1)
minor_ticks = np.arange(0, 1.1, 0.05)
# Values for plotting.
x1 = corr_matrix1['price'].sort_values(ascending=False).index
x2 = corr_matrix2['price'].sort_values(ascending=False).index
values1 = corr_matrix1['price'].sort_values(ascending=False).values
values2 = corr_matrix2['price'].sort_values(ascending=False).values
im1 = ax1.bar(x1, values1, color=cmap(values1))
im2 = ax2.bar(x2, values2, color=cmap(values2))
# Formatting for plot 1.
ax1.set_yticks(major_ticks)
ax1.set_yticks(minor_ticks, minor=True)
plt.setp(ax1.get_xticklabels(), rotation=45, ha='right', rotation_mode='anchor')
ax1.grid(which='both')
ax1.grid(which='minor', alpha=0.4)
ax1.grid(which='major', alpha=0.7)
ax1.xaxis.grid(False)
# Formatting for plot 2.
ax2.set_yticks(major_ticks)
ax2.set_yticks(minor_ticks, minor=True)
plt.setp(ax2.get_xticklabels(), rotation=45, ha='right', rotation_mode='anchor')
ax2.grid(which='both')
ax2.grid(which='minor', alpha=0.4)
ax2.grid(which='major', alpha=0.7)
ax2.xaxis.grid(False)
fig.tight_layout()
plt.show()
This function (when run with two Pandas DataFrames) outputs an image like the following:
I purposely captured the blank right side of the image as well in an attempt to better depict my predicament. What I want is for the bar charts to be appropriately sized in height and width as to take up the entire space, rather than be elongated and pushed to the left.
I've tried to use the ax.set(aspect='equal') method but it "scrunches up" the bar chart. Would anybody happen to know what I could do to solve this issue?
Thank you.
When you define figsize=(7,7) you are setting the size of the entire figure and not the subplots. So your entire figure must be a square in this case. You should change it to figsize=(14,7) or use a number larger than 14 to get a little bit of extra space.

Plotting multiple series on a line/bar graph with pandas

I'm trying to make a plot of a line and bar on the same graph. I'm close, but I can't solve a few items. Here's what I have so far...
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.DataFrame({'Value1': np.arange(80, 180, 1),
'Value2': np.arange(1.5, .5, -0.01)},
index=np.arange(10, 110, 1))
fig, ax = plt.subplots(figsize=(10, 10))
data['Value1'].plot(ax=ax)
ax2 = ax.twinx()
data['Value2'].plot(kind='bar', ax=ax2, color='y', ylim=(0, 3))
So the problems I have with this graph are...
The x-ticks look awful. If I only do a line graph, the x-ticks look fine. As soon as I add the twinx axis however, the major/minor ticks logic get's dropped. How can I keep that?
My x-axes is numeric. Note that the line intercepts the x-axis at the value "10" (its hard to see, but that's what's going on). I presume this is because the line's x-axis is supposed to begin at "10" and the bar's x-axis begins at 10 as well, but there's confusion of the value and label so the line's x-axis get's pushed over the label "20".
What's the best way to do this?
Bar plot and line plot has different X coordinate range is different, consider using two x coordinate.
you can try to save xticks and xtickslabels after data['Value1'].plot(ax=ax) and set them back after data['Value2'].plot(kind='bar', ax=ax2, color='y', ylim=(0, 3)):
data['Value1'].plot(ax=ax)
xticks = ax.get_xticks()
xlabels = [x.get_text() for x in ax.get_xticklabels()]
ax2 = ax.twinx()
data['Value2'].plot(kind='bar', ax=ax2, color='y', ylim=(0, 3))
ax.set_xticks(xticks)
ax.set_xticklabels(xlabels)
plt.show()

Change xticklabels fontsize of seaborn heatmap

Here is my question:
I plot 7 variable's coefficient using sns.clustermap()
x/y tickslabel seems really small(In my case, s1,s2,... s9)
My attempt
label='big ==> no effect
plt.tick_params(axis='both', which='minor', labelsize=12) ===> cbar label has changed, but the x/y axes looks the same.
Add
My code:
ds = pd.read_csv("xxxx.csv")
corr = ds.corr().mul(100).astype(int)
cmap = sns.diverging_palette(h_neg=210, h_pos=350, s=90, l=30, as_cmap=True)
sns.clustermap(data=corr_s, annot=True, fmt='d',cmap = "Blues",annot_kws={"size": 16},)
Consider calling sns.set(font_scale=1.4) before plotting your data. This will scale all fonts in your legend and on the axes.
My plot went from this,
To this,
Of course, adjust the scaling to whatever you feel is a good setting.
Code:
sns.set(font_scale=1.4)
cmap = sns.diverging_palette(h_neg=210, h_pos=350, s=90, l=30, as_cmap=True)
sns.clustermap(data=corr, annot=True, fmt='d', cmap="Blues", annot_kws={"size": 16})
Or just use the set_xticklabels:
g = sns.clustermap(data=corr_s, annot=True, fmt='d',cmap = "Blues")
g.ax_heatmap.set_xticklabels(g.ax_heatmap.get_xmajorticklabels(), fontsize = 16)
To get different colors for the ticklabels:
import matplotlib.cm as cm
colors = cm.rainbow(np.linspace(0, 1, corr_s.shape[0]))
for i, ticklabel in enumerate(g.ax_heatmap.xaxis.get_majorticklabels()):
ticklabel.set_color(colors[i])

Categories