0

I'm trying to create the graph present in the image bellow. I'm new on matplotlib so I don't know how to create the axis without insert some data. For example, if a have x and y and plot(x,y), the graph will be create and the axis too, but the axis will be correlated with the data. In the graph attach, the curves are isolines, so the correlation of the data doesn't depend exactly of the axis (depend by a function that I have described in the code).

enter image description here

How can I proceed?

0

1 Answer 1

1

You can use plt.xlim and plt.ylim to set the limits on the axis. With plt.grid you can control how to show the gridlines. set_major_locator can set the position for the ticks and corresponding gridlines.

The position for the text could be calculated by first finding the y on the line that corresponds to x=40. If that y would be too low, we can calculate an x value on the line corresponding to y=-1500. For the rotation of the text, we can take the tangent of the line, which needs to be corrected by the aspect ratio of the plot. To have the rotation still valid when the size of the plot is changed, a fixed aspect ratio can be set.

Here is some demonstration code to get you started:

import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
import numpy as np

fig, ax = plt.subplots()

aspect = 1 / 300
ax.set_aspect(aspect)  # a fixed aspect ratio is needed so the text rotation stays equal to the line rotation
for iso in range(-5000, 16001, 1000):
    x1 = 25 + iso / 100
    x2 = -50
    y1 = -1000
    y2 = 7000 + iso
    plt.plot([x1, x2], [y1, y2], c='crimson', lw=2 if iso % 5000 == 0 else 0.5)
    if iso % 5000 == 0:
        # xt,yt:  x,y value for text; first try y position when x = 40; if too small find x position for y = -1500
        xt = 40
        yt = (y1 * (xt - x2) + y2 * (x1 - xt)) / (x1 - x2)
        if yt < y1:
            yt = -1500
            xt = (x1 * (yt - y2) + x2 * (y1 - yt)) / (y1 - y2)
        ax.text(xt, yt, iso if iso != 0 else "zero",
                {'ha': 'center', 'va': 'center', 'bbox': {'fc': 'lightgoldenrodyellow', 'pad': 2, 'alpha': 0.7}},
                rotation=np.arctan(aspect * (y1 - y2) / (x1 - x2)) / np.pi * 180)

ax.xaxis.set_major_locator(MultipleLocator(10))
ax.xaxis.set_minor_locator(MultipleLocator(5))
ax.xaxis.set_major_formatter(FormatStrFormatter('%d°C'))
ax.yaxis.set_major_locator(MultipleLocator(5000))
ax.yaxis.set_minor_locator(MultipleLocator(1000))
plt.grid(True, which='major', color='blue', linestyle='--', lw=0.5)
plt.grid(True, which='minor', color='blue', linestyle='--', lw=0.2)
plt.xlim(-50, 50)
plt.ylim(-5000, 20000)
plt.show()

result

Sign up to request clarification or add additional context in comments.

1 Comment

Any idea of how i could add the labels aligned with the curve equal the image? I guess i should make a if equal you did for the lw, but i can't configure the position...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.