This question already has answers here:
Plot a horizontal line on a given plot
(7 answers)
Closed 1 year ago.
I would like to draw a horizontal line with matplotlib's plt.axhline() function, but I want the horizontal line to stop at the absolute value of 5 on the x-axis. How do I set xmax in plt.axhline() to stop at 5?
plt.figure()
plt.plot(np.arange(-60, 60, 20), np.arange(0, 1.2, 0.2))
plt.axhline(y = 0.5, xmax = 5, c= 'r')
You need to use plt.hlines instead, also specify a xmin and change c to color .
import matplotlib.pyplot as plt
import numpy as np
xmin = -65
plt.figure()
plt.plot(np.arange(-60, 60, 20), np.arange(0, 1.2, 0.2))
plt.hlines(y = 0.5, xmin=xmin , xmax = 5, color= 'r')
plt.xlim(left=xmin);
Related
I am using matplotlib in Python and want to use the same plot but with several different axes that are all functions of the first one, but that do not linearly depend on the first y value.
As an example, let's assume a plot that shows a simple line y=x.
Now I have a random function like f(y)=5y^2 + 2.
My ideal output graph should now still be a line, but the equidistant ticks should not be y=1, 2, 3, 4, but f(y)=7, 22, 47, 82, so that I can overlay the two graphs with 2 different axes.
Is this even possible, as the distance between the ticks is not even nor can it be expressed in a log plot? Therefore I simply want to put a function on each tick value, without changing the graph nor the ticks' positions.
In a graphics program this would be straightforward, by simply using the same plot and manually rewriting each tick.
https://drive.google.com/file/d/1fp2vrFvlz-9xdJPmqdQjyMQK7gzPX24G/view?usp=sharing
Thank you in advance! The example code is not really helpful, as it is just the standard matplotlib code but the most important scaling part is missing.
I know that I can set the ticks manually with yticks, but this does not solve the scaling problem and all ticks would appear very close together.
plt.plot(["time_max_axis"], ["position_max_axis"])
plt.xlabel("Time (ms)")
plt.ylabel("Max position (mm)")
plt.ylim(0, z0_mm)
plt.show()
plt.plot(["time_max_axis"], ["frequency_axis"])
plt.xlabel("Oscillation frequency (kHz)")
plt.ylabel("Max position (mm)")
plt.ylim(fion_kHz, fion_kHz * (1 + (f_shift4 + f_shift6) / 100))
plt.show()
import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
x = np.arange(50)
y = x/10 + np.random.rand(50)
fig, axs = plt.subplots(1,2, gridspec_kw={'width_ratios': [1, 20]})
plt.subplots_adjust(wspace=0, hspace=0)
axs[1].plot(x, y)
axs[1].plot(x, 2*y)
axs[1].plot(x, 3*y)
axs[1].grid()
axs[1].set_ylim(0)
axs[1].set_xlim(0)
axs[1].set_ylabel('max displacement $z_{max}$ (mm)')
ymin, ymax = axs[1].get_ylim()
majorlocator = ymax // 8 # 8 horizontal grid lines
ytickloc = np.arange(0, int(ymax), majorlocator)
axs[1].yaxis.set_major_locator(MultipleLocator(majorlocator))
ax1 = axs[1].twinx() # ghost axis of axs[1]
ax1.yaxis.set_ticks_position('left')
ax1.set_yticks([ymin, ymax])
ax1.set_yticklabels(['', f'$z_0$ = {round(ymax,2)}'])
axs[0].spines['top'].set_visible(False)
axs[0].spines['right'].set_visible(False)
axs[0].spines['bottom'].set_visible(False)
axs[0].spines['left'].set_visible(False)
axs[0].set_xticks([])
axs[0].set_yticks(ytickloc)
ytick2 = 5 * ytickloc**2 + 2 # f = 5y^2 + 2
ytick2 = list(ytick2)
ymin2 = ytick2[0]
ytick2[0] = ''
axs[0].set_yticklabels(ytick2)
axs[0].set_ylim(ymin, ymax)
axs[0].set_ylim(0)
axs[0].set_ylabel('Oscillation frequency $f_{osc}$ (kHz)')
ymax2 = 5 * ymax**2 + 2 # f = 5y^2 + 2
ax0 = axs[0].twinx() # ghost axis of axs[0]
ax0.yaxis.set_ticks_position('left')
ax0.spines['top'].set_visible(False)
ax0.spines['right'].set_visible(False)
ax0.spines['bottom'].set_visible(False)
ax0.spines['left'].set_visible(False)
ax0.set_yticks([ymin, ymax])
ax0.set_yticklabels([f'$\\bf{{f_{{ion}}}} = {round(ymin2, 2)}$', f'$f_{{max}}$ = {round(ymax2,2)}'])
plt.tight_layout()
Output:
This question already has answers here:
How to draw vertical lines on a given plot
(6 answers)
Closed 1 year ago.
I'm using the following:
fig, ax = plt.subplots(figsize=(20, 10))
ax.set_ylim(bottom=0, top=10)
for i in range(4):
ax.axvline(x=i, ymin=5, ymax=9, color="red", linewidth=40)
Which gives:
I would expect there to be a vertical line at each point from y = 5 to y = 9.
You should use matplotlib.pyplot.vlines, as suggested by BigBen in the comment:
for i in range(4):
ax.vlines(x=i, ymin=5, ymax=9, color="red", linewidth=40)
If you look at the parameters for axvline, you see that ymin and ymax goes from 0 to 1. A fraction of your complete ylimit.
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.axvline.html
So you need something like .5 to .9 or calculate the appropriate fractions.
fig, ax = plt.subplots(figsize=(20, 10))
ax.set_ylim(bottom=0, top=10)
for i in range(4):
ax.axvline(x=i, ymin=.5, ymax=.9, color="red", linewidth=40)
Output:
This question already has answers here:
How to force the Y axis to only use integers
(3 answers)
Closed 8 months ago.
I am making a bot which tracks discord server stats and makes a graph of them.
While making the bot, I faced a problem. The bot shows floating point numbers in the graph which are not supposed to be there.
Is it possible to disable the float numbers and show only 12, 13, 14 instead of 12, 12.25, 12.50, etc?
Answer
I suppose your data are in a y list. In this case you can use ax.set_yticks() as here:
yticks = range(min(y), max(y) + 1)
ax.set_yticks(yticks)
Code
import matplotlib.pyplot as plt
plt.style.use('dark_background')
x = ['14.09', '15.09', '16.09', '17.09', '18.09']
y = [12, 13, 13, 14, 14]
fig, ax = plt.subplots()
ax.plot(x, y, color = 'green', linestyle = '-', marker = 'o', markerfacecolor = 'red')
ax.set_facecolor('white')
ax.set_ylabel('Member count')
ax.set_title("Member count for 'СПГ'")
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
yticks = range(min(y), max(y) + 1)
ax.set_yticks(yticks)
plt.show()
Output
This question already has answers here:
No. of Observation inside BoxPlot, Matplotlib
(2 answers)
Closed 3 years ago.
I am using matplotlib to plot a boxplot as follows:
import numpy as np
import matplotlib.pyplot as plt
x1 = np.random.randint(0, 101, size=10).tolist()
x2 = np.random.randint(0, 101, size=20).tolist()
labels = ('Data10', 'Data20')
plt.boxplot((x1, x2))
plt.xticks(range(1, len(labels) + 1), labels, rotation='vertical')
Now, what I want to do is also be able to print the number of observations on top of each of these boxplots. Is there any easy way to do that using matplotlib?
No other way in matplotlib than to use annotations.
import numpy as np
import matplotlib.pyplot as plt
x1 = np.random.randint(0, 101, size=10).tolist()
x2 = np.random.randint(0, 101, size=20).tolist()
labels = ('Data10', 'Data20')
plt.boxplot((x1, x2))
plt.xticks(range(1, len(labels) + 1), labels, rotation='vertical')
ax = plt.gca() # get current axis object
ax.annotate('local max', xy=(.5, .5), xycoords='axes fraction',
xytext=(0.2, 0.95), textcoords='axes fraction')
This question already has answers here:
How to specify different color for a specific year value range in a single figure? (Python)
(2 answers)
Closed 4 years ago.
Say I have three sets of data x, y and z.
I want to plot a scatter of x and y, but I want to assign colours to different points depending on what their corresponding z values are.
So for example for every point where z is in the range 0 to 1 I want the data points to be red, and when z in the range 1 to 3 I want the points to be blue etc.
How do I do this?
Try this. adopted from ImportanceOfBeingErnest answer here
import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
x = np.linspace(0, 10, 100)
y = np.random.randint(0, 50, size=100)
z = np.random.rand(100)*10
bounds = [0,1,3,10]
colors = ["r", "b", "g"]
plt.figure(figsize=(8,6))
cmap = matplotlib.colors.ListedColormap(colors)
norm = matplotlib.colors.BoundaryNorm(bounds, len(colors))
rect = plt.scatter(x, y, s = 100, c=z, cmap=cmap, norm=norm)
cbar = plt.colorbar(rect, spacing="proportional")
cbar.set_label('Color', rotation=270, labelpad=10)
for i, txt in enumerate(z):
plt.annotate(np.around(txt, 1), (x[i], y[i]))
plt.show()