Issue
I want to plot a histogram in a Matplotlib subplot. I have the code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
def plot_Diff(data):
fig = plt.figure(figsize=(10, 10))
ax =fig.add_subplot(423)
x= dfe['O18ad']
bins=[-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
old_yticks = ax.get_yticks()
bin_counts, _, bars = plt.hist(x, bins, alpha=0.65, label='old', edgecolor='black', color='lightgrey')
new_ticks = old_yticks[old_yticks < bin_counts.max()]
new_ticks = np.append(new_ticks, bin_counts.max())
ax.set_yticks(new_ticks)
plt.show()
my data:
0 -4.268475
1 -4.265793
2 -4.263120
3 -4.260457
4 -4.257803
...
359995 -7.813345
359996 -7.821394
359997 -7.773479
359998 -7.807605
359999 -7.797769
How can I get the maximum value to be displayed automatically on the Y axis?
When I use the answer from it looks like this! I have also adapted the code accordingly
Solution
In the example below I start by removing the existing ticks that are close to or more than the new max value. Then I add in the desired max tick value. If we don't remove some of the existing ticks, they're close enough to overlap with the new one and make the labelling unclear.
With some optional extra labelling and aesthetics:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
#Test data
np.random.seed(0)
dfe = pd.DataFrame({'O18ad': np.random.randn(600_000) * 4 - 10})
#Plot
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot()
x = dfe['O18ad']
# bins=[-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
# A more compact way of defining the bins
bins = np.arange(-20, 2)
bin_counts, _, bars = plt.hist(x, bins, alpha=0.65, label='old', edgecolor='black', color='lightgrey')
new_max_tick = bin_counts.max()
old_ticks = ax.get_yticks()
#Drop everything > new_max_tick
#Also, drop the second-to-last tick to ensure clearance
new_ticks = old_yticks[old_yticks < new_max_tick][:-1]
#Insert new tick
new_ticks = np.append(new_ticks, new_max_tick)
ax.set_yticks(new_ticks)
Adding bar labels and removing some spines:
#You could also label the bars
# I've customised it but you could just use ax.bar_label(bars)
ax.bar_label(
bars,
fontsize=8, color='tab:red', rotation=90,
label_type='edge', padding=5, fmt=lambda v: int(round(v, -2))
)
#Remove the top and right spines for aesthetics
[ax.spines[spine].set_visible(False) for spine in ('top', 'right')]
plt.show()
Adapting the OP's plot_Diff()
function:
#Test data
np.random.seed(0)
dfe = pd.DataFrame({'O18ad': np.random.randn(600_000) * 4 - 10})
def plot_Diff(data, extra_formatting=True):
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(423)
x = dfe['O18ad']
bins=[-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1]
bin_counts, _, bars = plt.hist(x, bins, alpha=0.65, label='old', edgecolor='black', color='lightgrey')
new_max_tick = bin_counts.max()
old_ticks = ax.get_yticks()
#Drop everything > new_max_tick
#Also, drop the second-to-last tick to ensure clearance
new_ticks = old_yticks[old_yticks < new_max_tick][:-1]
#Insert new tick
new_ticks = np.append(new_ticks, new_max_tick)
ax.set_yticks(new_ticks)
if extra_formatting:
#Label axes
ax.set_ylabel('counts')
ax.set_xlabel('bin edge')
ax.set_title(f'Histogram of {x.name}\n\n')
#You could also label the bars
# I've customised it but you could just use ax.bar_label(bars)
ax.bar_label(
bars,
fontsize=8, color='tab:red', rotation=90,
label_type='edge', padding=5, fmt=lambda v: int(round(v, -2))
)
#Remove the top and right spines for aesthetics
[ax.spines[spine].set_visible(False) for spine in ('top', 'right')]
plot_Diff(dfe)
plt.show()
Answered By - user3128
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.