From 138313f02da59a2a563f55ec1fc91567f08f570f Mon Sep 17 00:00:00 2001 From: jgostick Date: Sun, 1 Mar 2026 11:26:36 -0500 Subject: [PATCH 01/11] Update documentation generation workflow Added '--extra extras' to the 'uv sync' command for documentation generation. --- .github/workflows/generate-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index c2ec1bc47b..20bb8d5230 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | - uv sync --group docs --group interactive + uv sync --group docs --group interactive --extra extras - name: Build the documentation run: | From 64d3f2ae45f659777f89dc35bb98cc4299679935 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 1 Mar 2026 16:27:22 +0000 Subject: [PATCH 02/11] =?UTF-8?q?maint:=20bump=20version:=203.6.1=20?= =?UTF-8?q?=E2=86=92=203.6.1-dev1=20[skip=20bump]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 68d72eeca4..19ccb1ad89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openpnm" -version = "3.6.1" +version = "3.6.1-dev1" description = "A framework for conducting pore network modeling simulations of multiphase transport in porous materials" authors = [{ name = "OpenPNM Team", email = "jgostick@gmail.com" }] maintainers = [ @@ -220,7 +220,7 @@ path = "src/openpnm/__version__.py" packages = ["src/openpnm"] [tool.bumpversion] -current_version = "3.6.1" +current_version = "3.6.1-dev1" parse = """(?x) (?P0|[1-9]\\d*)\\. (?P0|[1-9]\\d*)\\. From 7271519475bc5ba8958d8802e60c873dfb848448 Mon Sep 17 00:00:00 2001 From: jgostick Date: Thu, 12 Mar 2026 23:06:22 -0400 Subject: [PATCH 03/11] updating example --- examples/applications/porosity.ipynb | 34 ++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/examples/applications/porosity.ipynb b/examples/applications/porosity.ipynb index 05c99f27b2..a5053bc0ac 100644 --- a/examples/applications/porosity.ipynb +++ b/examples/applications/porosity.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -59,7 +59,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -133,7 +133,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -143,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -203,19 +203,19 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Porosity from image: 63.3%\n" + "Porosity from image: 64.9%\n" ] }, { "data": { - "image/png": "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7neLYPiP//iP4gWK5j7xiU/EsmXLYtKkSXHyySfHyy+/HN/4xjeKF/DHH3+88QV/3bp1ccopp8SgQYMaX+Bnz55dBO2TTz5ZLD5BU6nN/uAP/qAIzqOOOiqeeeaZxn2rV6+OM844I44//viYMmVKcWxqz4985COxcOFCTRkRjzzySFx00UXFdXf55ZcXf7A9++yzxVztv//7v9eOGV588cXi+Z2ev1OnTi3+EHnssceK18j0h8lPf/pT7dmZSmXiiSeeSAFeuvPOOxu3bd26tXTMMceUzjjjjC49t3K2bNmy0vbt25tsW7NmTal3796lT33qU43bPvvZz5b69u1bev755xu3LV68uGjz++67r1PPuVJcfvnlpT/+4z8unXXWWaUTTzyxyb4LLrigVFdXV3rzzTcbt/3zP/9z0Z6LFi0q1brULsOGDSv92Z/9WWnXrl2tHqcd22bmzJnFtfXMM8802X7NNdcU29944w3t2YnKJjhvvfXWUo8ePZq8ECWzZs0qLowXXnihy86tEo0dO7b4aHDYYYeVJk2a1Oy4UaNGlc4555xOPrvy96tf/aq4Hv/rv/6rWXCma7Rnz57FNft+6Q+YAQMGlCZPnlyqdffcc0/xvP3v//7v4v9btmxpFqDase2mT59etOerr77abHv37t2L9tWenadsapyrVq2KUaNGxcCBA5tsP+200xpvjdE26Q+iDRs2xKGHHlr8f/369cWqGOPGjWt2bGrf1Pb8v7R6yOc+97m47rrr4qSTTmrWNE8//XTs3LmzWXum291jxozRnhGxZMmS4rmcrr10uzvdpk3//+xnP1usDqYd85x99tnF58mTJxevhenW7b/927/FPffcU5Re0vgG12XnKZvgrK+vj7q6umbbG7a99NJLXXBWlen73/9+8YKV6koNbZu01r5vvPFGMTCL99x7773x/PPPx1e/+tUWm2Rf7elafW8gS/rj4mMf+1icf/758ZOf/CSuvfbaom0/85nPaMdMaVBfuh7TYMlUM05jE9JAofQH3ty5c7VnJyubtWq3bt0avXv3bra9Yd3AtJ99+93vfhc33HBDMXDl05/+dJO221f7trS/1rz++uvxpS99Ke64444YOnRoi8fsqz1dq1EMPkujPdNAloZRtJdccknxrhP33XdfMRpUO+ZJA9QmTJgQl156aRxyyCHx8MMPx6xZs4oR3WlkvfasweBM009a6vU03NZJ+9m7NKL2wgsvLEbepdHJabH897ed9t23L37xi8WIxfSX/N6u1b21p2v1/9sojZR/vyuvvLIIzjQiNE2p0I5t86Mf/agYvZ2mmaXpKA1/iKQRymkKX2pn12UN3qpNt7gaboG9X8O2NLeT1r355ptxwQUXxKZNm+IXv/hFk/ZquKXYWvumoNDbfO/24rx584qaUbrd+txzzxUfKQzT+8Smf6fb2vtqT9fq/z9fhw0b1qR9Gt71aOPGjdoxwze/+c3iFm1DaDZIU1FSzz6NU3Bd1mBwpkEV6a+pzZs3N9n+xBNPNO6nZemFPc2XS+330EMPxQknnNBk/+GHH17cdlyxYkWzr01zOLXte1JdOP0Fn4Lz6KOPbvxI12Bq2/TvdIsxzY3t2bNns/ZMtyHTwA3tGXHqqac2tun7NdR/0/WoHdsuDfZr6T0i0x90Saona89OVCoTjz/+eLN5nNu2bSsde+yxpdNPP71Lz62c7dy5s3TxxRcX0yMefvjhVo+bOnVqMY/z/dN6lixZUrR5mjpAqRjq/+CDDzb7SFNRRo4cWfw7TU9JJk6cWMzj3Lx5c2PTfetb3yrac+HChTXfnCtXriza4sorr2zSFldccUVxra5fv147ZvjoRz9a6tWrV+l//ud/mmz/+Mc/XkxH0Z6dq2yCM0nzDBvmx6VJ+ePHjy/+n+bU0bLPf/7zxQvURRddVJo/f36zjwYpMA855JBiQYm77767mB87ePDg0kknnVT8gULrWloA4amnnioWmTjllFOKPzy+8IUvlPr06VM677zzNOX/ufbaa4tr87LLLiv90z/9U/H8Tv+/7bbbtON+zitO87FnzJhRtGdaPCK153XXXac9azk400pBt9xyS2n48OHFi9If/uEfln7xi1909WmV/Yt6evK09vF+adWR9MLer1+/0gc+8IFiZaGXX365y869koMzWbp0afHHXQrMoUOHlm644YYmPdBat2PHjtJf//Vfl4488sjSQQcdVNw9mjt3brPjtGPbV1dLYZleH1N7psVL0opC7777rvbsZGW1Vi0AlLuyGRwEAJVAcAJABsEJABkEJwBkEJwAkEFwAkAGwQkAGQQnAGQQnACQQXACQAbBCQAZBCcARNv9L/ALWwDAkptqAAAAAElFTkSuQmCC", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAc4AAAHPCAYAAADaujoVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAIzpJREFUeJzt3Q2QldV9P/AfL/IeEBRhwaBOIo2KDiDVyhi01SrWaFINGk00rShDRmOko0M1MWlIIU1FqTaNSpMmDealhoyTVkMQOjUl4EsQmOo0KY4TX3gRjYKI8s79z3n87+qyu+we2Lt7797PZ2Zn4Xme3fvs2efe757nd8653UqlUikAgDbp3rbDAADBCQCZ9DgBIIPgBIAMghMAMghOAMggOAEgg+AEgAyCEwAyCE4AqJTg3LlzZ8ycOTNGjBgRffv2jdNPPz2WLFlSzocEgOoNzr/4i7+Iu+66Kz796U/H3XffHT169Ig/+7M/i1/96lflfFgAKJtu5Vrk/amnnip6mHfccUfcfPPNxbYdO3bEmDFj4qijjooVK1Y0+Zr+/fsXx6SATccAQEd49dVXY+/evdGnT594++23D3xwqUxuueWWUo8ePUpvvvlmo+1z5sxJQV166aWXmnxN9+7di30+tIFrwDXgGnANRCe0Qcqh1vQsV3qvXr06Ro8eHQMHDmy0/bTTTis+r1mzJj74wQ822pd6mvv27Wu0rft+N5M/0L97DBjQLSrd7zf2ikqwM7Y3/Lt39I1KcGTdrqpou85oz9bapivZuGlvpKd7eo7XDevR2adT1bRl22zbVoq33m6cMfXqoyflUGvKFpwbN26Murq6Jtvrt23YsKHJvnR7dv369Y227Zej8YVpg+IrNx8Rle78EWOjEiwrPVK82KcX+Y92uzAqweJVa6qi7TqjPVtrm65k1PjfxfqNe4vQfGnVcZ19OlVNW7bNV+e+HrPu3HzAY9pSJixbcG7fvj169+7dZHu6f1y/vzXN/SU6cIAZNADkS/kxsq7HAXvtbVG24EzTT9J0lP2lwT/1+w8UmOkH8JcoAO1lxvTBxceBeu1tUbbuW7olm27X7q9+W5rbCQDVpmzBOXbs2Fi7dm1s3bq10fYnn3yyYT8AVJuy3ar95Cc/GXPnzo358+c3zONMt26/+93vFvM79x9Re7AqeSAJAF1P2YIzheOUKVPi1ltvLSaWfvjDH45//dd/jRdeeCG+853vHPBr05STNHrWQKBDNyqOjz2xO3rGYe3w3dCe7WfGtMNj67Z9nufasuqULTiT73//+3H77bfHggULYvPmzXHKKafEww8/HJMmTTrg16V5mtUw5aQaHNNtdGefQpeiPdtPS4M00JY1HZxp6klaci99AEBXYFIkAFRKj7McDAYCoDPpcQJABsEJABkEJwBUe40zva2UWmbXsXjDmkM6vitfC7ltQ2U7mGvVNVB99DgBIIPgBIAMghMAqr3GCbWitZqY+lfn6oj6eu5juCY6nx4nAGQQnACQQXACQAY1Ttpde9dgmvt+XXluJ52nGq6r5s5R3bNj6XECQAbBCQAZBCcAZFDj5JB0Vm2ltcethlpVW+z/c6hllbd9q5XrpGPpcQJABsEJABkEJwBkUOOkS2qPWmBXqX9Re79PNc/y0uMEgAyCEwAyCE4AyCA4ASCDwUFAl1RLg4FaY7BQ+9LjBIAMghMAMghOAMigxgltXEShM2pmFnWHyqPHCQAZBCcAZBCcAJBBjROqWGfNVVR7pZbpcQJABsEJABkEJwBkUOOEdqrrHUy9sRzfsyO0dl6dUQOt1LaqRNauPTR6nACQQXACQAbBCQAZ1DihnbRHXa+r1OnU0OjK9DgBIIPgBIAMghMAMqhxQifqKjXN1qh50pXocQJABsEJABkEJwBkEJwAkMHgILJ4A+ODVysDgTprsND+30N7t72tyKPHCQAZBCcAZBCcAJBBjZMDUgsBaEyPEwAyCE4AyCA4ASCDGieUiXmEh9ZW6utUKj1OAMggOAEgg+AEgAxqnDVOHYmuytq1LbcFh0aPEwAyCE4AyCA4AaDaa5xH1u2KxauavydvbtyhUeugVjV37XfV1xPP8/LS4wSAcgXnr3/967jhhhvipJNOiv79+8eoUaPisssui7Vr1zY59je/+U1Mnjw5BgwYEEOGDImrrroqXnvttZyHA4DqvlX7jW98I5YvXx5TpkyJU045JV555ZX45je/GePHj48nnngixowZUxy3bt26mDRpUgwaNCjmzJkT27Zti7lz58YzzzwTTz31VPTq1atcPw8AVE5w/tVf/VX88Ic/bBR8l19+eZx88snxd3/3d/HAAw8U21JYvv322/H0008XvdLktNNOiz/90z+N733vezFt2rSDPmFzs1puC8DrSblq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fVoV7de//nXccMMNcdJJJ0X//v1j1KhRcdlll8XatWubHPub3/wmJk+eHAMGDIghQ4bEVVddFa+99lqnnHe1mD17dnTr1i3GjBnTZN+KFSvizDPPjH79+sXw4cPjxhtvjG3btnXKeVaqVatWxcUXX1xcb6mdUjvec889jY7Rjm3z3HPPxac+9aniXaRSW37kIx+JWbNmxTvvvKM9O1hFjaq94oorYuHChXHTTTfF8ccfH9/73veKYPiv//qv4gWKpj75yU/G8uXLY8qUKXHKKafEK6+8Et/85jeLF/Annnii4QU/vU3OuHHjYtCgQQ0v8HPnzi2C9qmnnioWn6Cx1GZ/8Ad/UATnscceG88++2zDvjVr1sQZZ5wRJ5xwQkybNq04NrXnH//xH8eiRYs0ZUQ8+uijcdFFFxXX3eWXX178wfb8888Xc7X//u//XjtmePnll4vnd3r+Tp8+vfhD5PHHHy9eI9MfJj/72c+0Z0cqVYgnn3wyBXjpjjvuaNi2ffv20oc+9KHSGWec0annVsmWL19e2rlzZ6Nta9euLfXu3bv06U9/umHb5z73uVLfvn1LL774YsO2JUuWFG1+//33d+g5V4vLL7+89Cd/8iels846q3TSSSc12nfBBReU6urqSm+++WbDtn/+538u2nPx4sWlWpfaZdiwYaU///M/L+3du7fF47Rj28yePbu4tp599tlG26+++upi+xtvvKE9O1DFBOctt9xS6tGjR6MXomTOnDnFhfHSSy912rlVo/Hjxxcf9Y466qjSlClTmhw3evTo0jnnnNPBZ1f5fvnLXxbX4//8z/80Cc50jfbs2bO4Zt8v/QEzYMCA0tSpU0u17t577y2et//7v/9b/H/btm1NAlQ7tt3MmTOL9nzttdeabO/evXvRvtqz41RMjXP16tUxevToGDhwYKPtp512WsOtMdom/UG0adOmOPLII4v/r1+/vlgVY8KECU2OTe2b2p73pNVDPv/5z8e1114bJ598cpOmeeaZZ2LPnj1N2jPd7h47dqz2jIilS5cWz+V07aXb3ek2bfr/5z73uWJ1MO2Y5+yzzy4+T506tXgtTLdu/+3f/i3uvffeovSSxje4LjtOxQTnxo0bo66ursn2+m0bNmzohLOqTj/4wQ+KF6xUV6pv26Sl9n3jjTeKgVm867777osXX3wxvva1rzXbJK21p2v13YEs6Y+Lj3/843H++efHT3/607jmmmuKtv3Lv/xL7ZgpDepL12MaLJlqxmlsQhoolP7AmzdvnvbsYBWzVu327dujd+/eTbbXrxuY9tO63/72t3H99dcXA1c++9nPNmq71tq3uf215vXXX48vf/nLcfvtt8fQoUObPaa19nStRjH4LI32TANZ6kfRXnLJJcW7Ttx///3FaFDtmCcNUJs0aVJceumlccQRR8QjjzwSc+bMKUZ0p5H12rMGgzNNP2mu11N/Wyft58DSiNoLL7ywGHmXRienxfLf33bat3Vf+tKXihGL6S/5A12rB2pP1+p7bZRGyr/flVdeWQRnGhGaplRox7b58Y9/XIzeTtPM0nSU+j9E0gjlNIUvtbPrsgZv1aZbXPW3wN6vflua20nL3nzzzbjgggtiy5Yt8Ytf/KJRe9XfUmypfVNQ6G2+e3tx/vz5Rc0o3W594YUXio8Uhul9YtO/023t1trTtfre83XYsGGN2qf+XY82b96sHTN861vfKm7R1odmvTQVJfXs0zgF12UNBmcaVJH+mtq6dWuj7U8++WTDfpqXXtjTfLnUfg8//HCceOKJjfaPHDmyuO24cuXKJl+b5nBq23elunD6Cz4F53HHHdfwka7B1Lbp3+kWY5ob27NnzybtmW5DpoEb2jPi1FNPbWjT96uv/6brUTu2XRrs19x7RKY/6JJUT9aeHahUIZ544okm8zh37NhR+vCHP1w6/fTTO/XcKtmePXtKF198cTE94pFHHmnxuOnTpxfzON8/rWfp0qVFm6epA5SKof4PPfRQk480FWXUqFHFv9P0lGTy5MnFPM6tW7c2NN23v/3toj0XLVpU8825atWqoi2uvPLKRm1xxRVXFNfq+vXrtWOGj33sY6VevXqV/u///q/R9k984hPFdBTt2bEqJjiTNM+wfn5cmpQ/ceLE4v9pTh3N+8IXvlC8QF100UWlBQsWNPmolwLziCOOKBaUuOeee4r5sYMHDy6dfPLJxR8otKy5BRCefvrpYpGJcePGFX94fPGLXyz16dOndN5552nK/++aa64prs3LLrus9E//9E/F8zv9/9Zbb9WOBzmvOM3HnjVrVtGeafGI1J7XXnut9qzl4EwrBd18882l4cOHFy9Kf/iHf1j6xS9+0dmnVfEv6unJ09LH+6VVR9ILe79+/UqHH354sbLQK6+80mnnXs3BmSxbtqz44y4F5tChQ0vXX399ox5ordu1a1fpb/7mb0rHHHNM6bDDDivuHs2bN6/Jcdqx7aurpbBMr4+pPdPiJWlFod27d2vPDlZRa9UCQKWrmMFBAFANBCcAZBCcAJBBcAJABsEJABkEJwBkEJwAkEFwAkAGwQkAGQQnAGQQnACQQXACQLTd/wPypb3ATu4r3AAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -226,7 +226,13 @@ ], "source": [ "np.random.seed(10)\n", - "im = ps.generators.overlapping_spheres(shape=[100, 100, 100], r=10, porosity=0.5, maxiter=0)\n", + "im = ps.generators.overlapping_spheres(\n", + " shape=[100, 100, 100],\n", + " r=10,\n", + " porosity=0.5,\n", + " maxiter=0,\n", + " seed=0,\n", + ")\n", "plt.imshow(im[:, :, 50])\n", "im_poro = ps.metrics.porosity(im)\n", "print(f\"Porosity from image: {im_poro*100:.1f}%\")" @@ -234,17 +240,17 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
[09:28:01] WARNING  Disabling paralelization as overlap exceeds than chunk size.                      _snow2.py:214\n",
+       "
[10:39:29] WARNING  Disabling paralelization as overlap exceeds than chunk size.                      _snow2.py:214\n",
        "
\n" ], "text/plain": [ - "\u001b[2;36m[09:28:01]\u001b[0m\u001b[2;36m \u001b[0m\u001b[33mWARNING \u001b[0m Disabling paralelization as overlap exceeds than chunk size. \u001b[2m_snow2.py\u001b[0m\u001b[2m:\u001b[0m\u001b[2m214\u001b[0m\n" + "\u001b[2;36m[10:39:29]\u001b[0m\u001b[2;36m \u001b[0m\u001b[33mWARNING \u001b[0m Disabling paralelization as overlap exceeds than chunk size. \u001b[2m_snow2.py\u001b[0m\u001b[2m:\u001b[0m\u001b[2m214\u001b[0m\n" ] }, "metadata": {}, @@ -274,14 +280,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Porosity from pnm: 67.7%\n" + "Porosity from pnm: 73.7%\n" ] } ], From aa88da5de56096b7e6e5b6413e8802a62f03a8fe Mon Sep 17 00:00:00 2001 From: jgostick Date: Thu, 12 Mar 2026 23:06:29 -0400 Subject: [PATCH 04/11] more fixes --- src/openpnm/visualization/_plottools.py | 49 ++++++++++++++++--------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/openpnm/visualization/_plottools.py b/src/openpnm/visualization/_plottools.py index 5ed9f3da97..852cfccb54 100644 --- a/src/openpnm/visualization/_plottools.py +++ b/src/openpnm/visualization/_plottools.py @@ -148,23 +148,27 @@ class of matplotlib, so check their documentation for additional throat_pos = np.column_stack((xyz[P1], xyz[P2])).reshape((Ts.size, 2, dim.sum())) # Deal with optional style related arguments - if 'c' in kwargs.keys(): - color = kwargs.pop('c') - color = mcolors.to_rgb(color) + tuple([alpha]) if isinstance(cmap, str): try: cmap = plt.colormaps.get_cmap(cmap) except AttributeError: cmap = plt.cm.get_cmap(cmap) + kwargs['cmap'] = cmap # Override colors with color_by if given - if color_by is not None: + if color_by is None: + if 'c' in kwargs.keys(): + color = kwargs.pop('c') + color = mcolors.to_rgb(color) + tuple([alpha]) + kwargs['color'] = color + _ = kwargs.pop('cmap', None) + else: color_by = np.array(color_by) if len(color_by) != len(Ts): color_by = color_by[Ts] if not np.all(np.isfinite(color_by)): color_by[~np.isfinite(color_by)] = 0 logger.warning('nans or infs found in color_by array, setting to 0') - color = color_by + kwargs['array'] = color_by if size_by is not None: if len(size_by) != len(Ts): size_by = size_by[Ts] @@ -180,13 +184,22 @@ class of matplotlib, so check their documentation for additional vmax = kwargs.pop('vmax', None) if ThreeD: - lc = Line3DCollection(throat_pos, array=color, cmap=cmap, alpha=alpha, - linestyles=linestyle, linewidths=linewidth, - antialiaseds=np.ones_like(network.Ts), **kwargs) + lc = Line3DCollection( + throat_pos, + alpha=alpha, + linestyles=linestyle, + linewidths=linewidth, + antialiaseds=np.ones_like(network.Ts), + **kwargs, + ) else: - lc = LineCollection(throat_pos, array=color, cmap=cmap, alpha=alpha, - linestyles=linestyle, linewidths=linewidth, - antialiaseds=np.ones_like(network.Ts), **kwargs) + lc = LineCollection( + throat_pos, alpha=alpha, + linestyles=linestyle, + linewidths=linewidth, + antialiaseds=np.ones_like(network.Ts), + **kwargs, + ) if label_by is not None: for count, (P1, P2) in enumerate(network.conns[Ts, :]): i, j, k = np.mean(network.coords[[P1, P2], :], axis=0) @@ -332,16 +345,17 @@ def plot_coordinates(network, Xl, Yl, Zl = network['pore.coords'].T # Parse formatting kwargs - if 'c' in kwargs.keys(): - color = kwargs.pop('c') - if 's' in kwargs.keys(): - markersize = kwargs.pop('s') if isinstance(cmap, str): try: cmap = plt.colormaps.get_cmap(cmap) except AttributeError: cmap = plt.cm.get_cmap(cmap) - if color_by is not None: + kwargs['cmap'] = cmap + if color_by is None: + if 'c' in kwargs.keys(): + color = kwargs.pop('c') + _ = kwargs.pop('cmap') + else: color_by = np.array(color_by) if len(color_by) != len(Ps): color_by = color_by[Ps] @@ -349,6 +363,8 @@ def plot_coordinates(network, color_by[~np.isfinite(color_by)] = 0 logger.warning('nans or infs found in color_by array, setting to 0') color = color_by + if 's' in kwargs.keys(): + markersize = kwargs.pop('s') if size_by is not None: if len(size_by) != len(Ps): size_by = size_by[Ps] @@ -375,7 +391,6 @@ def plot_coordinates(network, s=markersize, marker=marker, alpha=alpha, - cmap=cmap, **kwargs) if label_by is not None: for count, (i, j, k) in enumerate(network.coords[Ps, :]): From 9fe4d415cadd290e4e7344213229f1b686925385 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 13 Mar 2026 03:42:24 +0000 Subject: [PATCH 05/11] =?UTF-8?q?maint:=20bump=20version:=203.6.1-dev1=20?= =?UTF-8?q?=E2=86=92=203.6.1-dev2=20[skip=20bump]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 19ccb1ad89..552a398362 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openpnm" -version = "3.6.1-dev1" +version = "3.6.1-dev2" description = "A framework for conducting pore network modeling simulations of multiphase transport in porous materials" authors = [{ name = "OpenPNM Team", email = "jgostick@gmail.com" }] maintainers = [ @@ -220,7 +220,7 @@ path = "src/openpnm/__version__.py" packages = ["src/openpnm"] [tool.bumpversion] -current_version = "3.6.1-dev1" +current_version = "3.6.1-dev2" parse = """(?x) (?P0|[1-9]\\d*)\\. (?P0|[1-9]\\d*)\\. From 93b7c79c9e218e4c7a8332e05ea3195c06110694 Mon Sep 17 00:00:00 2001 From: TKlokgieters <72444546+TKlokgieters@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:59:20 +0200 Subject: [PATCH 06/11] Fix variable name from 'newshape' to 'shape' in reshape Numpy 2.1 changed variable name to shape. In Numpy 2.4 newshape is definitely removed --- src/openpnm/_skgraph/queries/_funcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openpnm/_skgraph/queries/_funcs.py b/src/openpnm/_skgraph/queries/_funcs.py index a73346e9c2..a17ea1c9bc 100644 --- a/src/openpnm/_skgraph/queries/_funcs.py +++ b/src/openpnm/_skgraph/queries/_funcs.py @@ -168,7 +168,7 @@ def find_connected_nodes(network, inds, flatten=True, logic="or"): if len(inds): temp = temp.astype(float) temp[inds] = np.nan - temp = np.reshape(temp, newshape=[len(edges), 2], order="F") + temp = np.reshape(temp, shape=[len(edges), 2], order="F") neighbors = temp else: neighbors = [np.array([], dtype=np.int64) for i in range(len(edges))] From 17a3b32f01f65e03b07be1847e8dab752bd867b2 Mon Sep 17 00:00:00 2001 From: TKlokgieters <72444546+TKlokgieters@users.noreply.github.com> Date: Wed, 15 Apr 2026 16:05:48 +0200 Subject: [PATCH 07/11] Update numpy version constraint in pyproject.toml Required for newshape name change to shape in np.reshape Possibly later versions also allowed --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 552a398362..4cbe9121e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "matplotlib-inline>=0.1.7", "networkx>=3.5", "numba>=0.61", - "numpy<2.2", + "numpy=2.1", "pandas>=2.3.2", "pyamg>=5.3.0", "pypardiso; platform_system != 'Darwin' and (platform_machine == 'x86_64' or platform_machine == 'AMD64')", From acc6ddaf8fe7bc34040c1a330b585160229dbd91 Mon Sep 17 00:00:00 2001 From: TKlokgieters <72444546+TKlokgieters@users.noreply.github.com> Date: Wed, 15 Apr 2026 16:20:02 +0200 Subject: [PATCH 08/11] Update numpy version constraint in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4cbe9121e1..faf78a908b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "matplotlib-inline>=0.1.7", "networkx>=3.5", "numba>=0.61", - "numpy=2.1", + "numpy>=2.1,<2.2", "pandas>=2.3.2", "pyamg>=5.3.0", "pypardiso; platform_system != 'Darwin' and (platform_machine == 'x86_64' or platform_machine == 'AMD64')", From cf4969d4a64c549850ac103d4b4e9a7e78a6f1e3 Mon Sep 17 00:00:00 2001 From: TKlokgieters <72444546+TKlokgieters@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:26:31 +0200 Subject: [PATCH 09/11] Use positional np.reshape argument for (new)shape As suggested by @gerlero --- src/openpnm/_skgraph/queries/_funcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openpnm/_skgraph/queries/_funcs.py b/src/openpnm/_skgraph/queries/_funcs.py index a17ea1c9bc..3d11783ecc 100644 --- a/src/openpnm/_skgraph/queries/_funcs.py +++ b/src/openpnm/_skgraph/queries/_funcs.py @@ -168,7 +168,7 @@ def find_connected_nodes(network, inds, flatten=True, logic="or"): if len(inds): temp = temp.astype(float) temp[inds] = np.nan - temp = np.reshape(temp, shape=[len(edges), 2], order="F") + temp = np.reshape(temp, [len(edges), 2], order="F") neighbors = temp else: neighbors = [np.array([], dtype=np.int64) for i in range(len(edges))] From 22a84998bf49ff95c3366f6a30913d1f51d2cc22 Mon Sep 17 00:00:00 2001 From: TKlokgieters <72444546+TKlokgieters@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:27:40 +0200 Subject: [PATCH 10/11] Restate original numpy versioning Due to positional reshape argument no version constraint necessary --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index faf78a908b..552a398362 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "matplotlib-inline>=0.1.7", "networkx>=3.5", "numba>=0.61", - "numpy>=2.1,<2.2", + "numpy<2.2", "pandas>=2.3.2", "pyamg>=5.3.0", "pypardiso; platform_system != 'Darwin' and (platform_machine == 'x86_64' or platform_machine == 'AMD64')", From 94762df8596c64890e4936227b94b41bd810f735 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 16 Apr 2026 13:01:43 +0000 Subject: [PATCH 11/11] =?UTF-8?q?maint:=20bump=20version:=203.6.1-dev2=20?= =?UTF-8?q?=E2=86=92=203.6.1-dev3=20[skip=20bump]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 552a398362..fcfc846cbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openpnm" -version = "3.6.1-dev2" +version = "3.6.1-dev3" description = "A framework for conducting pore network modeling simulations of multiphase transport in porous materials" authors = [{ name = "OpenPNM Team", email = "jgostick@gmail.com" }] maintainers = [ @@ -220,7 +220,7 @@ path = "src/openpnm/__version__.py" packages = ["src/openpnm"] [tool.bumpversion] -current_version = "3.6.1-dev2" +current_version = "3.6.1-dev3" parse = """(?x) (?P0|[1-9]\\d*)\\. (?P0|[1-9]\\d*)\\.