Plotting Carlyle’s Circle with Matplotlib in Excel

Recently I happened to read of Carlyle’s Circle, which is a circle that has two intersection points with a parabola on the X axis. See the Wikipedia article for more details:

https://en.wikipedia.org/wiki/Carlyle_circle

This post looks at the options for plotting this circle in Excel, using both the Excel built-in xy graphs and Python Matplotlib graphs with the pyxll add-in. The new Python code used has been added to the py_SciPy code, with examples added to the py_EvalU spreadsheet, both of which can be downloaded from:

py_SciPy.zip

See Scipy Functions with Excel and pyxll 5 – Evaluate with Units for more details of the py_EvalU spreadsheet.

Using the py_EvalU spreadsheet, the functions for a parabola and the associated Carlyle Circle can be entered as text, which can be evaluated and listed over a specified range, using the py_Eval function. These two lines can then be plotted on an Excel xy graph:

As an alternative, Matplotlib can be used with pyxll to generate the plot data and generate an xy graph. This has the advantages:

  • The generated data does not need to be written to the spreadsheet.
  • It is easier to set axis limits, and to set the axis scales equal, so that the circle plots as a circle and not an ellipse.
  • More and easier options for adding text and titles, etc.

The py_PlotFunc function will evaluate the parabola over a specified range of x, and plot the result:

py_PlotCirc plots a circle with a specified centre and radius:

These two functions are called by py_PlotCarlyle, which has the parameters of the parabola as input, and calculates the centre and radius of the Carlyle Circe, then plots both, together with the diameter of the circle, and the coordinates of the intersection of the circle with the x axis, which are also the intersection points with the parabola:

The code for the py_PlotCarlyle function is shown below. All the other code is freely available in the download file.

@xl_func(category = "Eval-Units")
@xl_arg('Quadabc', 'numpy_array<float>', ndim=1)
@xl_arg("EqualAx", 'bool')
@xl_arg("DecPlace", 'int')
def py_PlotCarlyle(Quadabc, EqualAx = True, DecPlace = 3):
    a, b, c = Quadabc[:]
    if b**2 - 4*a*c < 0:
        return 'No real solutions'
    xdiff = (b**2 - 4*a*c)**0.5
    x1 = (-b - xdiff)/(2*a)
    x2 = (-b + xdiff)/(2*a)
    roots = [x1, x2]
    xlabels = ['x = ' + str(round(num,DecPlace)) for num in roots]
    if b < 0:
        btxt = str(b)
    else:
        btxt = "+ " + str(b)
    if c < 0:
        ctxt = str(c)
    else:
        ctxt = "+ " + str(c)
    head = "Carlyle's Circle for y = " + str(a) + "x^2 " + btxt + "x " + ctxt
    n = 40
    s = -b/a
    p = c/a
    Xcen = s/2
    Ycen = 1 + (p-1)/2
    r = ((s**2 + (p-1)**2)**0.5)/2
    xmin = (Xcen - r)
    xmax = (Xcen + r)
    xquad = np.linspace(xmin, xmax, n)
    yquad = np.zeros(n)
    for i in range(0, n): 
        x = xquad[i]
        yquad[i] = a*x**2+b*x+c
    angvals = np.linspace(0, np.pi*2, n*2)
    sinangs = np.sin(angvals)
    cosangs = np.cos(angvals)
    xcirc = np.zeros(n*2)
    ycirc = np.zeros(n*2)
    xcirc[:] = cosangs[:]*r +Xcen
    ycirc[:] = sinangs[:]*r +Ycen

    xdiam = [0, s]
    ydiam = [1, p]
    labels = [' 0, 1', ' -b/a, c/a']

    fig, ax = plt.subplots()
    ax.plot(xquad, yquad, 'r', xcirc, ycirc, 'b', xdiam, ydiam, 'g')
    plt.grid(True)
    plt.title(head)
    if EqualAx: plt.axis('equal')
    for i in range(2):
        plt.text(xdiam[i], ydiam[i], labels[i], fontsize = 10, ha = 'left', va = 'top')
    plt.text(roots[0], 0, xlabels[0], fontsize = 10, ha = 'left', va = 'bottom')
    plt.text(roots[1], 0, xlabels[1], fontsize = 10, ha = 'left', va = 'top')
# Optionally customize the grid
    plt.grid(color='gray', linestyle='--', linewidth=0.5)
    plot(fig)
    return ' Function roots are ' + xlabels[0] + ' and ' + xlabels[1]

Posted in Charts, Drawing, Excel, Link to Python, Maths, Newton, PyXLL, UDFs | Tagged , , , , , , | Leave a comment

Upgrading plotly (to 6.9.1)

Today I found that some of my plotly functions were not working, and re-loading the pyxll files returned the message “could not import PySide6.Qtgui pyside6”. Searching for this problem I found:

After upgrading PySide6 gives error No module named ‘PySide6.QtWidgets’

In particular, the following procedure fixed the problem for me:

Solution :

$ python3.10 -m pip uninstall pyside6 pyside6-addons pyside6-essentials shiboken6
$ python3.10 -m pip cache purge
$ python3.10 -m pip install pyside6

It is necessary to clear cache files before reinstalling pyside6 other wise it will use previous cache files and the import error using continue to come.

But note that a following comment says that uninstalling and clearing the cache is not necessary.

$ python3.10 -m pip install --force-reinstall --no-cache-dir pyside6

No need to pip uninstall and pip cache clear

Posted in Drawing, Excel, Link to Python, PyXLL | Tagged , , , , , , | Leave a comment

3DFrame-py rel. 0.50

Following the recent post on the Python lru_cache function (Python functools and the Fibonacci Sequence) I have had a look at using lru_cache in the 3DFrame-py spreadsheet. So far using lru_cache in this code has provided little to no speed improvement, but I did find changes to the basic code that resulted in very significant improvements. These are incorporated in the new release, that can be downloaded from:

3DFrame-py.zip

See Installing 3DFrame-py for installation details, and details of other Python modules required. Also see Python and pyxll for details of the required pyxll package, including a coupon code for a 10% discount.

The most significant change is to the code to calculate beam fixed end actions under the applied loading. The original code allowed for beams with spring end releases at one or both ends, but for beams without end releases much simpler procedures are possible, and the new code applies the simplified procedures wherever possible. The processing time for a very large frame with different code and conditions is shown below:

The main conclusions are:

  • Total run time for linear analysis with “no jit” code was reduced by half, with the majority of the speed improvement in the code for Fixed End Moment Array (FEMA).
  • Using the Numba jit code, the old code was already fast, and this code was not updated.
  • For the analyses including non-linear geometric effects the total analysis times were almost the same for the new non-jit code, and the code with jit. The reasons for this are to be investigated.
  • One linear run used the “banded” solver. This was very slow, increasing the total solution time to over 12 minutes!
  • All the other runs used the PyPardiso solver, which is much faster than any of the Scipy solvers, but also has a further significant speed-up if an analysis is re-run without changing the stiffness matrix. This has the potential to speed up non-linear analyses, which will be investigated in future releases.

The other main change in the new code is that the VBA code to plot the frame in 3D has been replaced with Python code linking to my Plot3D function (see 3D plots with the latest Matplotlib). This has similar functionality to the VBA code but:

  • The Python code is very much faster. Redrawing the full frame for this large model with the VBA code took over 10 minutes. This is reduced to less than 1 second with Python.
  • The input data ranges are now selected automatically, and the plot re-draws automatically when anything is changed.
  • I have added slider bars to adjust the zoom ratio and the centre of view coordinates.

The full frame, with deflections magnified by 100 times:

Zoom in and pan down to the front corner of the frame:

Increase the deflection factor to 200 x:

The graph to plot selected beam actions or deflections has also been updated (but currently still uses VBA):

Posted in Beam Bending, Coordinate Geometry, Excel, Finite Element Analysis, Frame Analysis, Link to Python, Newton, NumPy and SciPy, PyXLL, Strand7, UDFs | Tagged , , , , , , , | Leave a comment

Some new (to me) music

Hugh Laurie started his career as straight man to Stephen Fry in comedy shows featuring sketches such as:

Since then he has had great success as both a comedian and a straight actor, but until recently I had no idea he was also a great jazz musician:

And for something completely different, Bert Jansch has been featured her numerous times, but never before with Mary Hopkin:

Posted in Bach | Tagged , , , , | Leave a comment

The iccanobiF Sequence

Coincidentally, following the previous post, New Scientist’s regular brain teaser featured the iccanobiF Sequence, which is just like the Fibonacci Sequence, except that after adding the two previous numbers the digits of the results are reversed. Obviously the sequences are the same for single digit values, but following 5 and 8 the Fibonacci result is 13, and iccanobiF is 31.

Some examples of code for generating the sequence can be found at geeksforgeeks:
Program to find first N Iccanobif Numbers

The examples in the link all use a loop to find the value of the reversed digits, but in Python this can be done with a single line of code:

@xl_func()
@xl_arg('n', 'int')
def iccanobif(n):
    f1 = 1
    f2 = 1
    for i in range(2, n):
        f3 = int(str(f2+f1)[::-1])
        f1 = f2
        f2 = f3
    return f3

The code includes the pyxll decorators to link to Excel. The line generating the numbers in the sequence:

  • Adds f1 and f2 (to generate the next Fibonacci number)
  • Converts this to a string
  • Reverses the string
  • Converts the string back to an integer (which will automatically remove any leading zeros)

The results of this function called from Excel are shown below, together with the equivalent Fibonacci numbers.

Posted in Excel, Link to Python, Maths, Newton, PyXLL, UDFs | Tagged , , , , , | Leave a comment