How to format chart in Roassal 3? - smalltalk

I made a chart following the examples in the documentation. I find the title and x/y labels too close to the plot itself, and the tick labels too small. How do I format them?
x := -3.14 to: 3.14 count: 100.
y := x sin.
c := RSChart new.
p := RSLinePlot new x: x y: y.
c addPlot: p.
c title: 'Sine function'.
c xlabel: 'X axis'.
c ylabel: 'Y axis'.
c addDecoration: RSHorizontalTick new.
c addDecoration: RSVerticalTick new.
c open

The way the graph is constructed it uses the default offset of 5 for X axis and -5 for Y axis in the initialize of RSXLabelDecoration or RSYLabelDecoration respectively.
To move the titles around you have to create them yourself instead of using xlabel or ylabel.
You whould have to replace these two lines of code:
c xlabel: 'X axis'.
c ylabel: 'Y axis'.
with:
xAxisDecoration := c addDecoration: (RSXLabelDecoration new title: 'X axis'; offset: 15).
yAxisDecoration := c addDecoration: (RSYLabelDecoration new title: 'Y axis'; offset: -15).
The result:
Edit - forgot about the tick labels
To adjust the font size you need to add a message fontSize when creating a RSHorizontal(Vertical)Tick
The affected code would look like this:
c addDecoration: (RSHorizontalTick new fontSize: 10).
c addDecoration: (RSVerticalTick new fontSize: 10).
Producing this result:

Related

Map two data frames by common string elements from List column

I want to map two data frames if the string element from two columns match, The common column i have is string with comma separated. I tried map function by converting it to dictionary also. But it didn't worked.
df
Text
[Temp,Temp2]
[Temp4,Temp7,Temp2]
ClusterDf
Label Member
[Cluster1] [Temp,Temp8]
[Cluster2] [Temp4,Temp7]
I want output like
df
Text Label
[Temp,Temp2] [Cluster1]
[Temp4,Temp7,Temp2] [Cluster2]
Create dictionary by ClusterDf and then add new column by map with next and iter if no match:
d = {v: a[0] for a, b in zip(ClusterDf['Label'], ClusterDf['Member']) for v in b}
print (d)
{'Temp': 'Cluster1', 'Temp8': 'Cluster1', 'Temp4': 'Cluster2', 'Temp7': 'Cluster2'}
df['Label'] = df['Text'].map(lambda x: next(iter(d[y] for y in x if y in d), 'no match'))
print (df)
Text Label
0 [Temp, Temp2] Cluster1
1 [Temp4, Temp7, Temp2] Cluster2
If need list:
df['Label'] = df['Text'].map(lambda x: [next(iter(d[y] for y in x if y in d), 'no match')])
print (df)
Text Label
0 [Temp, Temp2] [Cluster1]
1 [Temp4, Temp7, Temp2] [Cluster2]
If want all matching if exist:
df['Label'] = df['Text'].map(lambda x: [d[y] for y in x if y in d])
print (df)
Text Label
0 [Temp, Temp2] [Cluster1]
1 [Temp4, Temp7, Temp2] [Cluster2, Cluster2]
Thanks #jezrael, Third solution worked for me perfectly. Thanks a lot.
You made my day
df['Label'] = df['Text'].map(lambda x: [d[y] for y in x if y in d])

matplotlib scatter plot using a 3rd data series to designate color

I have 3 data series that share the same index values:
series a
A 0.6
B 0.4
C 0.7
D 0.5
series b
A 0.8
B 0.4
C 0.7
D 0.5
series c
A 10
B 23
C 50
D 100
series a and b are my x and y axis. I would like to use series c to designate the color of the dots (if value at c > 80 then colors = red elif value at c > 20 then colors = blue).
This is what my code looks like so far:
colors = 'black' #default color
plt.scatter(a, b, s=np.pi*1, c=colors, alpha=0.5)
#this is what I'm looking for
#if value at c > 80 then colors = red elif value at c > 20 then colors = blue
plt.show()
this is what the finished graph would look like:
Thanks!
You want np.select to define color:
colors = np.select((c>80, c>20), ('r','b'), default='g')
plt.scatter(a,b, c=colors)
Output:
Another way, but not nearly as concise as #quang-hoang's.
Create a function with your criteria and then apply it to the df
def colors(row):
if row.v > 80: return 'red'
elif row.v > 20: return 'blue'
else: return 'green'
df['colors'] = df.apply(colors, axis=1)
Give you this:
x y v colors
A 0.6 0.8 10.0 green
B 0.4 0.4 23.0 blue
C 0.7 0.7 50.0 blue
D 0.5 0.5 100.0 red
df.plot.scatter('x', 'y', c=df.colors)

solving Ax=b using inverse matrix in maple

I am trying to solve a system of linear equations using the inverse matrix, but am having issues on my last command where I am trying to multiply the inverse matrix by B. Can anyone offer advice on what I am doing wrong?
restart; with(linalg):
sys := {a+.9*h+.8*c+.4*d+.1*e+0*f = 1, .1*a+.2*h+.4*c+.6*d+.5*e+.6*f = .6, .4*a+.5*h+.7*c+d+.6*e+.3*f = .7, .6*a+.1*h+.2*c+.3*d+.5*e+f = .5, .8*a+.8*h+c+.7*d+.4*e+.2*f = .8, .9*a+h+.8*c+.5*d+.2*e+.1*f = .9}:
solve(sys, {a, c, d, e, f, h});
{a = 0.08191850594, c = 0.7504244482, d = 3.510186757,
e = -6.474108659, f = 2.533531409, h = -0.4876910017}
Z := genmatrix(sys, [a, h, c, d, e, f], 'b');
evalm(b);
linsolve(Z, b);
inverse(Z);
B := {`<|>`(`<,>`(1, .6, .7, .5, .8, .9))};
evalm(inverse(Z)&*B);
response is indented below each line where possible. I don't have enough points to put pictures in for matrix results so they have been left blank.
As a previous poster suggests, removing the curly braces will fix your code, however, it may also be worth noting that if you are using a copy of Maple 6 or newer, the linalg package has been deprecated by the newer LinearAlgebra package.
Here is equivalent code that uses the LinearAlgebra package:
with(LinearAlgebra):
sys := [a+.9*h+.8*c+.4*d+.1*e+0*f = 1, .1*a+.2*h+.4*c+.6*d+.5*e+.6*f = .6, .4*a+.5*h+.7*c+d+.6*e+.3*f = .7, .6*a+.1*h+.2*c+.3*d+.5*e+f = .5, .8*a+.8*h+c+.7*d+.4*e+.2*f = .8, .9*a+h+.8*c+.5*d+.2*e+.1*f = .9];
solve(sys, {a, c, d, e, f, h});
Z,b := GenerateMatrix(sys, [a, h, c, d, e, f]);
LinearSolve( Z, b );
MatrixInverse( Z );
MatrixInverse( Z ) . b;
One minor difference is that here the GenerateMatrix command returns both the coefficient matrix as well as the right hand side Vector. Also note that I suppressed the output for the with command using the : operator.
Just remove the curly brackets from B.
B := `<|>`(`<,>`(1, .6, .7, .5, .8, .9));
evalm(inverse(Z)&*B);

How to set dimensions of LineSeries

I have a line series that covers data from 1 to 20 along the X axis and 0 to 1 along the Y axis. My problem is that the x axis always starts at 0 and goes to the furthest value and the Y axis starts at 0 but only goes to the furthest value as well. How can I set these dimensions?
So for the Y axis this is what you want
plotModel.Axes.Add(new LinearAxis()
{
Title = "Y axis Name",
Position = AxisPosition.Left,
MinorStep = 0.1,
FilterMinValue = -1,
FilterMaxValue = 1
});
As for the X axis it seems to be more annoying handLabeling seems to be the only way.
plotModel.Axes.Add(new CategoryAxis()
{
Title = "X axis name",
Position = AxisPosition.Bottom,
Labels = {"1","2","3","4","5","6" } // ... upto 20
});
Then every item you add index the value of the Category label.
For example if I want an column of 64 on 3 in X axis then the code would look like this:
var item =new ColumnItem(62, 2); // index 2 being value "3"

Create a method for intersection points

http://paulbourke.net/geometry/2circle/
Solved this with help of few people on here, This code will get the point of intersection for two circles
Here is my workspace code
|b b1 r r1 r2 d |
b1:= CircleAnimeMorph new. " CircleAnimeMorph is my new class"
b1 center: 100#100.
b1 openInWorld.
b:= CircleAnimeMorph new.
b openInWorld.
d:= b1 center dist: b center. "distance between 2 circles"
r:=b1 bounds width /2. "radius of first circle"
r1:=b bounds width/2. "radius of second Circle"
r2:=r + r1 .
(d )< (r2)
ifTrue: [| a h mid c c1 myPen h1 h2 mx my mc mc1|
a := (r squared - r1 squared + d squared) / (2 * d).
h := (r squared - a squared) sqrt.
h1:= b center y - b1 center y.
h2:= b center x - b1 center x.
mx:=a * (b center x - b1 center x)/d.
my:=a* (b center y - b1 center y)/d.
mid := ((mx)+(b1 center x) # (b1 center y )+(my) ) " calculates mid point between 2 intersecting circles (p2)"
{
mc:=(h * h1)/d.
mc1:=(h * h2)/d.
c:=(mid x + mc )# (mid y - mc1 )."Actual Intersecting points"
c1:=(mid x -mc) # (mid y + mc1 )."Actual Intersecting points"
Transcript show: (c); show: (c1); cr
}.
myPen := Pen new.
myPen color: Color red.
myPen putDotOfDiameter: 5 at: mid.
myPen putDotOfDiameter: 5 at: c1.
myPen putDotOfDiameter: 5 at: c. ].
Can any one help me make this a methods ,I wanna make this a intersection method which will do all this
when i say
b1 intersection:b.
should do all of this and draw colored dots at intersecting points
It sounds like you just want to add a new method to your class. Open up a Browser, navigate to CircleAnimeMorph, click somewhere in the method category pane (that's the second pane from the right), click in the code pane (the lower half of the Browser) and add
intersection: aCircleAnimeMorph
"And here, put your workspace code, but remove the initialisation stuff,
change 'b' to 'self' and 'b1' to 'aCircleAnimeMorph',
and make sure you actually return the values. Don't forget to remove
the Transcript and drawing logic."