Matplotlib title and labels are mixed up [duplicate] - python

This question already has answers here:
Need to add space between SubPlots for X axis label, maybe remove labelling of axis notches
(2 answers)
Improve subplot size/spacing with many subplots
(8 answers)
How to remove gaps between subplots in matplotlib
(6 answers)
Closed 1 year ago.
I have the following code:
fig1 = plt.figure(figsize=(10, 10))
# Objeto
ax1 = fig1.add_subplot(3, 1, 1)
ax1.plot(xL, fL, 'k')
ax1.set_xlim(-0.04, 0.04)
ax1.set_ylim(0, 2.1)
ax1.set_title('Objeto')
ax1.set_xlabel('d (cm)')
ax1.set_ylabel('Intensidade')
ax1.grid(axis='both')
# Echo
ax2 = fig1.add_subplot(3, 1, 2)
tempo = np.arange(0, N0) * dT
CurvaT2 = exp(-tempo / T2)
ax2.plot(tempo, Ms[0, :], 'b', tempo, Ms[1, :], 'k-')
ax2.set_title('Echo') # 'FontSize',12
ax2.set_xlabel('Tempo (ms)')
ax2.set_ylabel('Intensidade')
ax2.grid(axis='both')
# Módulo Magnetização
ax3 = fig1.add_subplot(3, 1, 3)
ax3.plot(tempo, Mod, 'k', tempo, CurvaT2, 'g--')
ax3.set_title('Módulo Magnetização') # 'FontSize',12
ax3.set_xlabel('Tempo (ms)')
ax3.set_ylabel('Intensidade')
ax3.grid(axis='both')
Which produces the following image:
As you can see, the title and the xlabels are mixed up. What could I do to fix that?

An easy and practical way to resolve this is using the method plt.tight_layout() at the end of the code. This method automatically separates in a good way the figures.
Example:
and you can increase the separation between them with the pad parameter: plt.tight_layout(pad = 2) (the default is 1.08).
More details about this lovely function:
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.tight_layout.html

Related

How to place values inside stacked horizontal bar chart using python matplotlib? [duplicate]

This question already has answers here:
Stacked bars are unexpectedly annotated with the sum of bar heights
(2 answers)
How to add value labels on a bar chart
(7 answers)
Closed 10 months ago.
I want to create a stacked horizontal bar plot with values of each stack displayed inside it and the total value of the stacks just after the bar. Using python matplotlib, I could create a simple barh. My dataframe looks like below:
import pandas as pd
df = pd.DataFrame({"single":[168,345,345,352],
"comp":[481,44,23,58],})
item = ["white_rice",
"pork_and_salted_vegetables",
"sausage_and_potato_in_tomato_sauce",
"curry_vegetable",]
df.index = item
Expect to get bar plot like below except that it is not horizontal:
The code I tried is here...and i get AttributeError: 'DataFrame' object has no attribute 'rows'. Please help me with horizontal bar plot. Thanks.
fig, ax = plt.subplots(figsize=(10,4))
colors = ['c', 'y']
ypos = np.zeros(len(df))
for i, row in enumerate(df.index):
ax.barh(df.index, df[row], x=ypos, label=row, color=colors[i])
bottom += np.array(df[row])
totals = df.sum(axis=0)
x_offset = 4
for i, total in enumerate(totals):
ax.text(totals.index[i], total + x_offset, round(total), ha='center',) # weight='bold')
x_offset = -15
for bar in ax.patches:
ax.text(
# Put the text in the middle of each bar. get_x returns the start so we add half the width to get to the middle.
bar.get_y() + bar.get_height() / 2,
bar.get_width() + bar.get_x() + x_offset,
# This is actual value we'll show.
round(bar.get_width()),
# Center the labels and style them a bit.
ha='center',
color='w',
weight='bold',
size=10)
labels = df.index
ax.set_title('Label Distribution Overview')
ax.set_yticklabels(labels, rotation=90)
ax.legend(fancybox=True)
Consider the following approach to get something similar with matplotlib only (I use matplotlib 3.5.0). Basically the job is done with bar/barh and bar_label combination. You may change label_type and add padding to tweak plot appearance. Also you may use fmt to format values. Edited code with total values added.
import matplotlib.pyplot as plt
import pandas as pd
import random
def main(data):
data['total'] = data['male'] + data['female']
fig, (ax1, ax2) = plt.subplots(1, 2)
fig.suptitle('Plot title')
ax1.bar(x=data['year'].astype(str), height=data['female'], label='female')
ax1.bar_label(ax1.containers[0], label_type='center')
ax1.bar(x=data['year'].astype(str), height=data['male'], bottom=data['female'], label='male')
ax1.bar_label(ax1.containers[1], label_type='center')
ax1.bar_label(ax1.containers[1], labels=data['total'], label_type='edge')
ax1.legend()
ax2.barh(y=data['year'].astype(str), width=data['female'], label='female')
ax2.bar_label(ax2.containers[0], label_type='center')
ax2.barh(y=data['year'].astype(str), width=data['male'], left=data['female'], label='male')
ax2.bar_label(ax2.containers[1], label_type='center')
ax2.bar_label(ax2.containers[1], labels=data['total'], label_type='edge')
ax2.legend()
plt.show()
if __name__ == '__main__':
N = 4
main(pd.DataFrame({
'year': [2010 + val for val in range(N)],
'female': [int(10 + 100 * random.random()) for dummy in range(N)],
'male': [int(10 + 100 * random.random()) for dummy in range(N)]}))
Result (with total values added):

Matplotlib: problem with Adding an axes using the same arguments as a previous axes [duplicate]

This question already has answers here:
How does plt.gca work internally
(2 answers)
Object-oriented pyplot
(3 answers)
Closed 1 year ago.
I want to plot a dataset that basically shows the equilibrium point from a demand and supply curve. The graph for the demand and supply curve plots well but the equilibrium point graph doesn't seem to plot as the axes are different.
Code for the demand and supply curve.
def S(q):
return (q**2)
def D(q):
return (q - 20)**2
q = np.linspace(0, 16, 1000)
plt.plot(q, S(q), label = "Supply Curve")
plt.plot(q, D(q), label = "Demand Curve")
plt.title("Supply and Demand")
plt.legend(frameon = False)
plt.xlabel("Quantity $q$")
plt.ylabel("Price")
code for the Equilibrium price
q = sy.Symbol('q')
eq = sy.Eq(S(q), D(q))
sy.solve(eq)
plt.figure(figsize= (10, 8))#create figure and reset q to be numbers
q2 = np.linspace(0, 16, 1000)
plt.plot(q2, S(q2), label = "S Curve")#plot supply, demand, and equilibrium points
plt.plot(q2, D(q2), label = "D Curve")
plt.plot(10, 100, 'o', markersize = 14)
plt.title("Equilibrium point")#add titles and legend
plt.legend(frameon = False)
plt.xlabel("Quantity")
plt.ylabel("Price")
ax = plt.axes()#add arrow with annotation
ax.annotate('Equilibrium at (10, 100)', xy=(10,100), xytext=(10, 250), arrowprops=dict(facecolor='black'))
Expected Output
Given Output

How to change date format on x-axis [duplicate]

This question already has answers here:
Editing the date formatting of x-axis tick labels
(4 answers)
Closed 1 year ago.
currently i have this code:
def graph_s(self):
ex_list = list()
time = list()
if(len(self.sheet) > 1):
for index, row in self.sheet.iterrows():
ts = date(int(row['Year']), int(row['Month']), 1)
time.append(ts)
ex_list.append(float(row['grocery']) + float(row['transportation']) + float(row['leisure']) + float(row['utilities']) + float(row['savings']) + float(row['bills']))
z = sorted(zip(time,ex_list))
x=[date(2021,i,1) for i in z]
y=[i[1] for i in z]
plt.plot(x, y)
plt.show()
main()
else:
print('Sorry! There is not enough information to create a graph of you spending over time.')
main()
but the graph isnt what i wanted. i want to change the x-axis to a nicer version e.g. 2021-10, i want to omit the day
enter image description here
You have to define a DateFormatter for your x-axis. In your case you want only years and months. This is the notation: '%Y-%m' and below you can see how to apply the formatter.
myFmt = mdates.DateFormatter('%Y-%m')
ax1.xaxis.set_major_formatter(myFmt)
Example
This is adapted from here:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cbook as cbook
# Fixing random state for reproducibility
np.random.seed(19680801)
# load up some sample financial data
r = (cbook.get_sample_data('goog.npz', np_load=True)['price_data']
.view(np.recarray))
# create two subplots with the shared x and y axes
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot(r.date, r.close, lw=2)
myFmt = mdates.DateFormatter('%Y-%m')
plt.xticks(rotation=45)
ax1.xaxis.set_major_formatter(myFmt)

matplotlib pie chart replacing last pie subplot title with actual title of the main plot [duplicate]

This question already has answers here:
How do I set the figure title and axes labels font size?
(11 answers)
How to add a title to each subplot
(10 answers)
How to set a single, main title above all the subplots with Pyplot?
(3 answers)
Closed 1 year ago.
I have been running into an issue where matplotlib pie is replacing my last value of subplot text with actual plot title. Could anyone tell me why i am facing the issue and how to overcome it?
keep_list_tt = [6.012, 2.734, 2.76, 4.585, 4.19]
eppm_plot = [0, 771, 830, 919, 1097]
all_test_tt = [31.344, 31.344, 31.344, 31.344, 31.344]
always_failing_list_tt = [0.112, 0.112, 0.112, 0.112, 0.112]
always_failing_list_tt = [23.203, 23.203, 23.203, 23.203, 23.203]
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1,len(keep_list_tt), figsize=(30,8))
labels = ["always_failing_list_tt", "always_passing_list_tt", "keep_list_tt","remove_list_tt"]
explode = (0.2, 0,0.1,0.1)
for i in range(len(keep_list_tt)):
eppm_pie_plot = [always_failing_list_tt[i],always_passing_list_tt[i],keep_list_tt[i],round(np.subtract(all_test_tt[i],np.add(keep_list_tt[i],np.add(always_failing_list_tt[i],always_passing_list_tt[i]))),3)]
pie = axs[i].pie(eppm_pie_plot, explode=explode,autopct="")
axs[i].set_title("EPPM is - {}".format(eppm_plot[i]))
for j, a in enumerate(pie[2]):
a.set_text("{}".format(eppm_pie_plot[j]))
plt.legend(labels,bbox_to_anchor=(1.1,0.5) )
plt.axis('equal')
plt.title ("Temp")
plt.show()
The issue seems to be caused by the fact that plt.axis('equal') is applied only to the last graph outside the loop process. Please move that code inside the loop. And while you're at it, optimize the way the graph is looped.
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1,len(keep_list_tt), figsize=(30,8))
labels = ["always_failing_list_tt", "always_passing_list_tt", "keep_list_tt","remove_list_tt"]
explode = (0.2, 0,0.1,0.1)
for i, ax in enumerate(fig.axes):
eppm_pie_plot = [always_failing_list_tt[i],always_passing_list_tt[i],keep_list_tt[i],round(np.subtract(all_test_tt[i],np.add(keep_list_tt[i],np.add(always_failing_list_tt[i],always_passing_list_tt[i]))),3)]
pie = ax.pie(eppm_pie_plot, explode=explode, autopct="")
ax.set_title("EPPM is - {}".format(eppm_plot[i]))
ax.axis('equal')
for j, a in enumerate(pie[2]):
a.set_text("{}".format(eppm_pie_plot[j]))
plt.legend(labels, bbox_to_anchor=(1.1,0.5))
#plt.axis('equal')
fig.suptitle("Temp")
plt.show()

How to make the x axis of figure wider using pyplot in python since figsize is not working [duplicate]

This question already has answers here:
How do I change the size of figures drawn with Matplotlib?
(14 answers)
Closed 1 year ago.
I want to make the x axis of a figure wider in matplotlib and I use the following code.
But it seems that figsize does not have any effect. How I can change the size of the figure?
data_dates = np.loadtxt(file,usecols = 0, dtype=np.str)
data1 = np.loadtxt(file,usecols = 1)
data2 = np.loadtxt(file,usecols = 2)
data3 = np.loadtxt(file,usecols = 3)
plt.plot(figsize=(30,5))
plt.plot(data_dates,data1, label = "T")
plt.plot(data_dates,data2, label = "WS")
plt.plot(data_dates,data3, label = "WD")
plt.xlabel('Date', fontsize=8)
plt.xticks(rotation=90,fontsize=4)
plt.ylabel(' Percentage Difference (%)')
plt.legend()
plt.savefig(outfile,format='png',dpi=200,bbox_inches='tight')
a sample of the file is
01/06/2019 0.1897540512577196 0.28956205456965856 0.10983099750547703
02/06/2019 0.1914523564094276 0.1815325705314345 0.0004533827128655877
03/06/2019 0.2365346386184113 0.12301344973593868 0.058843355966174876
04/06/2019 0.2085897993039386 0.005466902564359565 0.014087537281676313
05/06/2019 0.15563355684612554 0.16249844426472368 0.11036007669758358
06/06/2019 0.11981475728282368 0.11015459703126898 0.03501167308950372
fig, ax = plt.subplots(1, 1)
fig.set_size_inches(30, 5)
plt.plot(data_dates,data1, label = "T")
plt.plot(data_dates,data2, label = "WS")
plt.plot(data_dates,data3, label = "WD")
plt.xlabel('Date', fontsize=8)
plt.xticks(rotation=90,fontsize=4)
plt.ylabel(' Percentage Difference (%)')
plt.legend()
plt.savefig("test.png",format='png',dpi=200,bbox_inches='tight')
Instead of creating the figure explicitly using subplots you could also use the get-current-figure method: fig = plt.gcf().

Categories