How to add multiple custom ticks to seaborn boxplot - python
I generated a boxplot using seaborn. On the x axis, I would like to have, both the number of days (20, 25, 32) and the actual dates they refer to (2022-05-08, 2022-05-13, 2022-05-20).
I found a potential solution at the following link add custom tick with matplotlib. I'm trying to adapt it to my problem but I could only get the number of days or the dates, not both.
I really would appreciate any help. Thank you in advance for your time.
Please, find below my code and the desired output.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({'nb_days':[20,20,20,25,25,20,32,32,25,32,32],
'Dates':['2022-05-08','2022-05-08','2022-05-08','2022-05-13','2022-05-13','2022-05-08','2022-05-20','2022-05-20','2022-05-13','2022-05-20','2022-05-20'],
'score':[3,3.5,3.4,2,2.2,3,5,5.2,4,4.3,5]})
df['Dates'] = df['Dates'].apply(pd.to_datetime)
tick_label = dict(zip(df['nb_days'],df['Dates'].apply(lambda x: x.strftime('%Y-%m-%d')))) #My custom xtick label
#Plot
fig,ax = plt.subplots(figsize=(6,6))
ax = sns.boxplot(x='nb_days',y='score',data=df,color=None)
# iterate over boxes to change color
for i,box in enumerate(ax.artists):
box.set_edgecolor('red')
box.set_facecolor('white')
sns.stripplot(x='nb_days',y='score',data=df,color='black')
ticks = sorted(df['nb_days'].unique())
labels = [tick_label.get(t, ticks[i]) for i,t in enumerate(ticks)]
ax.set_xticklabels(labels)
plt.tight_layout()
plt.show()
plt.close()
Here is the desired output.
You can do that by adding these lines in place of ax.set_xticklabels(labels)
new_labels=["{}\n{}".format(a_, b_) for a_, b_ in zip(ticks, labels)]
ax.set_xticklabels(new_labels)
Output
Try this:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({'nb_days':[20,20,20,25,25,20,32,32,25,32,32],
'Dates':['2022-05-08','2022-05-08','2022-05-08','2022-05-13','2022-05-13','2022-05-08','2022-05-20','2022-05-20','2022-05-13','2022-05-20','2022-05-20'],
'score':[3,3.5,3.4,2,2.2,3,5,5.2,4,4.3,5]})
df['Dates'] = df['Dates'].apply(pd.to_datetime)
tick_label = dict(zip(df['nb_days'],df['Dates'].apply(lambda x: x.strftime('%Y-%m-%d')))) #My custom xtick label
#Plot
fig,ax = plt.subplots(figsize=(6,6))
ax = sns.boxplot(x='nb_days',y='score',data=df,color=None)
# iterate over boxes to change color
for i,box in enumerate(ax.artists):
box.set_edgecolor('red')
box.set_facecolor('white')
sns.stripplot(x='nb_days',y='score',data=df,color='black')
ticks = sorted(df['nb_days'].unique())
labels = ["{}\n".format(t)+tick_label.get(t, ticks[i]) for i, t in enumerate(ticks)]
ax.set_xticklabels(labels)
plt.tight_layout()
plt.show()
plt.close()
Related
Using pandas date as the X values of a bar graph Python
The code below outputs the bar graph using graph_vals and Monthly_indx, however the x values of the graph Monthly_indx are messed up and impossible to read when displayed. How would I be able to fix the x axis and make the graph readable? Code: import pandas as pd import numpy as np import matplotlib import matplotlib.pyplot as plt graph_vals = np.array([0.0, 15.58698486544634, 62.39522773472678, 53.102459267328186, 20.664598839134662, 37.43748926661284, 24.919985065059905, 2.462993387475203, 20.53746782047295, 87.85805111410333, 38.70428059326558, 31.56608531221292, 7.418190883067737, 17.10281023326888, 31.804189226978277, 30.05396124982128, 64.40080197706149, 33.29684656571501, 52.913157810513006, 20.913775029581142, 68.41187918506716, 47.56850690090707, 56.2736117598243, 31.25351961092795, 72.49099807107945, 44.95116145453175, 78.0696975321658, 54.60288966093484]) Monthly_indx = pd.date_range( pd.to_datetime('2019-05-08'), pd.to_datetime('2021-09-08'), freq='MS') print(len(graph_vals), len(Monthly_indx)) ax1 = pd.DataFrame({'Monthly PnLs':graph_vals, 'Months':Monthly_indx }) ax = ax1.plot.bar(y='Monthly PnLs',x='Months', rot=0) plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right') Output:
If you are using Matplotlib, use plt.setp() to tilt your x-labels: plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right') You can adjust the angle to your liking.
How to set ticks in Seaborn FacetGrid?
I have a code like this, and I want to add ticks on the X-axis so I could see better what the value over 150 corresponds to, for example. the range for my X-values is from 178 to 17639. bins = np.linspace(df.days_with_cr_line.min(), df.days_with_cr_line.max(), 32) g = sns.FacetGrid(df, col="loan_status", hue="loan_status", palette=['#8856a7', '#f03b20'], col_wrap=2) g.map(plt.hist, 'days_with_cr_line', bins=bins, ec="k") I have tried g.set_xticks(np.arange(0,18000,500), minor=True) AttributeError: 'FacetGrid' object has no attribute 'set_xticks' and for axes in g.axes.flat: _ = axes.set_xticks(axes.get_xticks(range(0,18000))) this removes the tick labels without adding any ticks.
If you use set to set the number of ticks on the x-axis, and then set the tick labels for them, you will get the intended result. The data is created appropriately. import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt np.random.seed(20210831) df = pd.DataFrame({'days_with_cr_line':np.random.randint(10,1000,size=1000), 'loan_status':np.random.choice(['Fully paid','Not fully paid'], size=1000)}) bins = np.linspace(df.days_with_cr_line.min(), df.days_with_cr_line.max(), 32) g = sns.FacetGrid(df, col="loan_status", hue="loan_status", palette=['#8856a7', '#f03b20'], col_wrap=2) g.map(plt.hist, 'days_with_cr_line', bins=bins, ec="k") g.set(xticks=np.arange(0,1050,50)) g.set_xticklabels(np.arange(0,1050,50), rotation=90)
Matplotlib Plot time series with different periodicity
I have 2 dfs. One of them has data for a month. Another one, averages for the past quarters. I wanna plot the averages in front of the monthly data. How can I do it? Please note that I am trying to plot averages as dots and monthly as line chart. So far my best result was achieved by ax1=ax.twiny(), but still not ideal result as data point appear in throughout the chart, rather than just in front. import pandas as pd import numpy as np import matplotlib.dates as mdates from matplotlib.ticker import ScalarFormatter, FormatStrFormatter, FuncFormatter import matplotlib.ticker as ticker import matplotlib.pyplot as plt date_base = pd.date_range(start='1/1/2018', end='1/30/2018') df_base = pd.DataFrame(np.random.randn(30,4), columns=list("ABCD"), index=date_base) date_ext = pd.date_range(start='1/1/2017', end='1/1/2018', freq="Q") df_ext = pd.DataFrame(np.random.randn(4,4), columns=list("ABCD"), index=date_ext) def drawChartsPlt(df_base, df_ext): fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(111) number_of_plots = len(df_base.columns) LINE_STYLES = ['-', '--', '-.', 'dotted'] colormap = plt.cm.nipy_spectral ax.set_prop_cycle("color", [colormap(i) for i in np.linspace(0,1,number_of_plots)]) date_base = df_base.index date_base = [i.strftime("%Y-%m-%d") for i in date_base] q_ends = df_ext.index q_ends = [i.strftime("%Y-%m-%d") for i in q_ends] date_base.insert(0, "") #to shift xticks so they match chart date_base += q_ends for i in range(number_of_plots): df_base.ix[:-3, df_base.columns[i]].plot(kind="line", linestyle=LINE_STYLES[i%2], subplots=False, ax=ax) #ax.set_xticks(date_base) #ax.set_xticklabels(date_base) # ax.xaxis.set_major_locator(ticker.MultipleLocator(20)) ax.xaxis.set_major_locator(ticker.LinearLocator(len(date_base))) ax.xaxis.set_major_formatter(plt.FixedFormatter(date_base)) fig.autofmt_xdate() # ax1=ax.twinx() ax1=ax.twiny() ax1.set_prop_cycle("color", [colormap(i) for i in np.linspace(0,1,number_of_plots)]) for i in range(len(df_ext.columns)): ax1.scatter(x=df_ext.index, y=df_ext[df_ext.columns[i]]) ax.set_title("Test") #plt.minorticks_off()) ax.minorticks_off() #ax1.minorticks_off() #ax1.set_xticklabels(date_base) #ax1.set_xticklabels(q_ends) ax.legend(loc="center left", bbox_to_anchor=(1,0.5)) ax.xaxis.label.set_size(12) plt.xlabel("TEST X Label") plt.ylabel("TEST Y Label") ax1.set_xlabel("Quarters") plt.show() drawChartsPlt(df_base, df_ext)
The way I ended up coding it is by saving quarterly index of df_ext to a temp variable, overwriting it with dates that are close to df_base.index using pd.date_range(start=df_base.index[-1], periods=len(df_ext), freq='D'), and the finally setting the dates that I need with ax.set_xticklabels(list(date_base)+list(date_ext)). It looks like it could be achieved using broken axes as indicated Break // in x axis of matplotlib and Python/Matplotlib - Is there a way to make a discontinuous axis?, but I haven't tried that solution.
Fix x-axis scale seaborn factorplot
I'm attempting to make a figure that shows two plots, with each plot separated based on a set of categorical data. However, although I can make the graph, I cant figure out how to get the x-axis to be properly spaced. I want the x-axis to start before the first value (want axis to start at 60 [first value = 63]) and end after the last (want axis to end at 95 [last value = 92.1]), with xticks going up in 5's. Any help is much appreciated! Thanks in advance! import pandas as pd import matplotlib.pyplot as plt import matplotlib.axes import seaborn as sns Temperature = [63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1,63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1] Derivative = [0.0495,0.0507,0.0525,0.0548,0.0570,0.0579,0.0579,0.0574,0.0574,0.0576,0.0581,0.0587,0.0593,0.0592,0.0584,0.0580,0.0579,0.0580,0.0582,0.0588,0.0592,0.0594,0.0588,0.0581,0.0578,0.0579,0.0580,0.0579,0.0582,0.0581,0.0579,0.0574,0.0571,0.0563,0.0548,0.0538,0.0536,0.0540,0.0544,0.0551,0.0556,0.0551,0.0542,0.0535,0.0536,0.0542,0.0564,0.0623,0.0748,0.0982,0.1360,0.1897,0.2550,0.3228,0.3807,0.4177,0.4248,0.3966,0.3365,0.2558,0.1713,0.0971,0.0438,0.0140,0.0034,0.0028,0.0048,0.0058,0.0057,0.0050,0.0042,0.0038,0.0039,0.0041,0.0038,0.0031,0.0023,0.0017,0.0014,0.0012,0.0015,0.0019,0.0020,0.0018,0.0017,0.0015,0.0014,0.0014,0.0015,0.0014,0.0013,0.0011,0.0007,0.0004,0.0011,0.0105,0.0100,0.0096,0.0090,0.0084,0.0081,0.0077,0.0071,0.0066,0.0063,0.0064,0.0060,0.0057,0.0055,0.0054,0.0051,0.0047,0.0046,0.0042,0.0037,0.0035,0.0040,0.0043,0.0039,0.0032,0.0028,0.0028,0.0027,0.0029,0.0034,0.0038,0.0034,0.0027,0.0024,0.0021,0.0017,0.0015,0.0016,0.0015,0.0011,0.0008,0.0012,0.0019,0.0025,0.0027,0.0026,0.0019,0.0012,0.0010,0.0014,0.0016,0.0014,0.0010,0.0007,0.0007,0.0010,0.0017,0.0021,0.0020,0.0013,0.0012,0.0013,0.0014,0.0015,0.0018,0.0017,0.0012,0.0013,0.0018,0.0028,0.0031,0.0033,0.0027,0.0022,0.0015,0.0016,0.0022,0.0026,0.0026,0.0019,0.0012,0.0006,0.0007,0.0011,0.0016,0.0014,0.0010,0.0009,0.0012,0.0015,0.0014,0.0008,0.0001,-0.0003,0.0002] Category = ["a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b"] df = pd.DataFrame({"Temperature": Temperature, "Derivative": Derivative, "Category" : Category}) g = sns.factorplot(x="Temperature", y="Derivative", data=df, col="Category") g.set_xticklabels(step=10)
All the desired feature you describe suggest that using a factorplot here is absolutely the wrong choice. Instead use a normal matplotlib plot and then set the limits as usual, plt.xlim(60,95). import pandas as pd import matplotlib.pyplot as plt Temperature = [63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1,63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1] Derivative = [0.0495,0.0507,0.0525,0.0548,0.0570,0.0579,0.0579,0.0574,0.0574,0.0576,0.0581,0.0587,0.0593,0.0592,0.0584,0.0580,0.0579,0.0580,0.0582,0.0588,0.0592,0.0594,0.0588,0.0581,0.0578,0.0579,0.0580,0.0579,0.0582,0.0581,0.0579,0.0574,0.0571,0.0563,0.0548,0.0538,0.0536,0.0540,0.0544,0.0551,0.0556,0.0551,0.0542,0.0535,0.0536,0.0542,0.0564,0.0623,0.0748,0.0982,0.1360,0.1897,0.2550,0.3228,0.3807,0.4177,0.4248,0.3966,0.3365,0.2558,0.1713,0.0971,0.0438,0.0140,0.0034,0.0028,0.0048,0.0058,0.0057,0.0050,0.0042,0.0038,0.0039,0.0041,0.0038,0.0031,0.0023,0.0017,0.0014,0.0012,0.0015,0.0019,0.0020,0.0018,0.0017,0.0015,0.0014,0.0014,0.0015,0.0014,0.0013,0.0011,0.0007,0.0004,0.0011,0.0105,0.0100,0.0096,0.0090,0.0084,0.0081,0.0077,0.0071,0.0066,0.0063,0.0064,0.0060,0.0057,0.0055,0.0054,0.0051,0.0047,0.0046,0.0042,0.0037,0.0035,0.0040,0.0043,0.0039,0.0032,0.0028,0.0028,0.0027,0.0029,0.0034,0.0038,0.0034,0.0027,0.0024,0.0021,0.0017,0.0015,0.0016,0.0015,0.0011,0.0008,0.0012,0.0019,0.0025,0.0027,0.0026,0.0019,0.0012,0.0010,0.0014,0.0016,0.0014,0.0010,0.0007,0.0007,0.0010,0.0017,0.0021,0.0020,0.0013,0.0012,0.0013,0.0014,0.0015,0.0018,0.0017,0.0012,0.0013,0.0018,0.0028,0.0031,0.0033,0.0027,0.0022,0.0015,0.0016,0.0022,0.0026,0.0026,0.0019,0.0012,0.0006,0.0007,0.0011,0.0016,0.0014,0.0010,0.0009,0.0012,0.0015,0.0014,0.0008,0.0001,-0.0003,0.0002] Category = ["a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b"] df = pd.DataFrame({"Temperature": Temperature, "Derivative": Derivative, "Category" : Category}) for n, data in df.groupby("Category"): plt.plot(data["Temperature"],data["Derivative"] , marker="o", label=n) plt.xlim(60,95) plt.legend() plt.show() Or if subplots are desired, fig,axes = plt.subplots(ncols=len(df["Category"].unique()), sharey=True) for ax,(n, data) in zip(axes,df.groupby("Category")): ax.plot(data["Temperature"],data["Derivative"] , marker="o", label=n) ax.set_title("Category {}".format(n)) ax.set_xlim(60,95) plt.show() Finally, you may use a seaborn FacetGrid onto which you plot your data with a plot: g = sns.FacetGrid(df, col="Category") g.map(plt.plot, "Temperature", "Derivative",marker="o",) for ax in g.axes.flat: ax.set_xlim(60,95) plt.show()
Change the facecolor of boxplot in pandas
I need to change the colors of the boxplot drawn using pandas utility function. I can change most properties using the color argument but can't figure out how to change the facecolor of the box. Someone knows how to do it? import pandas as pd import numpy as np data = np.random.randn(100, 4) labels = list("ABCD") df = pd.DataFrame(data, columns=labels) props = dict(boxes="DarkGreen", whiskers="DarkOrange", medians="DarkBlue", caps="Gray") df.plot.box(color=props)
While I still recommend seaborn and raw matplotlib over the plotting interface in pandas, it turns out that you can pass patch_artist=True as a kwarg to df.plot.box, which will pass it as a kwarg to df.plot, which will pass is as a kwarg to matplotlib.Axes.boxplot. import pandas as pd import numpy as np data = np.random.randn(100, 4) labels = list("ABCD") df = pd.DataFrame(data, columns=labels) props = dict(boxes="DarkGreen", whiskers="DarkOrange", medians="DarkBlue", caps="Gray") df.plot.box(color=props, patch_artist=True)
As suggested, I ended up creating a function to plot this, using raw matplotlib. def plot_boxplot(data, ax): bp = ax.boxplot(data.values, patch_artist=True) for box in bp['boxes']: box.set(color='DarkGreen') box.set(facecolor='DarkGreen') for whisker in bp['whiskers']: whisker.set(color="DarkOrange") for cap in bp['caps']: cap.set(color="Gray") for median in bp['medians']: median.set(color="white") ax.axhline(0, color="DarkBlue", linestyle=":") ax.set_xticklabels(data.columns)
I suggest using df.plot.box with patch_artist=True and return_type='both' (which returns the matplotlib axes the boxplot is drawn on and a dictionary whose values are the matplotlib Lines of the boxplot) in order to have the best customization possibilities. For example, given this data: import numpy as np import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame( data=np.random.randn(100, 4), columns=list("ABCD") ) you can set a specific color for all the boxes: fig,ax = plt.subplots(figsize=(9,6)) ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax) for patch in props['boxes']: patch.set_facecolor('lime') plt.show() you can set a specific color for each box: colors = ['green','blue','yellow','red'] fig,ax = plt.subplots(figsize=(9,6)) ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax) for patch,color in zip(props['boxes'],colors): patch.set_facecolor(color) plt.show() you can easily integrate a colormap: colors = np.random.randint(0,10, 4) cm = plt.cm.get_cmap('rainbow') colors_cm = [cm((c-colors.min())/(colors.max()-colors.min())) for c in colors] fig,ax = plt.subplots(figsize=(9,6)) ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax) for patch,color in zip(props['boxes'],colors_cm): patch.set_facecolor(color) # to add colorbar fig.colorbar(plt.cm.ScalarMappable( plt.cm.colors.Normalize(min(colors),max(colors)), cmap='rainbow' ), ax=ax, cmap='rainbow') plt.show()