Plot vertical lines in matplotlib within a given y range [duplicate] - python

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:

Related

How to make horizontal line stop at specific x-value? [duplicate]

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);

2nd scale with ticks being a function of first ticks at same position in python/matplotlib

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:

How do I disable float numbers in matplotlib [duplicate]

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

How to assign colours to different ranges of data points in python [duplicate]

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()

in a scatter plot, make each grid cell as a square in matplotlib in python 3.2

I need to plot a 2D scatter from matplotlib in python 3.2.
But, the max and min values of data are verious greatly.
I need to adjust the grid and tickers so that each grid cell is a square and the number of grid lines connected to tickers should depend on the size of the figure.
UPDATE
I prefer n X n grid lines on X and Y axis respectively.
The value of n depends on the max value of X and Y. I want to keep n within 3 to 8. It means that there are not more than 8 grid lines and not less than 3 lines on X and Y direction.
My python ocde:
#yList is a list of float numbers
#xList is a list of float numbers
rcParams['figure.figsize'] = 6, 6
plt.scatter(xList, yList, s=3, c='g', alpha=0.5)
plt.Figure(figsize=(1,1), facecolor='w')
plt.ylim(0, max(yList))
plt.xlim(0, max(xList))
plt.grid()
plt.show()
Currently, each grid cell is rectagular. I need square for each cell.
This can be done using ax.set_x/yticks to adjust the grid, then ax.set_aspect to adjust the scale. If you do it correctly (first you correct the ratio due to difference between xmax and ymax, then you select the scale on the number of case), you will get square grid cells
import random
import matplotlib.pyplot as plt
xList = np.random.uniform(0,1,10)
yList = np.random.uniform(0,10,10)
fig = plt.figure()
ax = fig.gca()
plt.rcParams['figure.figsize'] = 6, 6
ax.scatter(xList, yList, s=3, c='g', alpha=0.5)
ax.set_ylim(0, max(yList))
ax.set_xlim(0, max(xList))
#Added code
n_x, ny = 3, 8
ax.set_xticks( np.linspace(*ax.get_xlim(), num=n_x+1) ) #Need 4 points to make 3 intervals
ax.set_yticks( np.linspace(*ax.get_ylim(), num=n_y+1) ) #Need 9 points to make 8 intervals
ax.set_aspect( ax.get_xlim()[1]/ax.get_ylim()[1] * n_y/n_x )
# ax.get_xlim()[1]/ax.get_ylim()[1] correct difference between xmax and ymax,
# n_y/n_x put the correct scale to get square grid cells
ax.grid()
fig.show()

Categories

Resources