Set y range on Matplotlib boxplot [duplicate] - python

This question already has answers here:
Changing the tick frequency on the x or y axis
(13 answers)
Closed 1 year ago.
How to set y axis label's on Matplotlib boxplot? I checked the docs and searched the google for it, but perhaps I am not using the right keywords. I want to set the y axis interval to 5000 instead of 20000 as it is shown in this graph.

You can use MultipleLocator and set y axis:
Example:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
# Sample
t = np.arange(0.0, 100.0, 0.1)
s = np.abs(100000 * np.sin(0.1 * np.pi * t) * np.exp(-t * 0.01))
# Plot function
fig, ax = plt.subplots()
ax.plot(t, s)
# Define the yaxis
ax.yaxis.set_major_locator(MultipleLocator(5000))
plt.show()
With MultipleLocator:
Without MultipleLocator:

Related

Matplotlib title and axis label padding

I'm just starting out experimenting with Matplotlib today. I've spent the last few hours trying to fix the positioning of the title and axis labels to no avail. I figured out to fix the spacing between the title and top of the chart and the axis labels and ticks using the padding parameter. I can't figure out how to make it so that the title is not crammed to top of the figure and the x/y axis labels aren't crammed to the left/bottom of the figure.
Below is an example that has nothing to do with my actual problem other than illustrating the formatting issue.
import matplotlib.pyplot as plt
import numpy as np
#create data
A = 5
f = 0.5
t = np.arange(0,10,0.01)
y = A * np.sin(2*np.pi*f*t)
#create plot
fig, ax = plt.subplots()
fig.set_size_inches(8*(16/9),8)
ax.plot(t,y)
#format plot
ax.spines.top.set_visible(False)
ax.spines.right.set_visible(False)
ax.set_title('Need this title to move down without moving into subplot so that it is not crammed on top',pad=20)
ax.set_ylabel('Need this label to move to the right',labelpad=20)
ax.set_xlabel('Need this label to move up',labelpad=20)
Any suggestions as to how to increase the margins between the outside of the title/labels and the edge of the figure would be greatly appreciated.
You can try something like that:
import matplotlib.pyplot as plt
import numpy as np
#create data
A = 5
f = 0.5
t = np.arange(0, 10, 0.01)
y = A * np.sin(2 * np.pi * f * t)
#create plot
fig, ax = plt.subplots()
fig.set_size_inches(8 * (16 / 9), 8)
ax.plot(t, y)
#format plot
ax.spines.top.set_visible(False)
ax.spines.right.set_visible(False)
ax.set_title("Title", y=-0.1)
ax.set_xlabel("x-label")
ax.xaxis.set_label_position("top")
ax.set_ylabel("y-label")
ax.yaxis.set_label_position("right")
If you want to move x/y-ticks on top/to the right as well, then use the following commands:
ax.xaxis.tick_top()
ax.yaxis.tick_right()
and then modify:
ax.spines.top.set_visible(False)
ax.spines.right.set_visible(False)
to
ax.spines.bottom.set_visible(False)
ax.spines.left.set_visible(False)

Python (matplotlib): Arrange multiple subplots (histograms) in grid [duplicate]

This question already has answers here:
How to plot in multiple subplots
(12 answers)
Closed 1 year ago.
I want to arrange 5 histograms in a grid. Here is my code and the result:
I was able to create the graphs but the difficulty comes by arranging them in a grid. I used the grid function to achieve that but i need to link the graphs to it in the respective places.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
Openness = df['O']
Conscientiousness = df['C']
Extraversion = df['E']
Areeableness = df['A']
Neurocitism = df['N']
grid = plt.GridSpec(2, 3, wspace=0.4, hspace=0.3)
# Plot 1
import matplotlib.pyplot as plt
import numpy as np
plt.hist(df['O'], bins = 100)
plt.title("Openness to experience")
plt.xlabel("Value")
plt.ylabel("Frequency")
# Plot 2
import matplotlib.pyplot as plt
import numpy as np
plt.hist(df['C'], bins = 100)
plt.title("Conscientiousness")
plt.xlabel("Value")
plt.ylabel("Frequency")
# Plot 3
import matplotlib.pyplot as plt
import numpy as np
plt.hist(df['E'], bins = 100)
plt.title("Extraversion")
plt.xlabel("Value")
plt.ylabel("Frequency")
# Plot 4
import matplotlib.pyplot as plt
import numpy as np
plt.hist(df['A'], bins = 100)
plt.title("Areeableness")
plt.xlabel("Value")
plt.ylabel("Frequency")
# Plot 5
import matplotlib.pyplot as plt
import numpy as np
plt.hist(df['N'], bins = 100)
plt.title("Neurocitism")
plt.xlabel("Value")
plt.ylabel("Frequency")
Results merge everything into one chart
But it should look like this
Could you guys please help me out?
You can use plt.subplots:
fig, axes = plt.subplots(nrows=2, ncols=2)
this creates a 2x2 grid. You can access individual positions by indexing hte axes object:
top left:
ax = axes[0,0]
ax.hist(df['C'], bins = 100)
ax.set_title("Conscientiousness")
ax.set_xlabel("Value")
ax.set_ylabel("Frequency")
and so on.
You also continue use GridSpec. Visit https://matplotlib.org/stable/tutorials/intermediate/gridspec.html
for example -
fig2 = plt.figure(constrained_layout=True)
spec2 = gridspec.GridSpec(ncols=2, nrows=3, figure=fig2)
f2_ax1 = fig2.add_subplot(spec2[0, 0])
f2_ax2 = fig2.add_subplot(spec2[0, 1])
f2_ax3 = fig2.add_subplot(spec2[1, 0])
f2_ax4 = fig2.add_subplot(spec2[1, 1])
f2_ax5 = fig2.add_subplot(spec2[2, 1])
# Plot 1
f2_ax1.hist(df['O'])
f2_ax1.set_title("Openness to experience")
f2_ax1.set_xlabel("Value")
f2_ax1.set_ylabel("Frequency")
` plt.show()

How can I synch up the colors for each iteration in a loop that plots successive curves in Matplotlib?

I have the following code to plot the solutions to multiple values of a damped oscillator:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
x = np.linspace(0, 50, 1000)
plt.figure(figsize=(9,7.5))
for mu in range(40,100,14):
plt.plot(x, np.exp(-(mu/500) * x), linestyle='--',alpha=0.4)
plt.plot(x, -np.exp(-(mu/500) * x), linestyle='--',alpha=0.4)
plt.plot(x, np.sin(np.sqrt(1 - ((mu/100)**2)) * x)*np.exp(-(mu/500) * x))
(See below for output figure)
The problem is that Pyplot seems to be assigning the colors for the 3 curves in each iteration (i.e. each value of mu) randomly, but I want the colors to be "in synch" so to speak, that is for the first value of mu, the curves for np.exp(-(mu/500), -np.exp(-(mu/500) * x), and np.sin(np.sqrt(1 - ((mu/100)**2)) * x)*np.exp(-(mu/500) * x) to be the same (or close).
I kind of hacked it by setting the color through each iteration using the RGB color tuple, and then incrementing the values in the tuple each time, but that's tedious, and you have to tie the increments to the number of iterations your loop will go through?
Is there a more elegant and concise way of doing it that can work with any number of iterations?
As an addition to the answers in #pink spikyhairman's comment, you can define a colormap and get colors by inputing mu/mumax into it:
# define mus outside of loop
mus = np.arange(40,100,14)
cmap = plt.cm.viridis
for mu in mus:
# define color as colormap entry between 0 and 1
color = cmap(mu/np.max(mus))
plt.plot(x, np.exp(-(mu/500) * x), linestyle='--',alpha=0.4, c=color)
plt.plot(x, -np.exp(-(mu/500) * x), linestyle='--',alpha=0.4, c=color)
plt.plot(x, np.sin(np.sqrt(1 - ((mu/100)**2)) * x)*np.exp(-(mu/500) * x), c=color)
From the matplotlib.pyplot.plot documentation:
By default, each line is assigned a different style specified by a
'style cycle'. The fmt and line property parameters are only necessary
if you want explicit deviations from these defaults. Alternatively,
you can also change the style cycle using the 'axes.prop_cycle'
rcParam.
You can create a cycler object with repeating parameters for colors and pass it to to the axes object via set_prop_cycle for example:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from cycler import cycler
sns.set()
x = np.linspace(0, 50, 1000)
fig, ax = plt.subplots(1, figsize=(9,7.5))
ax.set_prop_cycle(cycler('color', 'rrrbbb'))
for mu in range(40,40+28,14):
ax.plot(x, np.exp(-(mu/500) * x), linestyle='--',alpha=0.4)
ax.plot(x, -np.exp(-(mu/500) * x), linestyle='--',alpha=0.4)
ax.plot(x, np.sin(np.sqrt(1 - ((mu/100)**2)) * x)*np.exp(-(mu/500) * x))

Line plot that continuously varies transparency - Matplotlib

I wish to produce a single line plot in Matplotlib that has variable transparency, i.e. it starts from solid color to full transparent color.
I tried this but it didn't work.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 500)
y = np.sin(x)
alphas = np.linspace(1, 0, 500)
fig, ax = plt.subplots(1, 1)
ax.plot(x, y, alpha=alphas)
Matplotlib's "LineCollection" allows you to split the line to be plotted into individual line segments and you can assign a color to each segment. The code example below shows how each horizontal "x" value can be assigned an alpha (transparency) value that indexes into a sequential colormap that runs from transparent to a given color. A suitable colormap "myred" was created using Matplotlib's "colors" module.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import matplotlib.colors as colors
redfade = colors.to_rgb("red") + (0.0,)
myred = colors.LinearSegmentedColormap.from_list('my',[redfade, "red"])
x = np.linspace(0,1, 1000)
y = np.sin(x * 4 * np.pi)
alphas = x * 4 % 1
points = np.vstack((x, y)).T.reshape(-1, 1, 2)
segments = np.hstack((points[:-1], points[1:]))
fig, ax = plt.subplots()
lc = LineCollection(segments, array=alphas, cmap=myred, lw=3)
line = ax.add_collection(lc)
ax.autoscale()
plt.show()
If you are using the standard white background then you can save a few lines by using one of Matplotlib's builtin sequential colormaps that runs from white to a given color. If you remove the lines that created the colormap above and just put the agument cmap="Reds" in the LineCollection function, it creates a visually similar result.
The only solution I found was to plot each segment independently with varying transparency
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 500)
y = np.sin(x)
alphas = np.linspace(1, 0, 499)
fig, ax = plt.subplots(1, 1)
for i in range(499):
ax.plot(x[i:i+2], y[i:i+2], 'k', alpha=alphas[i])
But I don't like it... Maybe this is enough for someone
I don't know how to do this in matplotlib, but it's possible in Altair:
import numpy as np
import pandas as pd
import altair as alt
x = np.linspace(0, 2 * np.pi, 500)
y = np.sin(x)
alt.Chart(
pd.DataFrame({"x": x, "y": y, "o": np.linspace(0, 1, len(x))}),
).mark_point(
).encode(
alt.X("x"),
alt.Y("y"),
alt.Opacity(field="x", type="quantitative", scale=alt.Scale(range=[1, 0]), legend=None),
)
Result:

Align and share X axis in Matplotlib contour 2D and 1D plot with colourbar legend [duplicate]

This question already has answers here:
How to have one colorbar for all subplots
(13 answers)
Closed 4 years ago.
I am trying to include a 1D path through a 2D contour plot as a separate plot below the contour plot. Ideally these will have a shared and aligned X axis to guide the reader through the features of the plot, and will include a colour bar legend.
I have made this minimal example to show my attempt and the problem.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
# Generating dummy data
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z = np.outer(np.cos(y), np.cos(3*x))
# Configure the plot
gs = gridspec.GridSpec(2,1,height_ratios=[4,1])
fig = plt.figure()
cax = fig.add_subplot(gs[0])
# Contour plot
CS = cax.contourf(X, Y, Z)
# Add line illustrating 1D path
cax.plot([-3,3],[0,0],ls="--",c='k')
cbar = fig.colorbar(CS)
# Simple linear plot
lax = fig.add_subplot(gs[1],sharex=cax)
lax.plot(x, np.cos(3*x))
lax.set_xlim([-3,3])
plt.show()
This gives the following image as a result:
Clearly the colour bar being included in the subplot area is throwing off the align.
I the process of writing this question I found a work around by including the colour bar as it's own axis, such that the grid spec is now a 2x2 subplot grid.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z = np.outer(np.cos(y), np.cos(3*x))
# Gridspec is now 2x2 with sharp width ratios
gs = gridspec.GridSpec(2,2,height_ratios=[4,1],width_ratios=[20,1])
fig = plt.figure()
cax = fig.add_subplot(gs[0])
CS = cax.contourf(X, Y, Z)
cax.plot([-3,3],[0,0],ls="--",c='k')
lax = fig.add_subplot(gs[2],sharex=cax)
lax.plot(x, np.cos(3*x))
lax.set_xlim([-3,3])
# Make a subplot for the colour bar
bax = fig.add_subplot(gs[1])
# Use general colour bar with specific axis given.
cbar = plt.colorbar(CS,bax)
plt.show()
This gives the desired result.
I would still be interested if there are any more elegant solutions though.

Categories

Resources