Matplotbib - PercentFormatter - how to scale y axis and save plot? - python-3.x

just two quick questions I am struggeling with.
1. How can I scale the PercentFormatter, I want to set the y axis from 0 to 100 percent. I could do it without the PercentFormatter, but there must be a way including it, right?
2. The saveplot method cuts the x labels. How can i prevent that?
fig, ax = plt.subplots()
ax.bar(df['ErrorNames'], df["Frequency"], color="C0")
ax.set_xticklabels(df['ErrorNames'], rotation=90 ) ;
ax.set_ylabel('Error Frequency')
ax2 = ax.twinx()
ax2.set_ylabel('Accumulated Percentage of Frequency')
ax2.plot(df['ErrorNames'], df["cumpercentage"], color="C1", marker="D", ms=7)
ax2.yaxis.set_major_formatter(PercentFormatter())
ax.tick_params(axis="y", colors="C0")
ax2.tick_params(axis="y", colors="C1")
plt.savefig('Pareto')
plt.show()
Pareto Chart

Related

using % range in plot labels

I want to change the range in terms of %. In the attached figure along x-axis, I want to label it as -1%, -0.05%, 0, 0.05% and 1% along x-axis. Is there any way to do that directly in python using range function?
ax.set_xlim(-0.012, 0.012, 0.2)
You can modify the tick labels as shown below
fig, ax = plt.subplots()
x = np.linspace(-0.01, 0.01, 10)
ax.plot(x, -x/10, '-bo')
ax.set_xlim(-0.012, 0.012, 0.2)
labels = ['{:.2f}%'.format(item*100) for item in ax.get_xticks()]
ax.set_xticklabels(labels)

Pass a list of values to a tick constructor in matplotlib [duplicate]

I hope one of you may be able to help. I have a plot with one y-axis value and one x-axis corresponding to these y values. I want to add a second y-axis on the right hand side of the plot. The values that will appear on the second y-axis are determined through the first y-axis values by some relation: for example, y2 might be y2 = y1**2 - 100. How do I make a second y-axis which has its values determined by the y1 values, so that the y2 values correctly align with their y1 values on the y-axis?
twin axis
Adding a second y axis can be done by creating a twin axes, ax2 = ax.twinx().
The scale of this axes can be set using its limits, ax2.set_ylim(y2min, y2max). The values of y2min, y2max can be calculated using some known relationship (e.g. implemented as a function) from the limits of the left axis.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
x = np.linspace(0,50,101)
y = np.cumsum(np.random.normal(size=len(x)))+20.
fig, ax = plt.subplots()
ax2 = ax.twinx()
ax.plot(x,y, color="#dd0011")
ax.set_ylabel("Temperature [Celsius]")
ax2.set_ylabel("Temperature [Fahrenheit]")
# set twin scale (convert degree celsius to fahrenheit)
T_f = lambda T_c: T_c*1.8 + 32.
# get left axis limits
ymin, ymax = ax.get_ylim()
# apply function and set transformed values to right axis limits
ax2.set_ylim((T_f(ymin),T_f(ymax)))
# set an invisible artist to twin axes
# to prevent falling back to initial values on rescale events
ax2.plot([],[])
plt.show()
secondary axis
From matplotlib 3.1 onwards one can use a secondary_yaxis. This takes care of synchronizing the limits automatically. As input one needs the conversion function and its inverse.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
x = np.linspace(0,50,101)
y = np.cumsum(np.random.normal(size=len(x)))+20.
# Convert celsius to Fahrenheit
T_f = lambda T_c: T_c*1.8 + 32.
# Convert Fahrenheit to Celsius
T_c = lambda T_f: (T_f - 32.)/1.8
fig, ax = plt.subplots()
ax2 = ax.secondary_yaxis("right", functions=(T_f, T_c))
ax.plot(x,y, color="#dd0011")
ax.set_ylabel("Temperature [Celsius]")
ax2.set_ylabel("Temperature [Fahrenheit]")
plt.show()
The output is the same as above, but as you can see one does not need to set any limits.

Setting ticks on matplotlib 3-D plots

I'm doing some cluster analysis and want to use matplotlib to visualise the results. For the most part, this is working out OK. However, I'm struggling with controlling tick placement on the axes. That is, the ticks on the y axis are overcrowded and I'd like to thin them out. I've tried supplying a range for the ticks using the numpy arrange function, but this isn't working.
I don't know if this is because I'm not familiar enough with matplotlib, or if it's an issue with 3-D plotting. In any event, I've tried all the solutions I can find on Stack and nothing seems to be working.
My code:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(data['col_1'], data['col_2'], data['col_3'], c = data.index, cmap = cm.winter, s=60)
ax.view_init(15, 240)
ax.set_xlabel('X Axis')
ax.set_ylabel('Y Axis')
ax.set_zlabel('Z- Axis')
plt.title('Sample Plot')
plt.show()
My solution to this is to supply the ticks as follows:
ticks = np.arange(0.3, 0.7, 0.02)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(data['col_1'], data['col_2'], data['col_3'], c = data.index, cmap = cm.winter, s=60)
ax.view_init(15, 240)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
ax.set_zticks(ticks)
ax.set_xlabel('X Axis')
ax.set_ylabel('Y Axis')
ax.set_zlabel('Z- Axis')
plt.title('Sample Bad Plot')
plt.show()
However, this only produces the hot mess below. Any help to be had?
The problem is that your x-values lie approximately within the range 0.54-0.68, your y-values lie within the range 0.34-0.42 and your z-values lie within the range0.55-0.63. Now in your second code, you define ticks = np.arange(0.3, 0.7, 0.02) which creates ticks from 0.3 to 0.68 and then you assign these values to be displayed on x, y, z axis using ax.set_xticks(ticks) and so on. You get this mess because your supplied ticks values are outside the range of actual x, y, z data points. Since you are only interested in refining the y axis ticks, you can just do
ticks = np.arange(0.34, 0.44, 0.02)
and then just set the ticks for the y axis as
ax.set_yticks(ticks).
If you don't want to specify the numbers 0.34 and 0.44 manually, you can find the maximum and minimum y value and use something like ticks = np.arange(min_value, max_value, 0.02).
Since I do not have access to your original data data['col_1'] and so on, I can't play with your code but the above tips will surely help.

How to add another scale on the right part of y-axis in the same Python plot? [duplicate]

I hope one of you may be able to help. I have a plot with one y-axis value and one x-axis corresponding to these y values. I want to add a second y-axis on the right hand side of the plot. The values that will appear on the second y-axis are determined through the first y-axis values by some relation: for example, y2 might be y2 = y1**2 - 100. How do I make a second y-axis which has its values determined by the y1 values, so that the y2 values correctly align with their y1 values on the y-axis?
twin axis
Adding a second y axis can be done by creating a twin axes, ax2 = ax.twinx().
The scale of this axes can be set using its limits, ax2.set_ylim(y2min, y2max). The values of y2min, y2max can be calculated using some known relationship (e.g. implemented as a function) from the limits of the left axis.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
x = np.linspace(0,50,101)
y = np.cumsum(np.random.normal(size=len(x)))+20.
fig, ax = plt.subplots()
ax2 = ax.twinx()
ax.plot(x,y, color="#dd0011")
ax.set_ylabel("Temperature [Celsius]")
ax2.set_ylabel("Temperature [Fahrenheit]")
# set twin scale (convert degree celsius to fahrenheit)
T_f = lambda T_c: T_c*1.8 + 32.
# get left axis limits
ymin, ymax = ax.get_ylim()
# apply function and set transformed values to right axis limits
ax2.set_ylim((T_f(ymin),T_f(ymax)))
# set an invisible artist to twin axes
# to prevent falling back to initial values on rescale events
ax2.plot([],[])
plt.show()
secondary axis
From matplotlib 3.1 onwards one can use a secondary_yaxis. This takes care of synchronizing the limits automatically. As input one needs the conversion function and its inverse.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
x = np.linspace(0,50,101)
y = np.cumsum(np.random.normal(size=len(x)))+20.
# Convert celsius to Fahrenheit
T_f = lambda T_c: T_c*1.8 + 32.
# Convert Fahrenheit to Celsius
T_c = lambda T_f: (T_f - 32.)/1.8
fig, ax = plt.subplots()
ax2 = ax.secondary_yaxis("right", functions=(T_f, T_c))
ax.plot(x,y, color="#dd0011")
ax.set_ylabel("Temperature [Celsius]")
ax2.set_ylabel("Temperature [Fahrenheit]")
plt.show()
The output is the same as above, but as you can see one does not need to set any limits.

How to prevent from drawing overlapping axis ticks when adding a line to scatter plot?

fig, ax = plt.subplots()
ax = fig.add_subplot(111)
ax.scatter(X[1],y)
y_projection = X.dot(theta_after)
ax.plot(X[1], y_projection)
plt.show()
Above is my code. What I'm trying to do is basically fitting a line to the data. I use gradient descent method to find the suitable theta.
The problem I came across is that the code above created two x-axis and y-axis and that they were overlapping on each other
This is the result generated from the above code. I'm not allowed to embed a pic now, please click on this to open the pic.
X - is a 97*2 matrix in which the first column is all 1.
You are creating an extra Axes with your second line. Just remove the following line:
ax = fig.add_subplot(111)
You already have an Axes when you run fig, ax = plt.subplots()

Resources