I am using the code below to generate this heatmap:
dim = np.arange(1, 32, 1)
fig, ax = plt.subplots(figsize=(7,9))
heatmap = ax.imshow(h.T, cmap=plt.cm.get_cmap('Blues', 4), clim=[1,144])
cbaxes = fig.add_axes([.8, .35, .04, .3])
cbar = fig.colorbar(heatmap, ticks = [1, 36, 72, 108, 144], label = 'Number of valid records per day', cax = cbaxes)
ax.set_ylabel("Days", fontsize=15)
ax.set_xlabel("Months", fontsize=15)
ax.set_title("Number of valid records per day", fontsize=20)
ax.set_yticks(range(0,31))
ax.set_yticklabels(dim, ha='center', minor=False, fontsize=12)
ax.set_xticks(range(0,13,1))
ax.set_xticklabels(ylabel, rotation = 45, ha = 'right')
ax.set_facecolor('gray')
cbar.set_label('Number of valid records')
ax.xaxis.set_minor_locator(MultipleLocator(0.5))
ax.yaxis.set_minor_locator(MultipleLocator(0.5))
ax.tick_params(axis='y', which='major', pad=10)
ax.grid(which = 'minor', color = 'w')
fig.show()
As you can see there is a slight offset of the gridlines with respect to the heat map cells. Why is that? How can I fix it?
Thanks to the comment left by Jody Klymak, I added the following line of code at the beginning of my notebook and it solved the problem:
matplotlib.rcParams['figure.dpi'] = 300
The first image is the figure I'm trying to reproduce, and the second image is the data I have. Does anyone have a clean way to do this with pandas or matplotlib?
Just transpose the DataFrame and use df.plot with the stacked flag set to true:
import pandas as pd
from matplotlib import pyplot as plt
df = pd.DataFrame({'squad': [0.6616, 0.1245, 0.0950],
'quac': [0.83, 0.065, 0.0176],
'quoref': [0.504, 0.340364, 0.1067]})
# Transpose
plot_df = df.T
# plot
ax = plot_df.plot(kind='bar', stacked=True, rot='horizontal')
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.)
ax.set_ylabel("% of Questions")
plt.tight_layout()
plt.show()
You can try this:
data = {'squad':[0.661669, 0.127516, 0.095005],
'quac':[0.930514, 0.065951, 0.017680],
'quoref': [0.504963, 0.340364, 0.106700]}
df = pd.DataFrame(data)
bars_1 = df.iloc[0]
bars_2 = df.iloc[1]
bars_3 = df.iloc[2]
# Heights of bars_1 + bars_2
bars_1_to_2 = np.add(bars_1, bars_2).tolist()
# The position of the bars on the x-axis
r = [0, 1, 2]
plt.figure(figsize = (7, 7))
plt.bar(r, bars_1, color = 'lightgrey', edgecolor = 'white')
plt.bar(r, bars_2, bottom = bars_1, color = 'darkgrey', edgecolor = 'white')
plt.bar(r, bars_3, bottom = bars_1_to_2, color = 'dimgrey', edgecolor = 'white')
plt.yticks(np.arange(0, 1.1, 0.1))
plt.xticks(ticks = r, labels = df.columns)
plt.ylabel('% of Questions')
plt.show()
I have a time series plot and I would like to add a vertical line to it at event time. If I use this code:
event_time = pd.to_datetime('10/12/2016 06:21:00')
ax = df_stats_t.plot(x = 't', y='t_TI_var_pwr', linestyle='none',...
color = 'black', marker = 'o')
ax1 = ax.twinx()
ax1.axvline(event_time, color='red', linestyle='-')
df_stats_t.plot(x='t',y='t_TI_var_ws',ax=ax1, linestyle='none', ...
color = 'green', marker = 'o')
It takes a subset of the time series starting at event_time and doesn't produce a vertical line.
If I move ax1.axvline(event_time, color='red', linestyle='-') to the bottom, I get the plot I want but the vertical line is still missing.
event_time = pd.to_datetime('10/12/2016 06:21:00')
ax = df_stats_t.plot(x = 't', y='t_TI_var_pwr', linestyle='none',...
color = 'black', marker = 'o')
ax1 = ax.twinx()
df_stats_t.plot(x='t',y='t_TI_var_ws',ax=ax1, linestyle='none',...
color = 'green', marker = 'o')
ax1.axvline(event_time, color='red', linestyle='-')
How can I get the vertical line to discplay at x = event_time for all y values?
works with plt
ax = df_stats_t.plot(x = 't', y='t_TI_var_pwr', linestyle='none', color = 'black', marker = 'o')
ax1 = ax.twinx()
df_stats_t.plot(x='t',y='t_TI_var_ws',ax=ax1, linestyle='none', color = 'green', marker = 'o')
plt.axvline(event_time, color='red', linestyle='-')
I have a dataframe as shown in the code and I generated a barh chart for each row using a loop. I am trying to plot a single legend for all the charts on the bottom-right corner but without success. I tried the lines of codes such as the ones below - and many others found online - inside the plotting loop and outside without success. Kindly suggest a solution that could work.
#handles, labels = bars.get_legend_handles_labels()
#bars.legend(handles, labels)
#bars.legend(loc='bottom right', ncol=9)
import pandas as pd
import matplotlib.pyplot as plt
import io
lines=['Business Category,Not_sure!,Performance_of_certain_applications,DNS_Resolution_Time,User’s_perception_of_your_network_(QoE),Routing_stability,Packet_loss/Jitter,Network_utilisation,Reachability,Latency,Bandwidth/Throughput\n'
'Academic
Institution,0.0,18.0,16.0,19.0,17.0,17.0,22.0,24.0,26.0,33.0\n'
'Civil society,0.0,5.0,2.0,2.0,1.0,1.0,2.0,4.0,4.0,6.0\n'
'End-user (Home/Mobile broadband),0.0,5.0,7.0,5.0,5.0,6.0,7.0,6.0,9.0,9.0\n'
'Internet Service Provider (ISP),1.0,20.0,22.0,22.0,27.0,31.0,20.0,25.0,32.0,32.0\n'
'Internet eXchange Point (IXP),0.0,2.0,3.0,2.0,7.0,6.0,5.0,5.0,8.0,7.0\n'
'Other,1.0,7.0,8.0,9.0,10.0,9.0,17.0,13.0,16.0,19.0\n'
'Regulator/Government Agency,0.0,1.0,1.0,2.0,1.0,0.0,2.0,1.0,4.0,5.0\n'
'Total,2.0,58.0,59.0,61.0,68.0,70.0,75.0,78.0,99.0,111.0\n']
df3 = pd.read_csv(pd.compat.StringIO("\n".join(lines)), sep=",").set_index('Business Category')
i = j = roundcounter = 0
patterns = ['\\', '|', '/', '+', 'x', 'o', 'O', '.', '*', '-']
color=['orange', 'darkseagreen', 'maroon', 'mediumpurple', 'saddlebrown', 'orchid', 'indianred',
'tomato', 'dimgrey', 'aquamarine']
fig, axes = plt.subplots(3,3, sharex=False, sharey=True)
print("\nWhich of these performance indicators/metrics are important for your organisation/network?\n\n")
for col in df3[:-1].index:
bars = df3.loc[col].plot.barh(width=.9, figsize=(15, 10), color=color, title=df3.loc[col].name,
ax=axes[i, j])
for spine in axes[i, j].spines:
axes[i, j].spines[spine].set_visible(False)
for bar, pattern in zip(bars.patches, patterns):
bar.set_hatch(pattern)
fig.tight_layout()
if j==2:
if roundcounter==0:
roundcounter+=1
i=1
j=0
elif roundcounter==1:
roundcounter+=1
j=0
i=2
elif roundcounter==2:
i=2
j=0
elif j==1 or j==0:
j+=1
axes[2, 1].axis('off')
axes[2, 2].axis('off')
bars.legend()
plt.savefig('figures/metrics.png')
plt.show()
As a new user I cannot post image yet but it is available here: https://drive.google.com/open?id=1c46FOZnA9aBtDb62kJg8h5bxePoTThrI
I am able to fix the problem after trying a number of solutions. See code below. There is an additional 'import matplotlib as mpl' to the libraries in the original question.
#Adding 'Total' row and column to use for sorting.
df3.loc['Total',:]= df3.sum(axis=0)
df3=df3[df3.iloc[-1,:].sort_values(ascending=False).index]
df3['Total'] = df3.sum(axis=1)
df3 = df3.sort_values(by='Total', ascending=False)
i = j = roundcounter = 0
patterns = ['\\', '|', '/', '+', 'x', 'o', 'O', '.', '*', '-']
color=['orange', 'darkseagreen', 'maroon', 'mediumpurple', 'saddlebrown', 'orchid', 'indianred',
'tomato', 'dimgrey', 'aquamarine']
fig, axes = plt.subplots(3,3, sharex=False, sharey=True)
print("\nWhich of these performance indicators/metrics are important for your organisation/network?\n\n")
#Plot the graphs
for col in df3[1:].index:
bars = df3.loc[col].drop(['Total']).plot.barh(width=.9, figsize=(22, 18), color=color, ax=axes[i, j])
axes[i, j].set_title(df3.loc[col].name, fontdict={'fontsize': 25, 'fontweight': 'medium'})
axes[i, j].get_yaxis().set_ticklabels([])
for tick in axes[i, j].xaxis.get_major_ticks():
tick.label.set_fontsize(25)
for spine in axes[i, j].spines:
axes[i, j].spines[spine].set_visible(False)
for bar, pattern in zip(bars.patches, patterns):
bar.set_hatch(pattern)
if j==2:
if roundcounter==0:
roundcounter+=1
i=1
j=0
elif roundcounter==1:
roundcounter+=1
j=0
i=2
elif roundcounter==2:
i=2
j=0
elif j==1 or j==0:
j+=1
axes[0, 2].set_xticks([0, 4, 8, 12, 16, 20], minor=False)
axes[2, 1].axis('off')
axes[2, 2].axis('off')
labels = df3.loc['Academic Institution'].drop(['Total']).index.tolist()
handles = [rect for rect in bars.get_children() if isinstance(rect, mpl.patches.Rectangle)]
legend = fig.legend(handles, labels, loc=4, fontsize=25)
legend.set_title('Metric/Options Selected',prop={'size':26})
plt.savefig('figures/metrics.png', bbox_inches="tight")
fig.tight_layout()
plt.show()
I do have a plot that only consists of horizontal lines at certain values when I have a signal, otherwise none. So, I am looking for a way to plot this without the vertical lines. there may be gaps between the lines when there is no signal and I dont want the lines to connect nor do I want a line falling off to 0. Is there a way to plot this like that in matplotlib?
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
axes = self.figure.add_subplot(111)
axes.plot(df.index, df["x1"], lw=1.0, c=self.getColour('g', i), ls=ls)
The plot you are looking for is Matplotlib's plt.hlines(y, xmin, xmax).
For example:
import matplotlib.pyplot as plt
y = range(1, 11)
xmin = range(10)
xmax = range(1, 11)
colors=['blue', 'green', 'red', 'yellow', 'orange', 'purple',
'cyan', 'magenta', 'pink', 'black']
fig, ax = plt.subplots(1, 1)
ax.hlines(y, xmin, xmax, colors=colors)
plt.show()
Yields a plot like this:
See the Matplotlib documentation for more details.