matplotlib annotations shift to the right [duplicate] - matplotlib

This question already has answers here:
How to fix overlapping annotations / text
(5 answers)
scatter plot with aligned annotations at each data point
(1 answer)
Closed 9 months ago.
I'm plotting both a line and some scatter points on the line. I want to label the x-coordinate of the scatter points on the line, and the annotations are being obstructed by the line. Without manually inputting the position of the annotations, is there a way to shift all of the annotation texts to the right by a certain amount?
Below is part of the code to produce the scatter plot and annotation.
import numpy as np
import matplotlib.pyplot as plt
fs = 20
figure, ax1 = plt.subplots()
ax1.set_xlim(1.6, 2.0)
ax1.set_ylim(-2, 5)
annotations = ['$1.66$', '$1.68$', '$1.72$', '$1.74$', '$1.76$']
xpoint = [1.66, 1.68, 1.72, 1.74, 1.76]
ypoint = [3.47072347e-01, 5.05186795e+00, 1.61807901e+01, 5.60855544e+01, 6.07027325e+02]
ax1.scatter(xpoint, np.log10(ypoint), color='k')
for i, label in enumerate(annotations):
ax1.annotate(label, (xpoint[i], np.log10(ypoint[i])), ha='left', va='center', fontsize=fs)
ax1.tick_params(labelsize=fs)
figure.savefig("plot.svg", bbox_inches='tight')

Related

Adjust position of colorbar in Matplotlib subplots [duplicate]

This question already has answers here:
Python matplotlib - how to move colorbar without resizing the heatmap?
(1 answer)
Matplotlib: let color bar not affect size and proportions of the plot
(2 answers)
How do I maintain image size when using a colorbar?
(2 answers)
Adjusting subplots to make space for colorbar
(1 answer)
Closed last month.
The Plot I Want to Fix
I am trying to graph three graphs stacked on top of each other and for the most part it works fine.
However when I add a colorbar to the last spectogram plot it completely squishes the plot, making the overall figure ugly.... How do I fix this?
fig, ax = plt.subplots(3, sharex=True, figsize=(50, 10))
fig.suptitle('Test' + str("%03d" % (i,)) + '+ Noisereduce', fontsize=48)
ax[0].plot(time, raw, color='blue')
ax[0].plot(time, fltr, color='orange')
ax[0].set_title('Raw Signal')
ax[1].plot(time, fltr, color='orange')
ax[1].set_title('noisereduce (stationary filter)')
spect = ax[2].pcolormesh(t, f, 10*np.log10(Sxx), vmin=vmin, vmax=vmax, shading='gouraud')
ax[2].set(xlabel='Time [sec]', ylabel='Frequency [Hz]')
fig.colorbar(spect, ax=ax[2])
ax[2].set_title('noisereduce - spectogram (upper 67% of intensities)')
plt.show()

How, for one plot only, to change the width with Seaborn/Matplotlib [duplicate]

This question already has answers here:
Matplotlib: get and set axes position
(1 answer)
Matplotlib different size subplots
(6 answers)
How to fully customize subplot size in matplotlib
(2 answers)
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
This code creates following PNG file though, This wasn't what I want.
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,figsize=(20, 6),gridspec_kw={'height_ratios': [2,1]})
fmri = sns.load_dataset("fmri")
flights = sns.load_dataset("flights")
sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event", ax=ax[0])
ax[0].legend(bbox_to_anchor=(1.02, 1), loc=2, borderaxespad=0.)
sns.lineplot(data=flights, x="year", y="passengers", ax=ax[1])
fig.savefig("test.png")
How can I make the width of second plot longer like this?
It looks easy, but I'm stuck on it..
Edit
The method I came up with was to use GridSpec like a following code, but it is complicated and not intuitive. There is another method that uses ax[0].get_position(), like Redox san taught me, but it is not good enough. I just want to increase the width of second plot a bit, however, Increasing the width of second plot doesn't work. I am still looking for another way.
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(20, 10))
gs = GridSpec(2, 2, width_ratios=[100,1], height_ratios=[2,1])
ax = []
ax.append(plt.subplot(gs.new_subplotspec((0, 0))))
plt.subplot(gs[0,1]).axis('off')
ax.append(plt.subplot(gs.new_subplotspec((1, 0), colspan=2)))
fmri = sns.load_dataset("fmri")
flights = sns.load_dataset("flights")
sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event", ax=ax[0])
ax[0].legend(bbox_to_anchor=(1.02, 1), loc=2, borderaxespad=0.)
sns.lineplot(data=flights, x="year", y="passengers", ax=ax[1])
fig.savefig("test.png")
you can do this by adjusting the widths of the subplots. After plotting (just before save), add these lines. This will get the width information and you can adjust the ratio to what you want it to be
gPos = ax[0].get_position()
gPos.x1 = 0.83 # I have used 83% to set the first plot to be of 83% of original width
ax[0].set_position(gPos)
The plot

How to remove all padding in matplotlib subplots when using images [duplicate]

This question already has answers here:
How to combine gridspec with plt.subplots() to eliminate space between rows of subplots
(1 answer)
How to remove the space between subplots in matplotlib.pyplot?
(5 answers)
Closed 3 years ago.
When creating subplots with matplotlib i cannot get tight layout where there would not be any spaces between subplot items.
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(3, 3, figsize=(10,10),gridspec_kw = {'wspace':0, 'hspace':0})
for i, ax in enumerate(axes.ravel()):
im = ax.imshow(np.random.normal(size=200).reshape([10,20]))
ax.axis('off')
plt.tight_layout()
Subplots would consist of images. Seems like there is way to do this when you are not using images. So i assume, there is some configuration about imshow().
I would like to keep aspect ratio of images, but make subplots compact as possible.
this is what i get now, but as you can see, there is a lot of row padding
https://imgur.com/a/u4IntRV

how to attach a color gradient to every bar using matplotlib [duplicate]

This question already has an answer here:
how to plot gradient fill on the 3d bars in matplotlib
(1 answer)
Closed 5 years ago.
The standard way in which I create bar plots in matplotlib is using ax.bar3d. This has the disadvantage of returning block of solid color. Does anyone know how to attach a gradient color to every bar? I am think in reproducing Fig. 1 from https://arxiv.org/pdf/1706.09289.pdf.
Try this:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(18,12))
ax = fig.add_subplot(111, projection='3d')
x_data, y_data = np.meshgrid(np.arange(5),np.arange(3))
z_data = np.random.rand(3,5)
colors = ['r','g','b'] # colors for every line of y
# plot colored 3d bars
for i in xrange(3): # cycle though y
# I multiply one color by len of x (it is 5) to set one color for y line
ax.bar3d(x_data[i], y_data[i], z_data[i], 1, 1, z_data[i], alpha=0.1, color=colors[i]*5)
# or use random colors
# ax.bar3d(x_data[i], y_data[i], z_data[i], 1, 1, z_data[i], alpha=0.1, color=[np.random.rand(3,1),]*5)
plt.show()
Result:

Change colour of curve according to its y-value in matplotlib [duplicate]

This question already has answers here:
Having line color vary with data index for line graph in matplotlib?
(4 answers)
Set line colors according to colormap
(1 answer)
Closed 8 years ago.
I'm trying to replicate the style of the attached figure using matplotlib's facilities.
Basically, I want to change the colour of the curve according to its y-value using matplotlib.
The plot you've shown doesn't have the color set by the vertical axis of the plot (which is what I would consider the y-value). Instead, it just has 8 different plots overlain, each with a different color, without stating what the color means.
Here's an example of something that looks like your plot:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
# some fake data:
x = np.linspace(0, 2*np.pi, 1000)
fs = np.arange(1, 5.)
ys = np.sin(x*fs[:, None])
for y, f in zip(ys, fs):
plt.plot(x, y, lw=3, c=cm.hot(f/5))
If you actually want the color of one line to change with respect to its value, you have to kind of hack it, because any given Line2D object can only have one color, as far as I know. One way to do this is to make a scatter plot, where each dot can have any color.
x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(2*x)
plt.scatter(x,y, c=cm.hot(np.abs(y)), edgecolor='none')
Notes:
The color vector should range between 0 and 1, so if y.max() > 1, then normalize by it: c=cm.hot(y/y.max()) and make sure it's all positive.
I used edgecolor='none' because by default the scatter markers have a black outline which makes the it look less like a uniform line.
If your data is spaced too far, you'll have to interpolate the data if you don't want gaps between markers.