This question already has answers here:
How do I change the size of figures drawn with Matplotlib?
(14 answers)
Closed 4 years ago.
May I ask how do i adjust the size of the graph? This is my code.
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(mean, median, marker="s", linestyle="")
for i, txt in enumerate(words):
ax.annotate(txt, (mean[i],median[i]))
ax.set_xlabel("median")
ax.set_ylabel("mean")
plt.show()
I tried to use
fig,ax=plt.subplots(figsize=(20,10))
but failed.
You first must have code that can execute, prior to tweaking the size of a figure:
(I added dummy data, and now it works)
import matplotlib.pyplot as plt
if __name__ == '__main__':
fig = plt.figure()
ax = fig.add_subplot(111)
mean, median = [1, 2, 3], [4, 5, 6] # dummy data
ax.plot(mean, median, marker="s", linestyle="")
for i, txt in enumerate(['a', 'b', 'c']):
ax.annotate(txt, (mean[i], median[i]))
ax.set_xlabel("median")
ax.set_ylabel("mean")
fig, ax = plt.subplots(figsize=(10, 10)) # size in inches
plt.show()
you can basically do this:
from pylab import rcParams
rcParams[figure.figsize] = (5,4) # Size in inches
Then you may continue with your code :)
Related
This question already has answers here:
How to plot confusion matrix with string axis rather than integer in python
(8 answers)
How can I plot a confusion matrix? [duplicate]
(3 answers)
Closed 9 months ago.
I have an array with confusion matrix values, let's say [[25, 4], [5, 17]], following an obvious [[tp, fp], [fn, tn]] order. Is there a way to plot it with matplotlib or something similar, with nice output yet minimal code? I would like to label the results as well.
You could draw a quick heatmap as follows using seaborn.heatmap():
import seaborn
import numpy as np
import matplotlib.pyplot as plt
data = [[25, 4], [5, 17]]
ax = seaborn.heatmap(data, xticklabels='PN', yticklabels='PN', annot=True, square=True, cmap='Blues')
ax.set_xlabel('Actual')
ax.set_ylabel('Predicted')
plt.show()
Result:
You can then tweak some settings to make it look prettier:
import seaborn
import numpy as np
import matplotlib.pyplot as plt
data = [[25, 4], [5, 17]]
ax = seaborn.heatmap(
data,
xticklabels='PN', yticklabels='PN',
annot=True, square=True,
cmap='Blues', cbar_kws={'format': '%.0f'}
)
ax.set_xlabel('Actual')
ax.set_ylabel('Predicted')
ax.xaxis.tick_top()
ax.xaxis.set_label_position('top')
plt.tick_params(top=False, bottom=False, left=False, right=False)
plt.yticks(rotation=0)
plt.show()
Result:
You could also adjust vmin= and vmax= so that the color changes accordingly.
Normalizing the data and using vmin=0, vmax=1 can also be an idea if you want the color to reflect percentages of total tests:
import seaborn
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
data = np.array([[25, 4], [5, 17]], dtype='float')
normalized = data / data.sum()
ax = seaborn.heatmap(
normalized, vmin=0, vmax=1,
xticklabels='PN', yticklabels='PN',
annot=data, square=True, cmap='Blues',
cbar_kws={'format': FuncFormatter(lambda x, _: "%.0f%%" % (x * 100))}
)
ax.set_xlabel('Actual')
ax.set_ylabel('Predicted')
ax.xaxis.tick_top()
ax.xaxis.set_label_position('top')
plt.tick_params(top=False, bottom=False, left=False, right=False)
plt.yticks(rotation=0)
plt.show()
Result:
How do I increase the figure size for this figure?
This does nothing:
fig.figsize(15, 15)
Use this on a figure object:
fig.set_figheight(15)
fig.set_figwidth(15)
Alternatively, when using .subplots() to create a new figure, specify figsize=:
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
In addition to the previous answers, here is an option to set the size of the figure and the size of the subplots within the figure individually by means of gridspec_kw:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#generate random data
x,y=range(100), range(10)
z=np.random.random((len(x),len(y)))
Y=[z[i].sum() for i in range(len(x))]
z=pd.DataFrame(z).unstack().reset_index()
#Plot data
fig, axs = plt.subplots(2,1,figsize=(16,9), gridspec_kw={'height_ratios': [1, 2]})
axs[0].plot(Y)
axs[1].scatter(z['level_1'], z['level_0'],c=z[0])
with this figure as result:
Alternatively, create a figure() object using the figsize argument and then use add_subplot to add your subplots. E.g.
import matplotlib.pyplot as plt
import numpy as np
f = plt.figure(figsize=(10,3))
ax = f.add_subplot(121)
ax2 = f.add_subplot(122)
x = np.linspace(0,4,1000)
ax.plot(x, np.sin(x))
ax2.plot(x, np.cos(x), 'r:')
Benefits of this method are that the syntax is closer to calls of subplot() instead of subplots(). E.g. subplots doesn't seem to support using a GridSpec for controlling the spacing of the subplots, but both subplot() and add_subplot() do.
You can use plt.figure(figsize = (16,8)) to change figure size of a single plot and with up to two subplots. (arguments inside figsize lets to modify the figure size)
To change figure size of more subplots you can use plt.subplots(2,2,figsize=(10,10)) when creating subplots.
from matplotlib import pyplot as plt
lis=[img,gaussian_img,gaussian_img_8bit]
f,axs=plt.subplots(3,1,figsize=(25,25)) #ROW,COLUMN
axs[0].imshow(lis[0])
axs[1].imshow(lis[1])
axs[2].imshow(lis[2])
For plotting subplots in a for loop which is useful sometimes:
Sample code to for a matplotlib plot of multiple subplots of histograms from a multivariate numpy array (2 dimensional).
plt.figure(figsize=(16, 8))
for i in range(1, 7):
plt.subplot(2, 3, i)
plt.title('Histogram of {}'.format(str(i)))
plt.hist(x[:,i-1], bins=60)
This question already has answers here:
Matplotlib scatter plot with legend
(6 answers)
Closed 5 years ago.
I'd like to make this kind of scatter plot where the points have colors specified by the "c" option and the legend shows the color's meanings.
The data source of mine is like following:
scatter_x = [1,2,3,4,5]
scatter_y = [5,4,3,2,1]
group = [1,3,2,1,3] # each (x,y) belongs to the group 1, 2, or 3.
I tried this:
plt.scatter(scatter_x, scatter_y, c=group, label=group)
plt.legend()
Unfortunately, I did not get the legend as expected. How to show the legend properly? I expected there are five rows and each row shows the color and group correspondences.
As in the example you mentioned, call plt.scatter for each group:
import numpy as np
from matplotlib import pyplot as plt
scatter_x = np.array([1,2,3,4,5])
scatter_y = np.array([5,4,3,2,1])
group = np.array([1,3,2,1,3])
cdict = {1: 'red', 2: 'blue', 3: 'green'}
fig, ax = plt.subplots()
for g in np.unique(group):
ix = np.where(group == g)
ax.scatter(scatter_x[ix], scatter_y[ix], c = cdict[g], label = g, s = 100)
ax.legend()
plt.show()
check this out:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
scatter_x = np.array([1,2,3,4,5])
scatter_y = np.array([5,4,3,2,1])
group = np.array([1,3,2,1,3])
for g in np.unique(group):
i = np.where(group == g)
ax.scatter(scatter_x[i], scatter_y[i], label=g)
ax.legend()
plt.show()
This question already has answers here:
How do I let my matplotlib plot go beyond the axes?
(3 answers)
Closed 5 years ago.
I'm plotting data points using matplotlib.
Basically, I want to plot discrete points. Many of them are placed on the boundaries. However, as shown in the attached figure, the data points on the figure boundary only appears as a half circle rather than a full circle.
Could anyone suggest how to plot those points on the boundary as full circles?
def PlotGrid(grid_point, file_name):
plt.figure()
dims = np.shape(grid_point)
for i in range(0, dims[1]):
for j in range(0, dims[2]):
plt.plot(grid_point[0, i, j], grid_point[1, i, j], 'ro', markersize=15)
Thank you!
Set the plt.plot kwarg clip_on to False, and the points will show up outside the axes.
plt.plot(grid_point[0, i, j], grid_point[1, i, j], 'ro', markersize=15, clip_on=False)
From the docs:
Artist.set_clip_on(b)
Set whether artist uses clipping.
When False artists will be visible out side of the axes which can lead to unexpected results.
ACCEPTS: [True | False]
Here's a minimal example:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.plot(0, 0, 'ro', markersize=30, clip_on=True, label='clip_on=True')
ax.plot(1, 1, 'bo', markersize=30, clip_on=False, label='clip_on=False')
ax.legend()
plt.show()
Artists can be shown outside the axes by not allowing the axes to clip them, e.g. plt.plot(..., clip_on=False),
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["figure.figsize"] = (5,4)
plt.figure()
X,Y = np.meshgrid(range(4),range(4))
for i in range(0, 4):
for j in range(0, 4):
plt.plot(X[i,j], Y[i,j], 'ro', markersize=30, clip_on=False)
plt.margins(0.0)
plt.show()
However, it might be better to extend the axes range, such that the artist actually lives completely inside the axes. This can be done using plt.margins().
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
X,Y = np.meshgrid(range(4),range(4))
for i in range(0, 4):
for j in range(0, 4):
plt.plot(X[i,j], Y[i,j], 'ro', markersize=30)
plt.margins(0.1) ## add 10% margin on all sides
plt.show()
This question already has answers here:
How to remove gaps between subplots in matplotlib
(6 answers)
Closed 6 years ago.
I am having quite a bit of trouble understanding how to create good subplots. I want to create a figure that is similar to the one shown below. Does anyone know how I could set up a similar template as this?
Also, how would I include these points with error bars in the subplots?
This is my code for the error bars:
mass, p, errp, errl = np.loadtxt('/Users/shawn/Desktop/vika1.dat', usecols = [0, 10, 11, 12], unpack = True)
plt.errorbar(mass, np.log10(p) - 4, yerr = [np.log10(p) - np.log10(p-errl), np.log10(p + errp) - np.log10(p)], fmt = 'o', markerfacecolor = 'w', markeredgecolor = 'k', ecolor = 'k')
You could use sharex and sharey to share the axes. The following will give the layout you want. You can then plot individual subplots using your specific plot funcitons.
Updated complete code below
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
axes[0,0].plot(X, C, color="blue", linewidth=1.0, linestyle="-")
axes[0,1].plot(X, C, color="orange", linewidth=1.0, linestyle="-")
axes[1,0].plot(X, C, color="green", linewidth=1.0, linestyle="-")
axes[1,1].plot(X, C, color="red", linewidth=1.0, linestyle="-")
plt.subplots_adjust(wspace=0,hspace=0)
plt.show()
Can't understand why someone has downvoted me for the initial answer...
The below lines would prune the min value for both x and y axes thereby avoiding label overlaps
from matplotlib.ticker import MaxNLocator
axes[1,1].yaxis.set_major_locator(MaxNLocator(prune='lower'))
axes[1,1].xaxis.set_major_locator(MaxNLocator(prune='lower'))